merge default branch into stable to mark the start of the code freeze stable
authorMatt Mackall <mpm@selenic.com>
Sat, 18 Jun 2011 17:03:01 -0500
branchstable
changeset 14687 15200b46165b
parent 14508 07722bb8a08c (current diff)
parent 14686 6ab8b17adc03 (diff)
child 14688 e2da6eee7950
merge default branch into stable to mark the start of the code freeze
hgext/parentrevspec.py
mercurial/templates/static/graph.js
tests/darcs1.hg
tests/legacy-encoding.hg
tests/tampered.hg
tests/test-dumprevlog.t
tests/test-git-import.t
tests/test-issue322.t
tests/test-issue433.t
tests/test-issue436.t
tests/test-keyword.hg
tests/test-manifest.hg
tests/test-merge-symlinks.hg
tests/test-no-symlinks.hg
tests/test-parentrevspec.t
tests/test-rebase-keep-branch.t
tests/test-repair-strip
tests/test-repair-strip.out
tests/test-serve
tests/test-serve.out
tests/test-simplemerge-cmd.t
--- a/.hgignore	Wed Jun 01 16:32:48 2011 -0500
+++ b/.hgignore	Sat Jun 18 17:03:01 2011 -0500
@@ -7,6 +7,7 @@
 *.mergebackup
 *.o
 *.so
+*.dll
 *.pyd
 *.pyc
 *.pyo
@@ -25,6 +26,7 @@
 doc/*.[0-9].gendoc.txt
 doc/*.[0-9].{x,ht}ml
 MANIFEST
+MANIFEST.in
 patches
 mercurial/__version__.py
 mercurial.egg-info
@@ -34,6 +36,7 @@
 cscope.*
 i18n/hg.pot
 locale/*/LC_MESSAGES/hg.mo
+hgext/__index__.py
 
 # files installed with a local --pure build
 mercurial/base85.py
--- a/COPYING	Wed Jun 01 16:32:48 2011 -0500
+++ b/COPYING	Sat Jun 18 17:03:01 2011 -0500
@@ -1,12 +1,12 @@
-		    GNU GENERAL PUBLIC LICENSE
-		       Version 2, June 1991
+                    GNU GENERAL PUBLIC LICENSE
+                       Version 2, June 1991
 
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.
-     59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  Everyone is permitted to copy and distribute verbatim copies
  of this license document, but changing it is not allowed.
 
-			    Preamble
+                            Preamble
 
   The licenses for most software are designed to take away your
 freedom to share and change it.  By contrast, the GNU General Public
@@ -15,7 +15,7 @@
 General Public License applies to most of the Free Software
 Foundation's software and to any other program whose authors commit to
 using it.  (Some other Free Software Foundation software is covered by
-the GNU Library General Public License instead.)  You can apply it to
+the GNU Lesser General Public License instead.)  You can apply it to
 your programs, too.
 
   When we speak of free software, we are referring to freedom, not
@@ -55,8 +55,8 @@
 
   The precise terms and conditions for copying, distribution and
 modification follow.
-
-		    GNU GENERAL PUBLIC LICENSE
+
+                    GNU GENERAL PUBLIC LICENSE
    TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
 
   0. This License applies to any program or other work which contains
@@ -110,7 +110,7 @@
     License.  (Exception: if the Program itself is interactive but
     does not normally print such an announcement, your work based on
     the Program is not required to print an announcement.)
-
+
 These requirements apply to the modified work as a whole.  If
 identifiable sections of that work are not derived from the Program,
 and can be reasonably considered independent and separate works in
@@ -168,7 +168,7 @@
 access to copy the source code from the same place counts as
 distribution of the source code, even though third parties are not
 compelled to copy the source along with the object code.
-
+
   4. You may not copy, modify, sublicense, or distribute the Program
 except as expressly provided under this License.  Any attempt
 otherwise to copy, modify, sublicense or distribute the Program is
@@ -225,7 +225,7 @@
 
 This section is intended to make thoroughly clear what is believed to
 be a consequence of the rest of this License.
-
+
   8. If the distribution and/or use of the Program is restricted in
 certain countries either by patents or by copyrighted interfaces, the
 original copyright holder who places the Program under this License
@@ -255,7 +255,7 @@
 of preserving the free status of all derivatives of our free software and
 of promoting the sharing and reuse of software generally.
 
-			    NO WARRANTY
+                            NO WARRANTY
 
   11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
 FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
@@ -277,9 +277,9 @@
 PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
 POSSIBILITY OF SUCH DAMAGES.
 
-		     END OF TERMS AND CONDITIONS
-
-	    How to Apply These Terms to Your New Programs
+                     END OF TERMS AND CONDITIONS
+
+            How to Apply These Terms to Your New Programs
 
   If you develop a new program, and you want it to be of the greatest
 possible use to the public, the best way to achieve this is to make it
@@ -303,17 +303,16 @@
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
 
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 
 Also add information on how to contact you by electronic and paper mail.
 
 If the program is interactive, make it output a short notice like this
 when it starts in an interactive mode:
 
-    Gnomovision version 69, Copyright (C) year  name of author
+    Gnomovision version 69, Copyright (C) year name of author
     Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
     This is free software, and you are welcome to redistribute it
     under certain conditions; type `show c' for details.
@@ -336,5 +335,5 @@
 This General Public License does not permit incorporating your program into
 proprietary programs.  If your program is a subroutine library, you may
 consider it more useful to permit linking proprietary applications with the
-library.  If this is what you want to do, use the GNU Library General
+library.  If this is what you want to do, use the GNU Lesser General
 Public License instead of this License.
--- a/Makefile	Wed Jun 01 16:32:48 2011 -0500
+++ b/Makefile	Sat Jun 18 17:03:01 2011 -0500
@@ -45,7 +45,8 @@
 clean:
 	-$(PYTHON) setup.py clean --all # ignore errors from this command
 	find . \( -name '*.py[cdo]' -o -name '*.so' \) -exec rm -f '{}' ';'
-	rm -f MANIFEST tests/*.err
+	rm -f $(addprefix mercurial/,$(notdir $(wildcard mercurial/pure/*.py)))
+	rm -f MANIFEST MANIFEST.in tests/*.err
 	rm -rf build mercurial/locale
 	$(MAKE) -C doc clean
 
@@ -68,16 +69,18 @@
 MANIFEST-doc:
 	$(MAKE) -C doc MANIFEST
 
-MANIFEST: MANIFEST-doc
-	hg manifest > MANIFEST
-	echo mercurial/__version__.py >> MANIFEST
-	cat doc/MANIFEST >> MANIFEST
+MANIFEST.in: MANIFEST-doc
+	hg manifest | sed -e 's/^/include /' > MANIFEST.in
+	echo include mercurial/__version__.py >> MANIFEST.in
+	sed -e 's/^/include /' < doc/MANIFEST >> MANIFEST.in
 
 dist:	tests dist-notests
 
-dist-notests:	doc MANIFEST
+dist-notests:	doc MANIFEST.in
 	TAR_OPTIONS="--owner=root --group=root --mode=u+w,go-w,a+rX-s" $(PYTHON) setup.py -q sdist
 
+check: tests
+
 tests:
 	cd tests && $(PYTHON) run-tests.py $(TESTFLAGS)
 
--- a/contrib/bash_completion	Wed Jun 01 16:32:48 2011 -0500
+++ b/contrib/bash_completion	Sat Jun 18 17:03:01 2011 -0500
@@ -62,13 +62,13 @@
 _hg_commands()
 {
     local commands
-    commands="$(_hg_cmd debugcomplete "$cur")" || commands=""
+    commands="$(HGPLAINEXCEPT=alias _hg_cmd debugcomplete "$cur")" || commands=""
     COMPREPLY=(${COMPREPLY[@]:-} $(compgen -W '$commands' -- "$cur"))
 }
 
 _hg_paths()
 {
-    local paths="$(_hg_cmd paths | sed -e 's/ = .*$//')"
+    local paths="$(_hg_cmd paths -q)"
     COMPREPLY=(${COMPREPLY[@]:-} $(compgen -W '$paths' -- "$cur"))
 }
 
--- a/contrib/check-code.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/contrib/check-code.py	Sat Jun 18 17:03:01 2011 -0500
@@ -42,6 +42,7 @@
 
 
 testpats = [
+  [
     (r'(pushd|popd)', "don't use 'pushd' or 'popd', use 'cd'"),
     (r'\W\$?\(\([^\)]*\)\)', "don't use (()) or $(()), use 'expr'"),
     (r'^function', "don't use 'function', use old style"),
@@ -66,6 +67,10 @@
     (r'^source\b', "don't use 'source', use '.'"),
     (r'touch -d', "don't use 'touch -d', use 'touch -t' instead"),
     (r'ls\s+[^|-]+\s+-', "options to 'ls' must come before filenames"),
+    (r'[^>]>\s*\$HGRCPATH', "don't overwrite $HGRCPATH, append to it"),
+  ],
+  # warnings
+  []
 ]
 
 testfilters = [
@@ -76,6 +81,7 @@
 uprefix = r"^  \$ "
 uprefixc = r"^  > "
 utestpats = [
+  [
     (r'^(\S|  $ ).*(\S\s+|^\s+)\n', "trailing whitespace on non-output"),
     (uprefix + r'.*\|\s*sed', "use regex test output patterns instead of sed"),
     (uprefix + r'(true|exit 0)', "explicit zero exit unnecessary"),
@@ -84,20 +90,25 @@
      "explicit exit code checks unnecessary"),
     (uprefix + r'set -e', "don't use set -e"),
     (uprefixc + r'( *)\t', "don't use tabs to indent"),
+  ],
+  # warnings
+  []
 ]
 
-for p, m in testpats:
-    if p.startswith('^'):
-        p = uprefix + p[1:]
-    else:
-        p = uprefix + p
-    utestpats.append((p, m))
+for i in [0, 1]:
+    for p, m in testpats[i]:
+        if p.startswith('^'):
+            p = uprefix + p[1:]
+        else:
+            p = uprefix + p
+        utestpats[i].append((p, m))
 
 utestfilters = [
     (r"( *)(#([^\n]*\S)?)", repcomment),
 ]
 
 pypats = [
+  [
     (r'^\s*def\s*\w+\s*\(.*,\s*\(',
      "tuple parameter unpacking not available in Python 3+"),
     (r'lambda\s*\(.*,.*\)',
@@ -111,7 +122,6 @@
     (r'\w[+/*\-<>]\w', "missing whitespace in expression"),
     (r'^\s+\w+=\w+[^,)]$', "missing whitespace in assignment"),
     (r'.{85}', "line too long"),
-    (r'.{81}', "warning: line over 80 characters"),
     (r'[^\n]\Z', "no trailing newline"),
     (r'(\S\s+|^\s+)\n', "trailing whitespace"),
 #    (r'^\s+[^_ ][^_. ]+_[^_]+\s*=', "don't use underbars in identifiers"),
@@ -129,6 +139,7 @@
     (r'[\x80-\xff]', "non-ASCII character literal"),
     (r'("\')\.format\(', "str.format() not available in Python 2.4"),
     (r'^\s*with\s+', "with not available in Python 2.4"),
+    (r'\.isdisjoint\(', "set.isdisjoint not available in Python 2.4"),
     (r'^\s*except.* as .*:', "except as not available in Python 2.4"),
     (r'^\s*os\.path\.relpath', "relpath not available in Python 2.4"),
     (r'(?<!def)\s+(any|all|format)\(',
@@ -146,14 +157,35 @@
      "missing whitespace around operator"),
     (r'\s(\+=|-=|!=|<>|<=|>=|<<=|>>=)\S',
      "missing whitespace around operator"),
-    (r'[^+=*!<>&| -](\s=|=\s)[^= ]',
+    (r'[^+=*/!<>&| -](\s=|=\s)[^= ]',
      "wrong whitespace around ="),
     (r'raise Exception', "don't raise generic exceptions"),
-    (r'ui\.(status|progress|write|note|warn)\([\'\"]x',
-     "warning: unwrapped ui message"),
     (r' is\s+(not\s+)?["\'0-9-]', "object comparison with literal"),
     (r' [=!]=\s+(True|False|None)',
      "comparison with singleton, use 'is' or 'is not' instead"),
+    (r'^\s*(while|if) [01]:',
+     "use True/False for constant Boolean expression"),
+    (r'opener\([^)]*\).read\(',
+     "use opener.read() instead"),
+    (r'opener\([^)]*\).write\(',
+     "use opener.write() instead"),
+    (r'[\s\(](open|file)\([^)]*\)\.read\(',
+     "use util.readfile() instead"),
+    (r'[\s\(](open|file)\([^)]*\)\.write\(',
+     "use util.readfile() instead"),
+    (r'^[\s\(]*(open(er)?|file)\([^)]*\)',
+     "always assign an opened file to a variable, and close it afterwards"),
+    (r'[\s\(](open|file)\([^)]*\)\.',
+     "always assign an opened file to a variable, and close it afterwards"),
+    (r'(?i)descendent', "the proper spelling is descendAnt"),
+  ],
+  # warnings
+  [
+    (r'.{81}', "warning: line over 80 characters"),
+    (r'^\s*except:$', "warning: naked except clause"),
+    (r'ui\.(status|progress|write|note|warn)\([\'\"]x',
+     "warning: unwrapped ui message"),
+  ]
 ]
 
 pyfilters = [
@@ -164,6 +196,7 @@
 ]
 
 cpats = [
+  [
     (r'//', "don't use //-style comments"),
     (r'^  ', "don't use spaces to indent"),
     (r'\S\t', "don't use tabs except for indent"),
@@ -176,9 +209,13 @@
     (r'\([^\)]+\) \w+', "use (int)foo, not (int) foo"),
     (r'\S+ (\+\+|--)', "use foo++, not foo ++"),
     (r'\w,\w', "missing whitespace after ,"),
-    (r'\w[+/*]\w', "missing whitespace in expression"),
+    (r'^[^#]\w[+/*]\w', "missing whitespace in expression"),
     (r'^#\s+\w', "use #foo, not # foo"),
     (r'[^\n]\Z', "no trailing newline"),
+    (r'^\s*#import\b', "use only #include in standard C code"),
+  ],
+  # warnings
+  []
 ]
 
 cfilters = [
@@ -188,11 +225,31 @@
     (r'(\()([^)]+\))', repcallspaces),
 ]
 
+inutilpats = [
+  [
+    (r'\bui\.', "don't use ui in util"),
+  ],
+  # warnings
+  []
+]
+
+inrevlogpats = [
+  [
+    (r'\brepo\.', "don't use repo in revlog"),
+  ],
+  # warnings
+  []
+]
+
 checks = [
     ('python', r'.*\.(py|cgi)$', pyfilters, pypats),
     ('test script', r'(.*/)?test-[^.~]*$', testfilters, testpats),
     ('c', r'.*\.c$', cfilters, cpats),
     ('unified test', r'.*\.t$', utestfilters, utestpats),
+    ('layering violation repo in revlog', r'mercurial/revlog\.py', pyfilters,
+     inrevlogpats),
+    ('layering violation ui in util', r'mercurial/util\.py', pyfilters,
+     inutilpats),
 ]
 
 class norepeatlogger(object):
@@ -231,7 +288,7 @@
     return lines
 
 def checkfile(f, logfunc=_defaultlogger.log, maxerr=None, warnings=False,
-              blame=False):
+              blame=False, debug=False):
     """checks style and portability of a given file
 
     :f: filepath
@@ -245,24 +302,39 @@
     blamecache = None
     result = True
     for name, match, filters, pats in checks:
+        if debug:
+            print name, f
         fc = 0
         if not re.match(match, f):
+            if debug:
+                print "Skipping %s for %s it doesn't match %s" % (
+                       name, match, f)
             continue
         fp = open(f)
         pre = post = fp.read()
         fp.close()
         if "no-" + "check-code" in pre:
+            if debug:
+                print "Skipping %s for %s it has no- and check-code" % (
+                       name, f)
             break
         for p, r in filters:
             post = re.sub(p, r, post)
+        if warnings:
+            pats = pats[0] + pats[1]
+        else:
+            pats = pats[0]
         # print post # uncomment to show filtered version
         z = enumerate(zip(pre.splitlines(), post.splitlines(True)))
+        if debug:
+            print "Checking %s for %s" % (name, f)
         for n, l in z:
             if "check-code" + "-ignore" in l[0]:
+                if debug:
+                    print "Skipping %s for %s:%s (check-code -ignore)" % (
+                           name, f, n)
                 continue
             for p, msg in pats:
-                if not warnings and msg.startswith("warning"):
-                    continue
                 if re.search(p, l[1]):
                     bd = ""
                     if blame:
@@ -279,7 +351,6 @@
             if maxerr is not None and fc >= maxerr:
                 print " (too many errors, giving up)"
                 break
-        break
     return result
 
 if __name__ == "__main__":
@@ -290,8 +361,10 @@
                       help="max warnings per file")
     parser.add_option("-b", "--blame", action="store_true",
                       help="use annotate to generate blame info")
+    parser.add_option("", "--debug", action="store_true",
+                      help="show debug information")
 
-    parser.set_defaults(per_file=15, warnings=False, blame=False)
+    parser.set_defaults(per_file=15, warnings=False, blame=False, debug=False)
     (options, args) = parser.parse_args()
 
     if len(args) == 0:
@@ -302,6 +375,6 @@
     for f in check:
         ret = 0
         if not checkfile(f, maxerr=options.per_file, warnings=options.warnings,
-                         blame=options.blame):
+                         blame=options.blame, debug=options.debug):
             ret = 1
     sys.exit(ret)
--- a/contrib/dumprevlog	Wed Jun 01 16:32:48 2011 -0500
+++ b/contrib/dumprevlog	Sat Jun 18 17:03:01 2011 -0500
@@ -6,7 +6,7 @@
 from mercurial import revlog, node, util
 
 for fp in (sys.stdin, sys.stdout, sys.stderr):
-    util.set_binary(fp)
+    util.setbinary(fp)
 
 for f in sys.argv[1:]:
     binopen = lambda fn: open(fn, 'rb')
--- a/contrib/hg-ssh	Wed Jun 01 16:32:48 2011 -0500
+++ b/contrib/hg-ssh	Sat Jun 18 17:03:01 2011 -0500
@@ -16,7 +16,7 @@
 (probably together with these other useful options:
  no-port-forwarding,no-X11-forwarding,no-agent-forwarding)
 
-This allows pull/push over ssh to to the repositories given as arguments.
+This allows pull/push over ssh from/to the repositories given as arguments.
 
 If all your repositories are subdirectories of a common directory, you can
 allow shorter paths with:
@@ -42,7 +42,7 @@
     path = orig_cmd[6:-14]
     repo = os.path.normpath(os.path.join(cwd, os.path.expanduser(path)))
     if repo in allowed_paths:
-        dispatch.dispatch(['-R', repo, 'serve', '--stdio'])
+        dispatch.dispatch(dispatch.request(['-R', repo, 'serve', '--stdio']))
     else:
         sys.stderr.write("Illegal repository %r\n" % repo)
         sys.exit(-1)
--- a/contrib/perf.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/contrib/perf.py	Sat Jun 18 17:03:01 2011 -0500
@@ -1,14 +1,14 @@
 # perf.py - performance test routines
 '''helper extension to measure performance'''
 
-from mercurial import cmdutil, match, commands
+from mercurial import cmdutil, scmutil, match, commands
 import time, os, sys
 
 def timer(func, title=None):
     results = []
     begin = time.time()
     count = 0
-    while 1:
+    while True:
         ostart = os.times()
         cstart = time.time()
         r = func()
@@ -31,11 +31,11 @@
 
 def perfwalk(ui, repo, *pats):
     try:
-        m = cmdutil.match(repo, pats, {})
+        m = scmutil.match(repo[None], pats, {})
         timer(lambda: len(list(repo.dirstate.walk(m, [], True, False))))
     except:
         try:
-            m = cmdutil.match(repo, pats, {})
+            m = scmutil.match(repo[None], pats, {})
             timer(lambda: len([b for a, b, c in repo.dirstate.statwalk([], m)]))
         except:
             timer(lambda: len(list(cmdutil.walk(repo, pats, {}))))
--- a/contrib/python-hook-examples.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/contrib/python-hook-examples.py	Sat Jun 18 17:03:01 2011 -0500
@@ -13,7 +13,7 @@
     if kwargs.get('parent2'):
         return
     node = kwargs['node']
-    first = repo[node].parents()[0].node()
+    first = repo[node].p1().node()
     if 'url' in kwargs:
         last = repo['tip'].node()
     else:
--- a/contrib/shrink-revlog.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/contrib/shrink-revlog.py	Sat Jun 18 17:03:01 2011 -0500
@@ -1,5 +1,4 @@
-"""\
-reorder a revlog (the manifest by default) to save space
+"""reorder a revlog (the manifest by default) to save space
 
 Specifically, this topologically sorts the revisions in the revlog so that
 revisions on the same branch are adjacent as much as possible. This is a
@@ -18,7 +17,7 @@
 # (maybe: export before, shrink, export after, diff).
 
 import os, tempfile, errno
-from mercurial import revlog, transaction, node, util
+from mercurial import revlog, transaction, node, util, scmutil
 from mercurial import changegroup
 from mercurial.i18n import _
 
@@ -31,7 +30,10 @@
     while visit:
         cur = visit[-1]
         for p in edges[cur]:
-            if p not in finished:
+            # defend against node.nullrev because it's occasionally
+            # possible for a node to have parents (null, something)
+            # rather than (something, null)
+            if p not in finished and p != node.nullrev:
                 visit.append(p)
                 break
         else:
@@ -102,19 +104,21 @@
 
     ui.status(_('writing revs\n'))
 
-    count = [0]
-    def progress(*args):
-        ui.progress(_('writing'), count[0], total=len(order))
-        count[0] += 1
 
     order = [r1.node(r) for r in order]
 
     # this is a bit ugly, but it works
-    lookup = lambda x: "%020d" % r1.linkrev(r1.rev(x))
+    count = [0]
+    def lookup(revl, x):
+        count[0] += 1
+        ui.progress(_('writing'), count[0], total=len(order))
+        return "%020d" % revl.linkrev(revl.rev(x))
+
     unlookup = lambda x: int(x, 10)
 
     try:
-        group = util.chunkbuffer(r1.group(order, lookup, progress))
+        bundler = changegroup.bundle10(lookup)
+        group = util.chunkbuffer(r1.group(order, bundler))
         group = changegroup.unbundle10(group, "UN")
         r2.addgroup(group, unlookup, tr)
     finally:
@@ -190,8 +194,8 @@
     prefix = os.path.basename(indexfn)[:-1]
     tmpindexfn = util.mktempcopy(indexfn, emptyok=True)
 
-    r1 = revlog.revlog(util.opener(os.getcwd(), audit=False), indexfn)
-    r2 = revlog.revlog(util.opener(os.getcwd(), audit=False), tmpindexfn)
+    r1 = revlog.revlog(scmutil.opener(os.getcwd(), audit=False), indexfn)
+    r2 = revlog.revlog(scmutil.opener(os.getcwd(), audit=False), tmpindexfn)
 
     datafn, tmpdatafn = r1.datafile, r2.datafile
 
@@ -247,8 +251,8 @@
         if not opts.get('dry_run'):
             # racy, both files cannot be renamed atomically
             # copy files
-            util.os_link(indexfn, oldindexfn)
-            ignoremissing(util.os_link)(datafn, olddatafn)
+            util.oslink(indexfn, oldindexfn)
+            ignoremissing(util.oslink)(datafn, olddatafn)
 
             # rename
             util.rename(tmpindexfn, indexfn)
--- a/contrib/simplemerge	Wed Jun 01 16:32:48 2011 -0500
+++ b/contrib/simplemerge	Sat Jun 18 17:03:01 2011 -0500
@@ -43,7 +43,7 @@
 
 try:
     for fp in (sys.stdin, sys.stdout, sys.stderr):
-        util.set_binary(fp)
+        util.setbinary(fp)
     
     opts = {}
     try:
--- a/contrib/undumprevlog	Wed Jun 01 16:32:48 2011 -0500
+++ b/contrib/undumprevlog	Sat Jun 18 17:03:01 2011 -0500
@@ -4,12 +4,12 @@
 # $ undumprevlog < repo.dump
 
 import sys
-from mercurial import revlog, node, util, transaction
+from mercurial import revlog, node, scmutil, util, transaction
 
 for fp in (sys.stdin, sys.stdout, sys.stderr):
-    util.set_binary(fp)
+    util.setbinary(fp)
 
-opener = util.opener('.', False)
+opener = scmutil.opener('.', False)
 tr = transaction.transaction(sys.stderr.write, opener, "undump.journal")
 while 1:
     l = sys.stdin.readline()
--- a/contrib/win32/mercurial.ini	Wed Jun 01 16:32:48 2011 -0500
+++ b/contrib/win32/mercurial.ini	Sat Jun 18 17:03:01 2011 -0500
@@ -37,7 +37,6 @@
 [extensions]
 ;acl =
 ;alias =
-;bookmarks =
 ;bugzilla =
 ;children =
 ;churn =
@@ -56,7 +55,6 @@
 ;mq =
 ;notify =
 ;pager =
-;parentrevspec =
 ;patchbomb =
 ;progress =
 ;purge =
--- a/contrib/wix/guids.wxi	Wed Jun 01 16:32:48 2011 -0500
+++ b/contrib/wix/guids.wxi	Sat Jun 18 17:03:01 2011 -0500
@@ -33,7 +33,7 @@
   <?define templates.raw.guid = {04DE03A2-FBFD-4c5f-8DEA-5436DDF4689D} ?>
   <?define templates.rss.guid = {A7D608DE-0CF6-44f4-AF1E-EE30CC237FDA} ?>
   <?define templates.spartan.guid = {80222625-FA8F-44b1-86CE-1781EF375D09} ?>
-  <?define templates.static.guid = {68C9F843-DE7E-480f-9DA2-D220B19D02C3} ?>
+  <?define templates.static.guid = {B27D7311-050A-4A96-9971-B674A0EA21D0} ?>
 
   <!-- mercurial.wxs -->
   <?define ProductUpgradeCode = {A1CC6134-E945-4399-BE36-EB0017FDF7CF} ?>
--- a/contrib/wix/templates.wxs	Wed Jun 01 16:32:48 2011 -0500
+++ b/contrib/wix/templates.wxs	Sat Jun 18 17:03:01 2011 -0500
@@ -195,7 +195,7 @@
             <File Id="static.coal.file.png"      Name="coal-file.png" />
             <File Id="static.coal.folder.png"    Name="coal-folder.png" />
             <File Id="static.excanvas.js"        Name="excanvas.js" />
-            <File Id="static.graph.js"           Name="graph.js" />
+            <File Id="static.mercurial.js"       Name="mercurial.js" />
             <File Id="static.hgicon.png"         Name="hgicon.png" />
             <File Id="static.hglogo.png"         Name="hglogo.png" />
             <File Id="static.style.coal.css"     Name="style-coal.css" />
--- a/contrib/zsh_completion	Wed Jun 01 16:32:48 2011 -0500
+++ b/contrib/zsh_completion	Sat Jun 18 17:03:01 2011 -0500
@@ -360,8 +360,8 @@
     '(--help -h)'{-h,--help}'[display help and exit]'
     '--debug[debug mode]'
     '--debugger[start debugger]'
-    '--encoding[set the charset encoding (default: UTF8)]'
-    '--encodingmode[set the charset encoding mode (default: strict)]'
+    '--encoding[set the charset encoding]'
+    '--encodingmode[set the charset encoding mode]'
     '--lsprof[print improved command execution profile]'
     '--traceback[print traceback on exception]'
     '--time[time how long the command takes]'
--- a/doc/Makefile	Wed Jun 01 16:32:48 2011 -0500
+++ b/doc/Makefile	Sat Jun 18 17:03:01 2011 -0500
@@ -25,6 +25,10 @@
 	${PYTHON} gendoc.py > $@.tmp
 	mv $@.tmp $@
 
+hgrc.5: ../mercurial/help/config.txt
+
+hgrc.5.html: ../mercurial/help/config.txt
+
 %: %.txt common.txt
 	$(PYTHON) runrst hgmanpage $(RSTARGS) --halt warning \
 	  --strip-elements-with-class htmlonly $*.txt $*
--- a/doc/gendoc.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/doc/gendoc.py	Sat Jun 18 17:03:01 2011 -0500
@@ -87,6 +87,10 @@
 
     # print topics
     for names, sec, doc in helptable:
+        if names[0] == "config":
+            # The config help topic is included in the hgrc.5 man
+            # page.
+            continue
         for name in names:
             ui.write(".. _%s:\n" % name)
         ui.write("\n")
@@ -157,16 +161,7 @@
 
 
 def allextensionnames():
-    extensionnames = []
-
-    extensionsdictionary = extensions.enabled()[0]
-    extensionnames.extend(extensionsdictionary.keys())
-
-    extensionsdictionary = extensions.disabled()[0]
-    extensionnames.extend(extensionsdictionary.keys())
-
-    return extensionnames
-
+    return extensions.enabled().keys() + extensions.disabled().keys()
 
 if __name__ == "__main__":
     show_doc(sys.stdout)
--- a/doc/hgignore.5.txt	Wed Jun 01 16:32:48 2011 -0500
+++ b/doc/hgignore.5.txt	Sat Jun 18 17:03:01 2011 -0500
@@ -11,85 +11,7 @@
 :Manual section: 5
 :Manual group:   Mercurial Manual
 
-Synopsis
---------
-
-The Mercurial system uses a file called ``.hgignore`` in the root
-directory of a repository to control its behavior when it searches
-for files that it is not currently tracking.
-
-Description
------------
-
-The working directory of a Mercurial repository will often contain
-files that should not be tracked by Mercurial. These include backup
-files created by editors and build products created by compilers.
-These files can be ignored by listing them in a ``.hgignore`` file in
-the root of the working directory. The ``.hgignore`` file must be
-created manually. It is typically put under version control, so that
-the settings will propagate to other repositories with push and pull.
-
-An untracked file is ignored if its path relative to the repository
-root directory, or any prefix path of that path, is matched against
-any pattern in ``.hgignore``.
-
-For example, say we have an untracked file, ``file.c``, at
-``a/b/file.c`` inside our repository. Mercurial will ignore ``file.c``
-if any pattern in ``.hgignore`` matches ``a/b/file.c``, ``a/b`` or ``a``.
-
-In addition, a Mercurial configuration file can reference a set of
-per-user or global ignore files. See the |hgrc(5)|_ man page for details
-of how to configure these files. Look for the "ignore" entry in the
-"ui" section.
-
-To control Mercurial's handling of files that it manages, see the
-|hg(1)|_ man page. Look for the ``-I`` and ``-X`` options.
-
-Syntax
-------
-
-An ignore file is a plain text file consisting of a list of patterns,
-with one pattern per line. Empty lines are skipped. The ``#``
-character is treated as a comment character, and the ``\`` character
-is treated as an escape character.
-
-Mercurial supports several pattern syntaxes. The default syntax used
-is Python/Perl-style regular expressions.
-
-To change the syntax used, use a line of the following form::
-
-  syntax: NAME
-
-where ``NAME`` is one of the following:
-
-``regexp``
-  Regular expression, Python/Perl syntax.
-``glob``
-  Shell-style glob.
-
-The chosen syntax stays in effect when parsing all patterns that
-follow, until another syntax is selected.
-
-Neither glob nor regexp patterns are rooted. A glob-syntax pattern of
-the form ``*.c`` will match a file ending in ``.c`` in any directory,
-and a regexp pattern of the form ``\.c$`` will do the same. To root a
-regexp pattern, start it with ``^``.
-
-Example
--------
-
-Here is an example ignore file. ::
-
-  # use glob syntax.
-  syntax: glob
-
-  *.elc
-  *.pyc
-  *~
-
-  # switch to regexp syntax.
-  syntax: regexp
-  ^\.pc/
+.. include:: ../mercurial/help/hgignore.txt
 
 Author
 ------
@@ -109,3 +31,4 @@
 Public License version 2 or any later version.
 
 .. include:: common.txt
+
--- a/doc/hgmanpage.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/doc/hgmanpage.py	Sat Jun 18 17:03:01 2011 -0500
@@ -48,6 +48,7 @@
 
 from docutils import nodes, writers, languages
 import roman
+import inspect
 
 FIELD_LIST_INDENT = 7
 DEFINITION_LIST_INDENT = 7
@@ -160,7 +161,12 @@
         nodes.NodeVisitor.__init__(self, document)
         self.settings = settings = document.settings
         lcode = settings.language_code
-        self.language = languages.get_language(lcode)
+        arglen = len(inspect.getargspec(languages.get_language)[0])
+        if arglen == 2:
+            self.language = languages.get_language(lcode,
+                                                   self.document.reporter)
+        else:
+            self.language = languages.get_language(lcode)
         self.head = []
         self.body = []
         self.foot = []
--- a/doc/hgrc.5.txt	Wed Jun 01 16:32:48 2011 -0500
+++ b/doc/hgrc.5.txt	Sat Jun 18 17:03:01 2011 -0500
@@ -19,1119 +19,7 @@
 Synopsis
 --------
 
-The Mercurial system uses a set of configuration files to control
-aspects of its behavior.
-
-Files
------
-
-Mercurial reads configuration data from several files, if they exist.
-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 earlier paths override later
-ones.
-
-| (Unix, Windows) ``<repo>/.hg/hgrc``
-
-    Per-repository configuration options that only apply in a
-    particular repository. This file is not version-controlled, and
-    will not get transferred during a "clone" operation. Options in
-    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.
-
-| (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) ``<install-dir>\Mercurial.ini``
-| (Windows) ``<install-dir>\hgrc.d\*.rc``
-| (Windows) ``HKEY_LOCAL_MACHINE\SOFTWARE\Mercurial``
-
-    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.  Mercurial checks each of these locations in the specified
-    order until one or more configuration files are detected.  If the
-    pywin32 extensions are not installed, Mercurial will only look for
-    site-wide configuration in ``C:\Mercurial\Mercurial.ini``.
-
-Syntax
-------
-
-A configuration file consists of sections, led by a ``[section]`` header
-and followed by ``name = value`` entries (sometimes called
-``configuration keys``)::
-
-    [spam]
-    eggs=ham
-    green=
-       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.
-
-Configuration keys can be set multiple times, in which case mercurial
-will use the value that was configured last. As an example::
-
-    [spam]
-    eggs=large
-    ham=serrano
-    eggs=small
-
-This would set the configuration key named ``eggs`` to ``small``.
-
-It is also possible to define a section multiple times. A section can
-be redefined on the same and/or on different hgrc files. For example::
-
-    [foo]
-    eggs=large
-    ham=serrano
-    eggs=small
-
-    [bar]
-    eggs=ham
-    green=
-       eggs
-
-    [foo]
-    ham=prosciutto
-    eggs=medium
-    bread=toasted
-
-This would set the ``eggs``, ``ham``, and ``bread`` configuration keys
-of the ``foo`` section to ``medium``, ``prosciutto``, and ``toasted``,
-respectively. As you can see there only thing that matters is the last
-value that was set for each of the configuration keys.
-
-If a configuration key is set multiple times in different
-configuration files the final value will depend on the order in which
-the different configuration files are read, with settings from earlier
-paths overriding later ones as described on the ``Files`` section
-above.
-
-A line of the form ``%include file`` will include ``file`` into the
-current configuration file. The inclusion is recursive, which means
-that included files can include other files. Filenames are relative to
-the configuration file in which the ``%include`` directive is found.
-Environment variables and ``~user`` constructs are expanded in
-``file``. This lets you do something like::
-
-  %include ~/.hgrc.d/$HOST.rc
-
-to include a different configuration file on each computer you use.
-
-A line with ``%unset name`` will remove ``name`` from the current
-section, if it has been set previously.
-
-The values are either free-form text strings, lists of text strings,
-or Boolean values. Boolean values can be set to true using any of "1",
-"yes", "true", or "on" and to false using "0", "no", "false", or "off"
-(all case insensitive).
-
-List values are separated by whitespace or comma, except when values are
-placed in double quotation marks::
-
-  allow_read = "John Doe, PhD", brian, betty
-
-Quotation marks can be escaped by prefixing them with a backslash. Only
-quotation marks at the beginning of a word is counted as a quotation
-(e.g., ``foo"bar baz`` is the list of ``foo"bar`` and ``baz``).
-
-Sections
---------
-
-This section describes the different sections that may appear in a
-Mercurial "hgrc" file, the purpose of each section, its possible keys,
-and their possible values.
-
-``alias``
-"""""""""
-Defines command aliases.
-Aliases allow you to define your own commands in terms of other
-commands (or aliases), optionally including arguments.
-
-Alias definitions consist of lines of the form::
-
-    <alias> = <command> [<argument]...
-
-For example, this definition::
-
-    latest = log --limit 5
-
-creates a new command ``latest`` that shows only the five most recent
-changesets. You can define subsequent aliases using earlier ones::
-
-    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!
-
-An alias can start with an exclamation point (``!``) to make it a
-shell alias. A shell alias is executed with the shell and will let you
-run arbitrary commands. As an example, ::
-
-   echo = !echo
-
-will let you do ``hg echo foo`` to have ``foo`` printed in your
-terminal. A better example might be::
-
-   purge = !$HG status --no-status --unknown -0 | xargs -0 rm
-
-which will make ``hg purge`` delete all unknown files in the
-repository in the same manner as the purge extension.
-
-Shell aliases are executed in an environment where ``$HG`` expand to
-the path of the Mercurial that was used to execute the alias. This is
-useful when you want to call further Mercurial commands in a shell
-alias, as was done above for the purge alias. In addition,
-``$HG_ARGS`` expand to the arguments given to Mercurial. In the ``hg
-echo foo`` call above, ``$HG_ARGS`` would expand to ``echo foo``.
-
-``auth``
-""""""""
-
-Authentication credentials for HTTP authentication. This section
-allows you to store usernames and passwords for use when logging
-*into* HTTP servers. See the web_ configuration section if you want to
-configure *who* can login to your HTTP server.
-
-Each line has the following format::
-
-    <name>.<argument> = <value>
-
-where ``<name>`` is used to group arguments into authentication
-entries. Example::
-
-    foo.prefix = hg.intevation.org/mercurial
-    foo.username = foo
-    foo.password = bar
-    foo.schemes = http https
-
-    bar.prefix = secure.example.org
-    bar.key = path/to/file.key
-    bar.cert = path/to/file.cert
-    bar.schemes = https
-
-Supported arguments:
-
-``prefix``
-    Either ``*`` or a URI prefix with or without the scheme part.
-    The authentication entry with the longest matching prefix is used
-    (where ``*`` matches everything and counts as a match of length
-    1). If the prefix doesn't include a scheme, the match is performed
-    against the URI with its scheme stripped as well, and the schemes
-    argument, q.v., is then subsequently consulted.
-``username``
-    Optional. Username to authenticate with. If not given, and the
-    remote site requires basic or digest authentication, the user will
-    be prompted for it. Environment variables are expanded in the
-    username letting you do ``foo.username = $USER``.
-``password``
-    Optional. Password to authenticate with. If not given, and the
-    remote site requires basic or digest authentication, the user
-    will be prompted for it.
-``key``
-    Optional. PEM encoded client certificate key file. Environment
-    variables are expanded in the filename.
-``cert``
-    Optional. PEM encoded client certificate chain file. Environment
-    variables are expanded in the filename.
-``schemes``
-    Optional. Space separated list of URI schemes to use this
-    authentication entry with. Only used if the prefix doesn't include
-    a scheme. Supported schemes are http and https. They will match
-    static-http and static-https respectively, as well.
-    Default: https.
-
-If no suitable authentication entry is found, the user is prompted
-for credentials as usual if required by the remote.
-
-
-``decode/encode``
-"""""""""""""""""
-Filters for transforming files on checkout/checkin. This would
-typically be used for newline processing or other
-localization/canonicalization of files.
-
-Filters consist of a filter pattern followed by a filter command.
-Filter patterns are globs by default, rooted at the repository root.
-For example, to match any file ending in ``.txt`` in the root
-directory only, use the pattern ``*.txt``. To match any file ending
-in ``.c`` anywhere in the repository, use the pattern ``**.c``.
-For each file only the first matching filter applies.
-
-The filter command can start with a specifier, either ``pipe:`` or
-``tempfile:``. If no specifier is given, ``pipe:`` is used by default.
-
-A ``pipe:`` command must accept data on stdin and return the transformed
-data on stdout.
-
-Pipe example::
-
-  [encode]
-  # uncompress gzip files on checkin to improve delta compression
-  # note: not necessarily a good idea, just an example
-  *.gz = pipe: gunzip
-
-  [decode]
-  # recompress gzip files when writing them to the working dir (we
-  # can safely omit "pipe:", because it's the default)
-  *.gz = gzip
-
-A ``tempfile:`` command is a template. The string ``INFILE`` is replaced
-with the name of a temporary file that contains the data to be
-filtered by the command. The string ``OUTFILE`` is replaced with the name
-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.
-
-This filter mechanism is used internally by the ``eol`` extension to
-translate line ending characters between Windows (CRLF) and Unix (LF)
-format. We suggest you use the ``eol`` extension for convenience.
-
-
-``defaults``
-""""""""""""
-
-(defaults are deprecated. Don't use them. Use aliases instead)
-
-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::
-
-  [defaults]
-  log = -v
-  status = -m
-
-The actual commands, instead of their aliases, must be used when
-defining command defaults. The command defaults will also be applied
-to the aliases of the commands defined.
-
-
-``diff``
-""""""""
-
-Settings used when displaying diffs. Everything except for ``unified`` is a
-Boolean and defaults to False.
-
-``git``
-    Use git extended diff format.
-``nodates``
-    Don't include dates in diff headers.
-``showfunc``
-    Show which function each change is in.
-``ignorews``
-    Ignore white space when comparing lines.
-``ignorewsamount``
-    Ignore changes in the amount of white space.
-``ignoreblanklines``
-    Ignore changes whose lines are all blank.
-``unified``
-    Number of lines of context to show.
-
-``email``
-"""""""""
-Settings for extensions that send email messages.
-
-``from``
-    Optional. Email address to use in "From" header and SMTP envelope
-    of outgoing messages.
-``to``
-    Optional. Comma-separated list of recipients' email addresses.
-``cc``
-    Optional. Comma-separated list of carbon copy recipients'
-    email addresses.
-``bcc``
-    Optional. Comma-separated list of blind carbon copy recipients'
-    email addresses.
-``method``
-    Optional. Method to use to send email messages. If value is ``smtp``
-    (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
-    ``/usr/sbin/sendmail`` is enough to use sendmail to send messages.
-``charsets``
-    Optional. Comma-separated list of character sets considered
-    convenient for recipients. Addresses, headers, and parts not
-    containing patches of outgoing messages will be encoded in the
-    first character set to which conversion from local encoding
-    (``$HGENCODING``, ``ui.fallbackencoding``) succeeds. If correct
-    conversion fails, the text in question is sent as is. Defaults to
-    empty (explicit) list.
-
-    Order of outgoing email character sets:
-
-    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::
-
-  [email]
-  from = Joseph User <joe.user@example.com>
-  method = /usr/sbin/sendmail
-  # charsets for western Europeans
-  # us-ascii, utf-8 omitted, as they are tried first and last
-  charsets = iso-8859-1, iso-8859-15, windows-1252
-
-
-``extensions``
-""""""""""""""
-
-Mercurial has an extension mechanism for adding new features. To
-enable an extension, create an entry for it in this section.
-
-If you know that the extension is already in Python's search path,
-you can give the name of the module, followed by ``=``, with nothing
-after the ``=``.
-
-Otherwise, give a name that you choose, followed by ``=``, followed by
-the path to the ``.py`` file (including the file name extension) that
-defines the extension.
-
-To explicitly disable an extension that is enabled in an hgrc of
-broader scope, prepend its path with ``!``, as in ``foo = !/ext/path``
-or ``foo = !`` when path is not supplied.
-
-Example for ``~/.hgrc``::
-
-  [extensions]
-  # (the mq extension will get loaded from Mercurial's path)
-  mq =
-  # (this extension will get loaded from the file specified)
-  myfeature = ~/.hgext/myfeature.py
-
-
-``hostfingerprints``
-""""""""""""""""""""
-
-Fingerprints of the certificates of known HTTPS servers.
-A HTTPS connection to a server with a fingerprint configured here will
-only succeed if the servers certificate matches the fingerprint.
-This is very similar to how ssh known hosts works.
-The fingerprint is the SHA-1 hash value of the DER encoded certificate.
-The CA chain and web.cacerts is not used for servers with a fingerprint.
-
-For example::
-
-    [hostfingerprints]
-    hg.intevation.org = 38:76:52:7c:87:26:9a:8f:4a:f8:d3:de:08:45:3b:ea:d6:4b:ee:cc
-
-This feature is only supported when using Python 2.6 or later.
-
-
-``format``
-""""""""""
-
-``usestore``
-    Enable or disable the "store" repository format which improves
-    compatibility with systems that fold case or otherwise mangle
-    filenames. Enabled by default. Disabling this option will allow
-    you to store longer filenames in some situations at the expense of
-    compatibility and ensures that the on-disk format of newly created
-    repositories will be compatible with Mercurial before version 0.9.4.
-
-``usefncache``
-    Enable or disable the "fncache" repository format which enhances
-    the "store" repository format (which has to be enabled to use
-    fncache) to allow longer filenames and avoids using Windows
-    reserved names, e.g. "nul". Enabled by default. Disabling this
-    option ensures that the on-disk format of newly created
-    repositories will be compatible with Mercurial before version 1.1.
-
-``dotencode``
-    Enable or disable the "dotencode" repository format which enhances
-    the "fncache" repository format (which has to be enabled to use
-    dotencode) to avoid issues with filenames starting with ._ on
-    Mac OS X and spaces on Windows. Enabled by default. Disabling this
-    option ensures that the on-disk format of newly created
-    repositories will be compatible with Mercurial before version 1.7.
-
-``merge-patterns``
-""""""""""""""""""
-
-This section specifies merge tools to associate with particular file
-patterns. Tools matched here will take precedence over the default
-merge tool. Patterns are globs by default, rooted at the repository
-root.
-
-Example::
-
-  [merge-patterns]
-  **.c = kdiff3
-  **.jpg = myimgmerge
-
-``merge-tools``
-"""""""""""""""
-
-This section configures external merge tools to use for file-level
-merges.
-
-Example ``~/.hgrc``::
-
-  [merge-tools]
-  # Override stock tool location
-  kdiff3.executable = ~/bin/kdiff3
-  # Specify command line
-  kdiff3.args = $base $local $other -o $output
-  # Give higher priority
-  kdiff3.priority = 1
-
-  # Define new tool
-  myHtmlTool.args = -m $local $other $base $output
-  myHtmlTool.regkey = Software\FooSoftware\HtmlMerge
-  myHtmlTool.priority = 1
-
-Supported arguments:
-
-``priority``
-  The priority in which to evaluate this tool.
-  Default: 0.
-``executable``
-  Either just the name of the executable or its pathname.  On Windows,
-  the path can use environment variables with ${ProgramFiles} syntax.
-  Default: the tool name.
-``args``
-  The arguments to pass to the tool executable. You can refer to the
-  files being merged as well as the output file through these
-  variables: ``$base``, ``$local``, ``$other``, ``$output``.
-  Default: ``$local $base $other``
-``premerge``
-  Attempt to run internal non-interactive 3-way merge tool before
-  launching external tool.  Options are ``true``, ``false``, or ``keep``
-  to leave markers in the file if the premerge fails.
-  Default: True
-``binary``
-  This tool can merge binary files. Defaults to False, unless tool
-  was selected by file pattern match.
-``symlink``
-  This tool can merge symlinks. Defaults to False, even if tool was
-  selected by file pattern match.
-``check``
-  A list of merge success-checking options:
-
-  ``changed``
-    Ask whether merge was successful when the merged file shows no changes.
-  ``conflicts``
-    Check whether there are conflicts even though the tool reported success.
-  ``prompt``
-    Always prompt for merge success, regardless of success reported by tool.
-
-``checkchanged``
-  True is equivalent to ``check = changed``.
-  Default: False
-``checkconflicts``
-  True is equivalent to ``check = conflicts``.
-  Default: False
-``fixeol``
-  Attempt to fix up EOL changes caused by the merge tool.
-  Default: False
-``gui``
-  This tool requires a graphical interface to run. Default: False
-``regkey``
-  Windows registry key which describes install location of this
-  tool. Mercurial will search for this key first under
-  ``HKEY_CURRENT_USER`` and then under ``HKEY_LOCAL_MACHINE``.
-  Default: None
-``regkeyalt``
-  An alternate Windows registry key to try if the first key is not
-  found.  The alternate key uses the same ``regname`` and ``regappend``
-  semantics of the primary key.  The most common use for this key
-  is to search for 32bit applications on 64bit operating systems.
-  Default: None
-``regname``
-  Name of value to read from specified registry key. Defaults to the
-  unnamed (default) value.
-``regappend``
-  String to append to the value read from the registry, typically
-  the executable name of the tool.
-  Default: None
-
-
-``hooks``
-"""""""""
-Commands or Python functions that get automatically executed by
-various actions such as starting or finishing a commit. Multiple
-hooks can be run for the same action by appending a suffix to the
-action. Overriding a site-wide hook can be done by changing its
-value or setting it to an empty string.
-
-Example ``.hg/hgrc``::
-
-  [hooks]
-  # update working directory after adding changesets
-  changegroup.update = hg update
-  # do not use the site-wide hook
-  incoming =
-  incoming.email = /my/email/hook
-  incoming.autobuild = /my/build/hook
-
-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``.
-
-``changegroup``
-  Run after a changegroup has been added via push, pull or unbundle.
-  ID of the first new changeset is in ``$HG_NODE``. URL from which
-  changes came is in ``$HG_URL``.
-``commit``
-  Run after a changeset has been created in the local repository. ID
-  of the newly created changeset is in ``$HG_NODE``. Parent changeset
-  IDs are in ``$HG_PARENT1`` and ``$HG_PARENT2``.
-``incoming``
-  Run after a changeset has been pulled, pushed, or unbundled into
-  the local repository. The ID of the newly arrived changeset is in
-  ``$HG_NODE``. URL that was source of changes came is in ``$HG_URL``.
-``outgoing``
-  Run after sending changes from local repository to another. ID of
-  first changeset sent is in ``$HG_NODE``. Source of operation is in
-  ``$HG_SOURCE``; see "preoutgoing" hook for description.
-``post-<command>``
-  Run after successful invocations of the associated command. The
-  contents of the command line are passed as ``$HG_ARGS`` and the result
-  code in ``$HG_RESULT``. Parsed command line arguments are passed as 
-  ``$HG_PATS`` and ``$HG_OPTS``. These contain string representations of
-  the python data internally passed to <command>. ``$HG_OPTS`` is a 
-  dictionary of options (with unspecified options set to their defaults).
-  ``$HG_PATS`` is a list of arguments. Hook failure is ignored.
-``pre-<command>``
-  Run before executing the associated command. The contents of the
-  command line are passed as ``$HG_ARGS``. Parsed command line arguments
-  are passed as ``$HG_PATS`` and ``$HG_OPTS``. These contain string
-  representations of the data internally passed to <command>. ``$HG_OPTS``
-  is a  dictionary of options (with unspecified options set to their
-  defaults). ``$HG_PATS`` is a list of arguments. If the hook returns 
-  failure, the command doesn't execute and Mercurial returns the failure
-  code.
-``prechangegroup``
-  Run before a changegroup is added via push, pull or unbundle. Exit
-  status 0 allows the changegroup to proceed. Non-zero status will
-  cause the push, pull or unbundle to fail. URL from which changes
-  will come is in ``$HG_URL``.
-``precommit``
-  Run before starting a local commit. Exit status 0 allows the
-  commit to proceed. Non-zero status will cause the commit to fail.
-  Parent changeset IDs are in ``$HG_PARENT1`` and ``$HG_PARENT2``.
-``preoutgoing``
-  Run before collecting changes to send from the local repository to
-  another. Non-zero status will cause failure. This lets you prevent
-  pull over HTTP or SSH. Also prevents against local pull, push
-  (outbound) or bundle commands, but not effective, since you can
-  just copy files instead then. Source of operation is in
-  ``$HG_SOURCE``. If "serve", operation is happening on behalf of remote
-  SSH or HTTP repository. If "push", "pull" or "bundle", operation
-  is happening on behalf of repository on same system.
-``pretag``
-  Run before creating a tag. Exit status 0 allows the tag to be
-  created. Non-zero status will cause the tag to fail. ID of
-  changeset to tag is in ``$HG_NODE``. Name of tag is in ``$HG_TAG``. Tag is
-  local if ``$HG_LOCAL=1``, in repository if ``$HG_LOCAL=0``.
-``pretxnchangegroup``
-  Run after a changegroup has been added via push, pull or unbundle,
-  but before the transaction has been committed. Changegroup is
-  visible to hook program. This lets you validate incoming changes
-  before accepting them. Passed the ID of the first new changeset in
-  ``$HG_NODE``. Exit status 0 allows the transaction to commit. Non-zero
-  status will cause the transaction to be rolled back and the push,
-  pull or unbundle will fail. URL that was source of changes is in
-  ``$HG_URL``.
-``pretxncommit``
-  Run after a changeset has been created but the transaction not yet
-  committed. Changeset is visible to hook program. This lets you
-  validate commit message and changes. Exit status 0 allows the
-  commit to proceed. Non-zero status will cause the transaction to
-  be rolled back. ID of changeset is in ``$HG_NODE``. Parent changeset
-  IDs are in ``$HG_PARENT1`` and ``$HG_PARENT2``.
-``preupdate``
-  Run before updating the working directory. Exit status 0 allows
-  the update to proceed. Non-zero status will prevent the update.
-  Changeset ID of first new parent is in ``$HG_PARENT1``. If merge, ID
-  of second new parent is in ``$HG_PARENT2``.
-``tag``
-  Run after a tag is created. ID of tagged changeset is in ``$HG_NODE``.
-  Name of tag is in ``$HG_TAG``. Tag is local if ``$HG_LOCAL=1``, in
-  repository if ``$HG_LOCAL=0``.
-``update``
-  Run after updating the working directory. Changeset ID of first
-  new parent is in ``$HG_PARENT1``. If merge, ID of second new parent is
-  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:: 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::
-
-  hookname = python:modulename.submodule.callable
-  hookname = python:/path/to/python/module.py:callable
-
-Python hooks are run within the Mercurial process. Each hook is
-called with at least three keyword arguments: a ui object (keyword
-``ui``), a repository object (keyword ``repo``), and a ``hooktype``
-keyword that tells what kind of hook is used. Arguments listed as
-environment variables above are passed as keyword arguments, with no
-``HG_`` prefix, and names in lower case.
-
-If a Python hook returns a "true" value or raises an exception, this
-is treated as a failure.
-
-
-``http_proxy``
-""""""""""""""
-Used to access web-based Mercurial repositories through a HTTP
-proxy.
-
-``host``
-    Host name and (optional) port of the proxy server, for example
-    "myproxy:8000".
-``no``
-    Optional. Comma-separated list of host names that should bypass
-    the proxy.
-``passwd``
-    Optional. Password to authenticate with at the proxy server.
-``user``
-    Optional. User name to authenticate with at the proxy server.
-``always``
-    Optional. Always use the proxy, even for localhost and any entries
-    in ``http_proxy.no``. True or False. Default: False.
-
-``smtp``
-""""""""
-Configuration for extensions that need to send email messages.
-
-``host``
-    Host name of mail server, e.g. "mail.example.com".
-``port``
-    Optional. Port to connect to on mail server. Default: 25.
-``tls``
-    Optional. Method to enable TLS when connecting to mail server: starttls,
-    smtps or none. Default: none.
-``username``
-    Optional. User name for authenticating with the SMTP server.
-    Default: none.
-``password``
-    Optional. Password for authenticating with the SMTP server. If not
-    specified, interactive sessions will prompt the user for a
-    password; non-interactive sessions will fail. Default: none.
-``local_hostname``
-    Optional. It's the hostname that the sender can use to identify
-    itself to the MTA.
-
-
-``patch``
-"""""""""
-Settings used when applying patches, for instance through the 'import'
-command or with Mercurial Queues extension.
-
-``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 ignored when patching and the result line endings are
-    normalized to either LF (Unix) or CRLF (Windows). When set to
-    ``auto``, end of lines are again ignored while patching but line
-    endings in patched files are normalized to their original setting
-    on a per-file basis. If target file does not exist or has no end
-    of line, patch line endings are preserved.
-    Default: strict.
-
-
-``paths``
-"""""""""
-Assigns symbolic names to repositories. The left side is the
-symbolic name, and the right gives the directory or URL that is the
-location of the repository. Default paths can be declared by setting
-the following entries.
-
-``default``
-    Directory or URL to use when pulling if no source is specified.
-    Default is set to repository from which the current repository was
-    cloned.
-``default-push``
-    Optional. Directory or URL to use when pushing if no destination
-    is specified.
-
-
-``profiling``
-"""""""""""""
-Specifies profiling format and file output. In this section
-description, 'profiling data' stands for the raw data collected
-during profiling, while 'profiling report' stands for a statistical
-text report generated from the profiling data. The profiling is done
-using lsprof.
-
-``format``
-    Profiling format.
-    Default: text.
-
-    ``text``
-      Generate a profiling report. When saving to a file, it should be
-      noted that only the report is saved, and the profiling data is
-      not kept.
-    ``kcachegrind``
-      Format profiling data for kcachegrind use: when saving to a
-      file, the generated file can directly be loaded into
-      kcachegrind.
-``output``
-    File path where profiling data or report should be saved. If the
-    file exists, it is replaced. Default: None, data is printed on
-    stderr
-
-``server``
-""""""""""
-Controls generic server settings.
-
-``uncompressed``
-    Whether to allow clients to clone a repository using the
-    uncompressed streaming protocol. This transfers about 40% more
-    data than a regular clone, but uses less memory and CPU on both
-    server and client. Over a LAN (100 Mbps or better) or a very fast
-    WAN, an uncompressed streaming clone is a lot faster (~10x) than a
-    regular clone. Over most WAN connections (anything slower than
-    about 6 Mbps), uncompressed streaming is slower, because of the
-    extra data transfer overhead. This mode will also temporarily hold
-    the write lock while determining what data to transfer.
-    Default is True.
-
-``validate``
-    Whether to validate the completeness of pushed changesets by
-    checking that all new file revisions specified in manifests are
-    present. Default is False.
-
-``subpaths``
-""""""""""""
-Defines subrepositories source locations rewriting rules of the form::
-
-    <pattern> = <replacement>
-
-Where ``pattern`` is a regular expression matching the source and
-``replacement`` is the replacement string used to rewrite it. Groups
-can be matched in ``pattern`` and referenced in ``replacements``. For
-instance::
-
-    http://server/(.*)-hg/ = http://hg.server/\1/
-
-rewrites ``http://server/foo-hg/`` into ``http://hg.server/foo/``.
-
-All patterns are applied in definition order.
-
-``trusted``
-"""""""""""
-
-Mercurial will not use the settings in the
-``.hg/hgrc`` file from a repository if it doesn't belong to a trusted
-user or to a trusted group, as various hgrc features allow arbitrary
-commands to be run. This issue is often encountered when configuring
-hooks or extensions for shared repositories or servers. However,
-the web interface will use some safe settings from the ``[web]``
-section.
-
-This section specifies what users and groups are trusted. The
-current user is always trusted. To trust everybody, list a user or a
-group with name ``*``. These settings must be placed in an
-*already-trusted file* to take effect, such as ``$HOME/.hgrc`` of the
-user or service running Mercurial.
-
-``users``
-  Comma-separated list of trusted users.
-``groups``
-  Comma-separated list of trusted groups.
-
-
-``ui``
-""""""
-
-User interface controls.
-
-``archivemeta``
-    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.
-``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 is False.
-``commitsubrepos``
-    Whether to commit modified subrepositories when committing the
-    parent repository. If False and one subrepository has uncommitted
-    changes, abort the commit.
-    Default is True.
-``debug``
-    Print debugging information. True or False. Default is False.
-``editor``
-    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.
-``ignore``
-    A file to read per-user ignore patterns from. This file should be
-    in the same format as a repository-wide .hgignore file. This
-    option supports hook syntax, so if you want to specify multiple
-    ignore files, you can do so by setting something like
-    ``ignore.other = ~/.hgignore2``. For details of the ignore file
-    format, see the |hgignore(5)|_ man page.
-``interactive``
-    Allow to prompt the user. True or False. Default is True.
-``logtemplate``
-    Template string for commands that print changesets.
-``merge``
-    The conflict resolution program to use during a manual merge.
-    For more information on merge tools see :hg:`help merge-tools`.
-    For configuring merge tools see the merge-tools_ section.
-``patch``
-    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``.
-``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.
-``slash``
-    Display paths using a slash (``/``) as the path separator. This
-    only makes a difference on systems where the default path
-    separator is not the slash character (e.g. Windows uses the
-    backslash character (``\``)).
-    Default is False.
-``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.
-``style``
-    Name of style to use for command output.
-``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
-    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). Environment variables in the
-    username are expanded.
-``verbose``
-    Increase the amount of output printed. True or False. Default is False.
-
-
-``web``
-"""""""
-
-Web interface configuration. The settings in this section apply to
-both the builtin webserver (started by :hg:`serve`) and the script you
-run through a webserver (``hgweb.cgi`` and the derivatives for FastCGI
-and WSGI).
-
-The Mercurial webserver does no authentication (it does not prompt for
-usernames and passwords to validate *who* users are), but it does do
-authorization (it grants or denies access for *authenticated users*
-based on settings in this section). You must either configure your
-webserver to do authentication for you, or disable the authorization
-checks.
-
-For a quick setup in a trusted environment, e.g., a private LAN, where
-you want it to accept pushes from anybody, you can use the following
-command line::
-
-    $ hg --config web.allow_push=* --config web.push_ssl=False serve
-
-Note that this will allow anybody to push anything to the server and
-that this should not be used for public servers.
-
-The full set of options is:
-
-``accesslog``
-    Where to output the access log. Default is stdout.
-``address``
-    Interface address to bind to. Default is all.
-``allow_archive``
-    List of archive format (bz2, gz, zip) allowed for downloading.
-    Default is empty.
-``allowbz2``
-    (DEPRECATED) Whether to allow .tar.bz2 downloading of repository
-    revisions.
-    Default is False.
-``allowgz``
-    (DEPRECATED) Whether to allow .tar.gz downloading of repository
-    revisions.
-    Default is False.
-``allowpull``
-    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. The contents of the allow_push list are
-    examined after the deny_push list.
-``allow_read``
-    If the user has not already been denied repository access due to
-    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, 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 contents of the allow_read list are
-    examined after the deny_read list.
-``allowzip``
-    (DEPRECATED) Whether to allow .zip downloading of repository
-    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/``.
-``cacerts``
-    Path to file containing a list of PEM encoded certificate
-    authority certificates. Environment variables and ``~user``
-    constructs are expanded in the filename. If specified on the
-    client, then it will verify the identity of remote HTTPS servers
-    with these certificates. The form must be as follows::
-
-        -----BEGIN CERTIFICATE-----
-        ... (certificate in base64 PEM encoding) ...
-        -----END CERTIFICATE-----
-        -----BEGIN CERTIFICATE-----
-        ... (certificate in base64 PEM encoding) ...
-        -----END CERTIFICATE-----
-
-    This feature is only supported when using Python 2.6 or later. If you wish
-    to use it with earlier versions of Python, install the backported
-    version of the ssl library that is available from
-    ``http://pypi.python.org``.
-
-    You can use OpenSSL's CA certificate file if your platform has one.
-    On most Linux systems this will be ``/etc/ssl/certs/ca-certificates.crt``.
-    Otherwise you will have to generate this file manually.
-
-    To disable SSL verification temporarily, specify ``--insecure`` from
-    command line.
-``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.
-``deny_push``
-    Whether to deny pushing to the repository. If empty or not set,
-    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 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 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
-    content of the allow_read list (see description). If both
-    deny_read and allow_read are empty or not set, then access is
-    permitted to all users by default. If the repository is being
-    served via hgwebdir, denied users will not be able to see it in
-    the list of repositories. The contents of the deny_read list have
-    priority over (are examined before) the contents of the allow_read
-    list.
-``descend``
-    hgwebdir indexes will not descend into subdirectories. Only repositories
-    directly in the current path will be shown (other repositories are still
-    available from the index corresponding to their containing path).
-``description``
-    Textual description of the repository's purpose or contents.
-    Default is "unknown".
-``encoding``
-    Character encoding name. Default is the current locale charset.
-    Example: "UTF-8"
-``errorlog``
-    Where to output the error log. Default is stderr.
-``hidden``
-    Whether to hide the repository in the hgwebdir index.
-    Default is False.
-``ipv6``
-    Whether to use IPv6. Default is False.
-``name``
-    Repository name to use in the web interface. Default is current
-    working directory.
-``maxchanges``
-    Maximum number of changes to list on the changelog. Default is 10.
-``maxfiles``
-    Maximum number of files to list per changeset. Default is 10.
-``port``
-    Port to listen on. Default is 8000.
-``prefix``
-    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.
-``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/``.
-``stripes``
-    How many lines a "zebra stripe" should span in multiline output.
-    Default is 1; set to 0 to disable.
-``style``
-    Which template map style to use.
-``templates``
-    Where to find the HTML templates. Default is install path.
-
+.. include:: ../mercurial/help/config.txt
 
 Author
 ------
--- a/hg	Wed Jun 01 16:32:48 2011 -0500
+++ b/hg	Sat Jun 18 17:03:01 2011 -0500
@@ -33,6 +33,6 @@
 import mercurial.dispatch
 
 for fp in (sys.stdin, sys.stdout, sys.stderr):
-    mercurial.util.set_binary(fp)
+    mercurial.util.setbinary(fp)
 
 mercurial.dispatch.run()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hg2	Sat Jun 18 17:03:01 2011 -0500
@@ -0,0 +1,38 @@
+#!/usr/bin/env python
+#
+# mercurial - scalable distributed SCM
+#
+# Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2 or any later version.
+
+import os
+import sys
+
+libdir = '@LIBDIR@'
+
+if libdir != '@' 'LIBDIR' '@':
+    if not os.path.isabs(libdir):
+        libdir = os.path.join(os.path.dirname(os.path.realpath(__file__)),
+                              libdir)
+        libdir = os.path.abspath(libdir)
+    sys.path.insert(0, libdir)
+
+# enable importing on demand to reduce startup time
+try:
+    from mercurial import demandimport; demandimport.enable()
+except ImportError:
+    import sys
+    sys.stderr.write("abort: couldn't find mercurial libraries in [%s]\n" %
+                     ' '.join(sys.path))
+    sys.stderr.write("(check your install and PYTHONPATH)\n")
+    sys.exit(-1)
+
+import mercurial.util
+import mercurial.dispatch
+
+for fp in (sys.stdin, sys.stdout, sys.stderr):
+    mercurial.util.setbinary(fp)
+
+mercurial.dispatch.run()
--- a/hgext/bugzilla.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/hgext/bugzilla.py	Sat Jun 18 17:03:01 2011 -0500
@@ -1,6 +1,7 @@
 # bugzilla.py - bugzilla integration for mercurial
 #
 # Copyright 2006 Vadim Gelfer <vadim.gelfer@gmail.com>
+# Copyright 2011 Jim Hague <jim.hague@acm.org>
 #
 # This software may be used and distributed according to the terms of the
 # GNU General Public License version 2 or any later version.
@@ -8,97 +9,161 @@
 '''hooks for integrating with the Bugzilla bug tracker
 
 This hook extension adds comments on bugs in Bugzilla when changesets
-that refer to bugs by Bugzilla ID are seen. The hook does not change
-bug status.
+that refer to bugs by Bugzilla ID are seen. The comment is formatted using
+the Mercurial template mechanism.
+
+The hook does not change bug status.
+
+Three basic modes of access to Bugzilla are provided:
+
+1. Access via the Bugzilla XMLRPC interface. Requires Bugzilla 3.4 or later.
+
+2. Check data via the Bugzilla XMLRPC interface and submit bug change
+   via email to Bugzilla email interface. Requires Bugzilla 3.4 or later.
+
+3. Writing directly to the Bugzilla database. Only Bugzilla installations
+   using MySQL are supported. Requires Python MySQLdb.
 
-The hook updates the Bugzilla database directly. Only Bugzilla
-installations using MySQL are supported.
+Writing directly to the database is susceptible to schema changes, and
+relies on a Bugzilla contrib script to send out bug change
+notification emails. This script runs as the user running Mercurial,
+must be run on the host with the Bugzilla install, and requires
+permission to read Bugzilla configuration details and the necessary
+MySQL user and password to have full access rights to the Bugzilla
+database. For these reasons this access mode is now considered
+deprecated, and will not be updated for new Bugzilla versions going
+forward.
+
+Access via XMLRPC needs a Bugzilla username and password to be specified
+in the configuration. Comments are added under that username. Since the
+configuration must be readable by all Mercurial users, it is recommended
+that the rights of that user are restricted in Bugzilla to the minimum
+necessary to add comments.
 
-The hook relies on a Bugzilla script to send bug change notification
-emails. That script changes between Bugzilla versions; the
-'processmail' script used prior to 2.18 is replaced in 2.18 and
-subsequent versions by 'config/sendbugmail.pl'. Note that these will
-be run by Mercurial as the user pushing the change; you will need to
-ensure the Bugzilla install file permissions are set appropriately.
+Access via XMLRPC/email uses XMLRPC to query Bugzilla, but sends
+email to the Bugzilla email interface to submit comments to bugs.
+The From: address in the email is set to the email address of the Mercurial
+user, so the comment appears to come from the Mercurial user. In the event
+that the Mercurial user email is not recognised by Bugzilla as a Bugzilla
+user, the email associated with the Bugzilla username used to log into
+Bugzilla is used instead as the source of the comment.
+
+Configuration items common to all access modes:
+
+bugzilla.version
+  This access type to use. Values recognised are:
+
+  :``xmlrpc``:       Bugzilla XMLRPC interface.
+  :``xmlrpc+email``: Bugzilla XMLRPC and email interfaces.
+  :``3.0``:          MySQL access, Bugzilla 3.0 and later.
+  :``2.18``:         MySQL access, Bugzilla 2.18 and up to but not
+                     including 3.0.
+  :``2.16``:         MySQL access, Bugzilla 2.16 and up to but not
+                     including 2.18.
+
+bugzilla.regexp
+  Regular expression to match bug IDs in changeset commit message.
+  Must contain one "()" group. The default expression matches ``Bug
+  1234``, ``Bug no. 1234``, ``Bug number 1234``, ``Bugs 1234,5678``,
+  ``Bug 1234 and 5678`` and variations thereof. Matching is case
+  insensitive.
+
+bugzilla.style
+  The style file to use when formatting comments.
+
+bugzilla.template
+  Template to use when formatting comments. Overrides style if
+  specified. In addition to the usual Mercurial keywords, the
+  extension specifies:
 
-The extension is configured through three different configuration
-sections. These keys are recognized in the [bugzilla] section:
+  :``{bug}``:     The Bugzilla bug ID.
+  :``{root}``:    The full pathname of the Mercurial repository.
+  :``{webroot}``: Stripped pathname of the Mercurial repository.
+  :``{hgweb}``:   Base URL for browsing Mercurial repositories.
+
+  Default ``changeset {node|short} in repo {root} refers to bug
+  {bug}.\\ndetails:\\n\\t{desc|tabindent}``
+
+bugzilla.strip
+  The number of path separator characters to strip from the front of
+  the Mercurial repository path (``{root}`` in templates) to produce
+  ``{webroot}``. For example, a repository with ``{root}``
+  ``/var/local/my-project`` with a strip of 2 gives a value for
+  ``{webroot}`` of ``my-project``. Default 0.
 
-host
-  Hostname of the MySQL server holding the Bugzilla database.
+web.baseurl
+  Base URL for browsing Mercurial repositories. Referenced from
+  templates as ``{hgweb}``.
+
+Configuration items common to XMLRPC+email and MySQL access modes:
+
+bugzilla.usermap
+  Path of file containing Mercurial committer email to Bugzilla user email
+  mappings. If specified, the file should contain one mapping per
+  line::
+
+    committer = Bugzilla user
+
+  See also the ``[usermap]`` section.
+
+The ``[usermap]`` section is used to specify mappings of Mercurial
+committer email to Bugzilla user email. See also ``bugzilla.usermap``.
+Contains entries of the form ``committer = Bugzilla user``.
 
-db
-  Name of the Bugzilla database in MySQL. Default 'bugs'.
+XMLRPC access mode configuration:
+
+bugzilla.bzurl
+  The base URL for the Bugzilla installation.
+  Default ``http://localhost/bugzilla``.
+
+bugzilla.user
+  The username to use to log into Bugzilla via XMLRPC. Default
+  ``bugs``.
+
+bugzilla.password
+  The password for Bugzilla login.
+
+XMLRPC+email access mode uses the XMLRPC access mode configuration items,
+and also:
 
-user
-  Username to use to access MySQL server. Default 'bugs'.
+bugzilla.bzemail
+  The Bugzilla email address.
+
+In addition, the Mercurial email settings must be configured. See the
+documentation in hgrc(5), sections ``[email]`` and ``[smtp]``.
+
+MySQL access mode configuration:
 
-password
+bugzilla.host
+  Hostname of the MySQL server holding the Bugzilla database.
+  Default ``localhost``.
+
+bugzilla.db
+  Name of the Bugzilla database in MySQL. Default ``bugs``.
+
+bugzilla.user
+  Username to use to access MySQL server. Default ``bugs``.
+
+bugzilla.password
   Password to use to access MySQL server.
 
-timeout
+bugzilla.timeout
   Database connection timeout (seconds). Default 5.
 
-version
-  Bugzilla version. Specify '3.0' for Bugzilla versions 3.0 and later,
-  '2.18' for Bugzilla versions from 2.18 and '2.16' for versions prior
-  to 2.18.
-
-bzuser
+bugzilla.bzuser
   Fallback Bugzilla user name to record comments with, if changeset
   committer cannot be found as a Bugzilla user.
 
-bzdir
+bugzilla.bzdir
    Bugzilla install directory. Used by default notify. Default
-   '/var/www/html/bugzilla'.
-
-notify
-  The command to run to get Bugzilla to send bug change notification
-  emails. Substitutes from a map with 3 keys, 'bzdir', 'id' (bug id)
-  and 'user' (committer bugzilla email). Default depends on version;
-  from 2.18 it is "cd %(bzdir)s && perl -T contrib/sendbugmail.pl
-  %(id)s %(user)s".
-
-regexp
-  Regular expression to match bug IDs in changeset commit message.
-  Must contain one "()" group. The default expression matches 'Bug
-  1234', 'Bug no. 1234', 'Bug number 1234', 'Bugs 1234,5678', 'Bug
-  1234 and 5678' and variations thereof. Matching is case insensitive.
-
-style
-  The style file to use when formatting comments.
-
-template
-  Template to use when formatting comments. Overrides style if
-  specified. In addition to the usual Mercurial keywords, the
-  extension specifies::
+   ``/var/www/html/bugzilla``.
 
-    {bug}       The Bugzilla bug ID.
-    {root}      The full pathname of the Mercurial repository.
-    {webroot}   Stripped pathname of the Mercurial repository.
-    {hgweb}     Base URL for browsing Mercurial repositories.
-
-  Default 'changeset {node|short} in repo {root} refers '
-          'to bug {bug}.\\ndetails:\\n\\t{desc|tabindent}'
-
-strip
-  The number of slashes to strip from the front of {root} to produce
-  {webroot}. Default 0.
-
-usermap
-  Path of file containing Mercurial committer ID to Bugzilla user ID
-  mappings. If specified, the file should contain one mapping per
-  line, "committer"="Bugzilla user". See also the [usermap] section.
-
-The [usermap] section is used to specify mappings of Mercurial
-committer ID to Bugzilla user ID. See also [bugzilla].usermap.
-"committer"="Bugzilla user"
-
-Finally, the [web] section supports one entry:
-
-baseurl
-  Base URL for browsing Mercurial repositories. Reference from
-  templates as {hgweb}.
+bugzilla.notify
+  The command to run to get Bugzilla to send bug change notification
+  emails. Substitutes from a map with 3 keys, ``bzdir``, ``id`` (bug
+  id) and ``user`` (committer bugzilla email). Default depends on
+  version; from 2.18 it is "cd %(bzdir)s && perl -T
+  contrib/sendbugmail.pl %(id)s %(user)s".
 
 Activating the extension::
 
@@ -109,11 +174,58 @@
     # run bugzilla hook on every change pulled or pushed in here
     incoming.bugzilla = python:hgext.bugzilla.hook
 
-Example configuration:
+Example configurations:
+
+XMLRPC example configuration. This uses the Bugzilla at
+``http://my-project.org/bugzilla``, logging in as user
+``bugmail@my-project.org`` with password ``plugh``. It is used with a
+collection of Mercurial repositories in ``/var/local/hg/repos/``,
+with a web interface at ``http://my-project.org/hg``. ::
+
+    [bugzilla]
+    bzurl=http://my-project.org/bugzilla
+    user=bugmail@my-project.org
+    password=plugh
+    version=xmlrpc
+    template=Changeset {node|short} in {root|basename}.
+             {hgweb}/{webroot}/rev/{node|short}\\n
+             {desc}\\n
+    strip=5
+
+    [web]
+    baseurl=http://my-project.org/hg
 
-This example configuration is for a collection of Mercurial
-repositories in /var/local/hg/repos/ used with a local Bugzilla 3.2
-installation in /opt/bugzilla-3.2. ::
+XMLRPC+email example configuration. This uses the Bugzilla at
+``http://my-project.org/bugzilla``, logging in as user
+``bugmail@my-project.org`` with password ``plugh``. It is used with a
+collection of Mercurial repositories in ``/var/local/hg/repos/``,
+with a web interface at ``http://my-project.org/hg``. Bug comments
+are sent to the Bugzilla email address
+``bugzilla@my-project.org``. ::
+
+    [bugzilla]
+    bzurl=http://my-project.org/bugzilla
+    user=bugmail@my-project.org
+    password=plugh
+    version=xmlrpc
+    bzemail=bugzilla@my-project.org
+    template=Changeset {node|short} in {root|basename}.
+             {hgweb}/{webroot}/rev/{node|short}\\n
+             {desc}\\n
+    strip=5
+
+    [web]
+    baseurl=http://my-project.org/hg
+
+    [usermap]
+    user@emaildomain.com=user.name@bugzilladomain.com
+
+MySQL example configuration. This has a local Bugzilla 3.2 installation
+in ``/opt/bugzilla-3.2``. The MySQL database is on ``localhost``,
+the Bugzilla database name is ``bugs`` and MySQL is
+accessed with MySQL username ``bugs`` password ``XYZZY``. It is used
+with a collection of Mercurial repositories in ``/var/local/hg/repos/``,
+with a web interface at ``http://my-project.org/hg``. ::
 
     [bugzilla]
     host=localhost
@@ -127,46 +239,98 @@
     strip=5
 
     [web]
-    baseurl=http://dev.domain.com/hg
+    baseurl=http://my-project.org/hg
 
     [usermap]
     user@emaildomain.com=user.name@bugzilladomain.com
 
-Commits add a comment to the Bugzilla bug record of the form::
+All the above add a comment to the Bugzilla bug record of the form::
 
     Changeset 3b16791d6642 in repository-name.
-    http://dev.domain.com/hg/repository-name/rev/3b16791d6642
+    http://my-project.org/hg/repository-name/rev/3b16791d6642
 
     Changeset commit comment. Bug 1234.
 '''
 
 from mercurial.i18n import _
 from mercurial.node import short
-from mercurial import cmdutil, templater, util
-import re, time
-
-MySQLdb = None
+from mercurial import cmdutil, mail, templater, util
+import re, time, xmlrpclib
 
-def buglist(ids):
-    return '(' + ','.join(map(str, ids)) + ')'
-
-class bugzilla_2_16(object):
-    '''support for bugzilla version 2.16.'''
+class bzaccess(object):
+    '''Base class for access to Bugzilla.'''
 
     def __init__(self, ui):
         self.ui = ui
+        usermap = self.ui.config('bugzilla', 'usermap')
+        if usermap:
+            self.ui.readconfig(usermap, sections=['usermap'])
+
+    def map_committer(self, user):
+        '''map name of committer to Bugzilla user name.'''
+        for committer, bzuser in self.ui.configitems('usermap'):
+            if committer.lower() == user.lower():
+                return bzuser
+        return user
+
+    # Methods to be implemented by access classes.
+    def filter_real_bug_ids(self, ids):
+        '''remove bug IDs that do not exist in Bugzilla from set.'''
+        pass
+
+    def filter_cset_known_bug_ids(self, node, ids):
+        '''remove bug IDs where node occurs in comment text from set.'''
+        pass
+
+    def add_comment(self, bugid, text, committer):
+        '''add comment to bug.
+
+        If possible add the comment as being from the committer of
+        the changeset. Otherwise use the default Bugzilla user.
+        '''
+        pass
+
+    def notify(self, ids, committer):
+        '''Force sending of Bugzilla notification emails.'''
+        pass
+
+# Bugzilla via direct access to MySQL database.
+class bzmysql(bzaccess):
+    '''Support for direct MySQL access to Bugzilla.
+
+    The earliest Bugzilla version this is tested with is version 2.16.
+
+    If your Bugzilla is version 3.2 or above, you are strongly
+    recommended to use the XMLRPC access method instead.
+    '''
+
+    @staticmethod
+    def sql_buglist(ids):
+        '''return SQL-friendly list of bug ids'''
+        return '(' + ','.join(map(str, ids)) + ')'
+
+    _MySQLdb = None
+
+    def __init__(self, ui):
+        try:
+            import MySQLdb as mysql
+            bzmysql._MySQLdb = mysql
+        except ImportError, err:
+            raise util.Abort(_('python mysql support not available: %s') % err)
+
+        bzaccess.__init__(self, ui)
+
         host = self.ui.config('bugzilla', 'host', 'localhost')
         user = self.ui.config('bugzilla', 'user', 'bugs')
         passwd = self.ui.config('bugzilla', 'password')
         db = self.ui.config('bugzilla', 'db', 'bugs')
         timeout = int(self.ui.config('bugzilla', 'timeout', 5))
-        usermap = self.ui.config('bugzilla', 'usermap')
-        if usermap:
-            self.ui.readconfig(usermap, sections=['usermap'])
         self.ui.note(_('connecting to %s:%s as %s, password %s\n') %
                      (host, db, user, '*' * len(passwd)))
-        self.conn = MySQLdb.connect(host=host, user=user, passwd=passwd,
-                                    db=db, connect_timeout=timeout)
+        self.conn = bzmysql._MySQLdb.connect(host=host,
+                                                   user=user, passwd=passwd,
+                                                   db=db,
+                                                   connect_timeout=timeout)
         self.cursor = self.conn.cursor()
         self.longdesc_id = self.get_longdesc_id()
         self.user_ids = {}
@@ -177,7 +341,7 @@
         self.ui.note(_('query: %s %s\n') % (args, kwargs))
         try:
             self.cursor.execute(*args, **kwargs)
-        except MySQLdb.MySQLError:
+        except bzmysql._MySQLdb.MySQLError:
             self.ui.note(_('failed query: %s %s\n') % (args, kwargs))
             raise
 
@@ -190,22 +354,22 @@
         return ids[0][0]
 
     def filter_real_bug_ids(self, ids):
-        '''filter not-existing bug ids from list.'''
-        self.run('select bug_id from bugs where bug_id in %s' % buglist(ids))
-        return sorted([c[0] for c in self.cursor.fetchall()])
+        '''filter not-existing bug ids from set.'''
+        self.run('select bug_id from bugs where bug_id in %s' %
+                 bzmysql.sql_buglist(ids))
+        return set([c[0] for c in self.cursor.fetchall()])
 
-    def filter_unknown_bug_ids(self, node, ids):
-        '''filter bug ids from list that already refer to this changeset.'''
+    def filter_cset_known_bug_ids(self, node, ids):
+        '''filter bug ids that already refer to this changeset from set.'''
 
         self.run('''select bug_id from longdescs where
                     bug_id in %s and thetext like "%%%s%%"''' %
-                 (buglist(ids), short(node)))
-        unknown = set(ids)
+                 (bzmysql.sql_buglist(ids), short(node)))
         for (id,) in self.cursor.fetchall():
             self.ui.status(_('bug %d already knows about changeset %s\n') %
                            (id, short(node)))
-            unknown.discard(id)
-        return sorted(unknown)
+            ids.discard(id)
+        return ids
 
     def notify(self, ids, committer):
         '''tell bugzilla to send mail.'''
@@ -230,7 +394,7 @@
             if ret:
                 self.ui.warn(out)
                 raise util.Abort(_('bugzilla notify command %s') %
-                                 util.explain_exit(ret)[0])
+                                 util.explainexit(ret)[0])
         self.ui.status(_('done\n'))
 
     def get_user_id(self, user):
@@ -251,15 +415,8 @@
             self.user_ids[user] = userid
             return userid
 
-    def map_committer(self, user):
-        '''map name of committer to bugzilla user name.'''
-        for committer, bzuser in self.ui.configitems('usermap'):
-            if committer.lower() == user.lower():
-                return bzuser
-        return user
-
     def get_bugzilla_user(self, committer):
-        '''see if committer is a registered bugzilla user. Return
+        '''See if committer is a registered bugzilla user. Return
         bugzilla username and userid if so. If not, return default
         bugzilla username and userid.'''
         user = self.map_committer(committer)
@@ -292,19 +449,19 @@
                  (bugid, userid, now, self.longdesc_id))
         self.conn.commit()
 
-class bugzilla_2_18(bugzilla_2_16):
+class bzmysql_2_18(bzmysql):
     '''support for bugzilla 2.18 series.'''
 
     def __init__(self, ui):
-        bugzilla_2_16.__init__(self, ui)
+        bzmysql.__init__(self, ui)
         self.default_notify = \
             "cd %(bzdir)s && perl -T contrib/sendbugmail.pl %(id)s %(user)s"
 
-class bugzilla_3_0(bugzilla_2_18):
+class bzmysql_3_0(bzmysql_2_18):
     '''support for bugzilla 3.0 series.'''
 
     def __init__(self, ui):
-        bugzilla_2_18.__init__(self, ui)
+        bzmysql_2_18.__init__(self, ui)
 
     def get_longdesc_id(self):
         '''get identity of longdesc field'''
@@ -314,13 +471,176 @@
             raise util.Abort(_('unknown database schema'))
         return ids[0][0]
 
+# Buzgilla via XMLRPC interface.
+
+class CookieSafeTransport(xmlrpclib.SafeTransport):
+    """A SafeTransport that retains cookies over its lifetime.
+
+    The regular xmlrpclib transports ignore cookies. Which causes
+    a bit of a problem when you need a cookie-based login, as with
+    the Bugzilla XMLRPC interface.
+
+    So this is a SafeTransport which looks for cookies being set
+    in responses and saves them to add to all future requests.
+    It appears a SafeTransport can do both HTTP and HTTPS sessions,
+    which saves us having to do a CookieTransport too.
+    """
+
+    # Inspiration drawn from
+    # http://blog.godson.in/2010/09/how-to-make-python-xmlrpclib-client.html
+    # http://www.itkovian.net/base/transport-class-for-pythons-xml-rpc-lib/
+
+    cookies = []
+    def send_cookies(self, connection):
+        if self.cookies:
+            for cookie in self.cookies:
+                connection.putheader("Cookie", cookie)
+
+    def request(self, host, handler, request_body, verbose=0):
+        self.verbose = verbose
+
+        # issue XML-RPC request
+        h = self.make_connection(host)
+        if verbose:
+            h.set_debuglevel(1)
+
+        self.send_request(h, handler, request_body)
+        self.send_host(h, host)
+        self.send_cookies(h)
+        self.send_user_agent(h)
+        self.send_content(h, request_body)
+
+        # Deal with differences between Python 2.4-2.6 and 2.7.
+        # In the former h is a HTTP(S). In the latter it's a
+        # HTTP(S)Connection. Luckily, the 2.4-2.6 implementation of
+        # HTTP(S) has an underlying HTTP(S)Connection, so extract
+        # that and use it.
+        try:
+            response = h.getresponse()
+        except AttributeError:
+            response = h._conn.getresponse()
+
+        # Add any cookie definitions to our list.
+        for header in response.msg.getallmatchingheaders("Set-Cookie"):
+            val = header.split(": ", 1)[1]
+            cookie = val.split(";", 1)[0]
+            self.cookies.append(cookie)
+
+        if response.status != 200:
+            raise xmlrpclib.ProtocolError(host + handler, response.status,
+                                          response.reason, response.msg.headers)
+
+        payload = response.read()
+        parser, unmarshaller = self.getparser()
+        parser.feed(payload)
+        parser.close()
+
+        return unmarshaller.close()
+
+class bzxmlrpc(bzaccess):
+    """Support for access to Bugzilla via the Bugzilla XMLRPC API.
+
+    Requires a minimum Bugzilla version 3.4.
+    """
+
+    def __init__(self, ui):
+        bzaccess.__init__(self, ui)
+
+        bzweb = self.ui.config('bugzilla', 'bzurl',
+                               'http://localhost/bugzilla/')
+        bzweb = bzweb.rstrip("/") + "/xmlrpc.cgi"
+
+        user = self.ui.config('bugzilla', 'user', 'bugs')
+        passwd = self.ui.config('bugzilla', 'password')
+
+        self.bzproxy = xmlrpclib.ServerProxy(bzweb, CookieSafeTransport())
+        self.bzproxy.User.login(dict(login=user, password=passwd))
+
+    def get_bug_comments(self, id):
+        """Return a string with all comment text for a bug."""
+        c = self.bzproxy.Bug.comments(dict(ids=[id]))
+        return ''.join([t['text'] for t in c['bugs'][str(id)]['comments']])
+
+    def filter_real_bug_ids(self, ids):
+        res = set()
+        bugs = self.bzproxy.Bug.get(dict(ids=sorted(ids), permissive=True))
+        for bug in bugs['bugs']:
+            res.add(bug['id'])
+        return res
+
+    def filter_cset_known_bug_ids(self, node, ids):
+        for id in sorted(ids):
+            if self.get_bug_comments(id).find(short(node)) != -1:
+                self.ui.status(_('bug %d already knows about changeset %s\n') %
+                               (id, short(node)))
+                ids.discard(id)
+        return ids
+
+    def add_comment(self, bugid, text, committer):
+        self.bzproxy.Bug.add_comment(dict(id=bugid, comment=text))
+
+class bzxmlrpcemail(bzxmlrpc):
+    """Read data from Bugzilla via XMLRPC, send updates via email.
+
+    Advantages of sending updates via email:
+      1. Comments can be added as any user, not just logged in user.
+      2. Bug statuses and other fields not accessible via XMLRPC can
+        be updated. This is not currently used.
+    """
+
+    def __init__(self, ui):
+        bzxmlrpc.__init__(self, ui)
+
+        self.bzemail = self.ui.config('bugzilla', 'bzemail')
+        if not self.bzemail:
+            raise util.Abort(_("configuration 'bzemail' missing"))
+        mail.validateconfig(self.ui)
+
+    def send_bug_modify_email(self, bugid, commands, comment, committer):
+        '''send modification message to Bugzilla bug via email.
+
+        The message format is documented in the Bugzilla email_in.pl
+        specification. commands is a list of command lines, comment is the
+        comment text.
+
+        To stop users from crafting commit comments with
+        Bugzilla commands, specify the bug ID via the message body, rather
+        than the subject line, and leave a blank line after it.
+        '''
+        user = self.map_committer(committer)
+        matches = self.bzproxy.User.get(dict(match=[user]))
+        if not matches['users']:
+            user = self.ui.config('bugzilla', 'user', 'bugs')
+            matches = self.bzproxy.User.get(dict(match=[user]))
+            if not matches['users']:
+                raise util.Abort(_("default bugzilla user %s email not found") %
+                                 user)
+        user = matches['users'][0]['email']
+
+        text = "\n".join(commands) + "\n@bug_id = %d\n\n" % bugid + comment
+
+        _charsets = mail._charsets(self.ui)
+        user = mail.addressencode(self.ui, user, _charsets)
+        bzemail = mail.addressencode(self.ui, self.bzemail, _charsets)
+        msg = mail.mimeencode(self.ui, text, _charsets)
+        msg['From'] = user
+        msg['To'] = bzemail
+        msg['Subject'] = mail.headencode(self.ui, "Bug modification", _charsets)
+        sendmail = mail.connect(self.ui)
+        sendmail(user, bzemail, msg.as_string())
+
+    def add_comment(self, bugid, text, committer):
+        self.send_bug_modify_email(bugid, [], text, committer)
+
 class bugzilla(object):
     # supported versions of bugzilla. different versions have
     # different schemas.
     _versions = {
-        '2.16': bugzilla_2_16,
-        '2.18': bugzilla_2_18,
-        '3.0':  bugzilla_3_0
+        '2.16': bzmysql,
+        '2.18': bzmysql_2_18,
+        '3.0':  bzmysql_3_0,
+        'xmlrpc': bzxmlrpc,
+        'xmlrpc+email': bzxmlrpcemail
         }
 
     _default_bug_re = (r'bugs?\s*,?\s*(?:#|nos?\.?|num(?:ber)?s?)?\s*'
@@ -353,10 +673,12 @@
     _split_re = None
 
     def find_bug_ids(self, ctx):
-        '''find valid bug ids that are referred to in changeset
-        comments and that do not already have references to this
-        changeset.'''
+        '''return set of integer bug IDs from commit comment.
 
+        Extract bug IDs from changeset comments. Filter out any that are
+        not known to Bugzilla, and any that already have a reference to
+        the given changeset in their comments.
+        '''
         if bugzilla._bug_re is None:
             bugzilla._bug_re = re.compile(
                 self.ui.config('bugzilla', 'regexp', bugzilla._default_bug_re),
@@ -376,7 +698,7 @@
         if ids:
             ids = self.filter_real_bug_ids(ids)
         if ids:
-            ids = self.filter_unknown_bug_ids(ctx.node(), ids)
+            ids = self.filter_cset_known_bug_ids(ctx.node(), ids)
         return ids
 
     def update(self, bugid, ctx):
@@ -418,13 +740,6 @@
     '''add comment to bugzilla for each changeset that refers to a
     bugzilla bug id. only add a comment once per bug, so same change
     seen multiple times does not fill bug with duplicate data.'''
-    try:
-        import MySQLdb as mysql
-        global MySQLdb
-        MySQLdb = mysql
-    except ImportError, err:
-        raise util.Abort(_('python mysql support not available: %s') % err)
-
     if node is None:
         raise util.Abort(_('hook type %s does not pass a changeset id') %
                          hooktype)
@@ -436,6 +751,6 @@
             for id in ids:
                 bz.update(id, ctx)
             bz.notify(ids, util.email(ctx.user()))
-    except MySQLdb.MySQLError, err:
-        raise util.Abort(_('database error: %s') % err.args[1])
+    except Exception, e:
+        raise util.Abort(_('Bugzilla error: %s') % e)
 
--- a/hgext/churn.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/hgext/churn.py	Sat Jun 18 17:03:01 2011 -0500
@@ -9,7 +9,7 @@
 '''command to display statistics about repository history'''
 
 from mercurial.i18n import _
-from mercurial import patch, cmdutil, util, templater, commands
+from mercurial import patch, cmdutil, scmutil, util, templater, commands
 import os
 import time, datetime
 
@@ -24,7 +24,7 @@
 
 def changedlines(ui, repo, ctx1, ctx2, fns):
     added, removed = 0, 0
-    fmatch = cmdutil.matchfiles(repo, fns)
+    fmatch = scmutil.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("+++ "):
@@ -54,15 +54,14 @@
     if opts.get('date'):
         df = util.matchdate(opts['date'])
 
-    m = cmdutil.match(repo, pats, opts)
+    m = scmutil.match(repo[None], pats, opts)
     def prep(ctx, fns):
         rev = ctx.rev()
         if df and not df(ctx.date()[0]): # doesn't match date format
             return
 
-        key = getkey(ctx)
+        key = getkey(ctx).strip()
         key = amap.get(key, key) # alias remap
-        key = key.strip() # ignore leading and trailing spaces
         if opts.get('changesets'):
             rate[key] = (rate.get(key, (0,))[0] + 1, 0)
         else:
--- a/hgext/color.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/hgext/color.py	Sat Jun 18 17:03:01 2011 -0500
@@ -18,14 +18,16 @@
 
 '''colorize output from some commands
 
-This extension modifies the status and resolve commands to add color to their
-output to reflect file status, the qseries command to add color to reflect
-patch status (applied, unapplied, missing), and to diff-related
-commands to highlight additions, removals, diff headers, and trailing
-whitespace.
+This extension modifies the status and resolve commands to add color
+to their output to reflect file status, the qseries command to add
+color to reflect patch status (applied, unapplied, missing), and to
+diff-related commands to highlight additions, removals, diff headers,
+and trailing whitespace.
 
 Other effects in addition to color, like bold and underlined text, are
-also available. Effects are rendered with the ECMA-48 SGR control
+also available. By default, the terminfo database is used to find the
+terminal codes used to change color and effect.  If terminfo is not
+available, then effects are rendered with the ECMA-48 SGR control
 function (aka ANSI escape codes).
 
 Default effects may be overridden from your configuration file::
@@ -66,13 +68,35 @@
   branches.current = green
   branches.inactive = none
 
-The color extension will try to detect whether to use ANSI codes or
-Win32 console APIs, unless it is made explicit::
+The available effects in terminfo mode are 'blink', 'bold', 'dim',
+'inverse', 'invisible', 'italic', 'standout', and 'underline'; in
+ECMA-48 mode, the options are 'bold', 'inverse', 'italic', and
+'underline'.  How each is rendered depends on the terminal emulator.
+Some may not be available for a given terminal type, and will be
+silently ignored.
+
+Because there are only eight standard colors, this module allows you
+to define color names for other color slots which might be available
+for your terminal type, assuming terminfo mode.  For instance::
+
+  color.brightblue = 12
+  color.pink = 207
+  color.orange = 202
+
+to set 'brightblue' to color slot 12 (useful for 16 color terminals
+that have brighter colors defined in the upper eight) and, 'pink' and
+'orange' to colors in 256-color xterm's default color cube.  These
+defined colors may then be used as any of the pre-defined eight,
+including appending '_background' to set the background to that color.
+
+The color extension will try to detect whether to use terminfo, ANSI
+codes or Win32 console APIs, unless it is made explicit; e.g.::
 
   [color]
   mode = ansi
 
-Any value other than 'ansi', 'win32', or 'auto' will disable color.
+Any value other than 'ansi', 'win32', 'terminfo', or 'auto' will
+disable color.
 
 '''
 
@@ -90,6 +114,110 @@
             'blue_background': 44, 'purple_background': 45,
             'cyan_background': 46, 'white_background': 47}
 
+def _terminfosetup(ui, mode):
+    '''Initialize terminfo data and the terminal if we're in terminfo mode.'''
+
+    global _terminfo_params
+    # If we failed to load curses, we go ahead and return.
+    if not _terminfo_params:
+        return
+    # Otherwise, see what the config file says.
+    if mode not in ('auto', 'terminfo'):
+        return
+
+    _terminfo_params.update((key[6:], (False, int(val)))
+        for key, val in ui.configitems('color')
+        if key.startswith('color.'))
+
+    try:
+        curses.setupterm()
+    except curses.error, e:
+        _terminfo_params = {}
+        return
+
+    for key, (b, e) in _terminfo_params.items():
+        if not b:
+            continue
+        if not curses.tigetstr(e):
+            # Most terminals don't support dim, invis, etc, so don't be
+            # noisy and use ui.debug().
+            ui.debug("no terminfo entry for %s\n" % e)
+            del _terminfo_params[key]
+    if not curses.tigetstr('setaf') or not curses.tigetstr('setab'):
+        ui.warn(_("no terminfo entry for setab/setaf: reverting to "
+          "ECMA-48 color\n"))
+        _terminfo_params = {}
+
+def _modesetup(ui, opts):
+    global _terminfo_params
+
+    coloropt = opts['color']
+    auto = coloropt == 'auto'
+    always = not auto and util.parsebool(coloropt)
+    if not always and not auto:
+        return None
+
+    formatted = always or (os.environ.get('TERM') != 'dumb' and ui.formatted())
+
+    mode = ui.config('color', 'mode', 'auto')
+    realmode = mode
+    if mode == 'auto':
+        if os.name == 'nt' and 'TERM' not in os.environ:
+            # looks line a cmd.exe console, use win32 API or nothing
+            realmode = 'win32'
+        elif not formatted:
+            realmode = 'ansi'
+        else:
+            realmode = 'terminfo'
+
+    if realmode == 'win32':
+        if not w32effects and mode == 'win32':
+            # only warn if color.mode is explicitly set to win32
+            ui.warn(_('warning: failed to set color mode to %s\n') % mode)
+            return None
+        _effects.update(w32effects)
+    elif realmode == 'ansi':
+        _terminfo_params = {}
+    elif realmode == 'terminfo':
+        _terminfosetup(ui, mode)
+        if not _terminfo_params:
+            if mode == 'terminfo':
+                ## FIXME Shouldn't we return None in this case too?
+                # only warn if color.mode is explicitly set to win32
+                ui.warn(_('warning: failed to set color mode to %s\n') % mode)
+            realmode = 'ansi'
+    else:
+        return None
+
+    if always or (auto and formatted):
+        return realmode
+    return None
+
+try:
+    import curses
+    # Mapping from effect name to terminfo attribute name or color number.
+    # This will also force-load the curses module.
+    _terminfo_params = {'none': (True, 'sgr0'),
+                        'standout': (True, 'smso'),
+                        'underline': (True, 'smul'),
+                        'reverse': (True, 'rev'),
+                        'inverse': (True, 'rev'),
+                        'blink': (True, 'blink'),
+                        'dim': (True, 'dim'),
+                        'bold': (True, 'bold'),
+                        'invisible': (True, 'invis'),
+                        'italic': (True, 'sitm'),
+                        'black': (False, curses.COLOR_BLACK),
+                        'red': (False, curses.COLOR_RED),
+                        'green': (False, curses.COLOR_GREEN),
+                        'yellow': (False, curses.COLOR_YELLOW),
+                        'blue': (False, curses.COLOR_BLUE),
+                        'magenta': (False, curses.COLOR_MAGENTA),
+                        'cyan': (False, curses.COLOR_CYAN),
+                        'white': (False, curses.COLOR_WHITE)}
+except ImportError:
+    _terminfo_params = False
+
 _styles = {'grep.match': 'red bold',
            'bookmarks.current': 'green',
            'branches.active': 'none',
@@ -107,6 +235,7 @@
            'diff.trailingwhitespace': 'bold red_background',
            'diffstat.deleted': 'red',
            'diffstat.inserted': 'green',
+           'ui.prompt': 'yellow',
            'log.changeset': 'yellow',
            'resolve.resolved': 'green bold',
            'resolve.unresolved': 'red bold',
@@ -120,13 +249,33 @@
            'status.unknown': 'magenta bold underline'}
 
 
+def _effect_str(effect):
+    '''Helper function for render_effects().'''
+
+    bg = False
+    if effect.endswith('_background'):
+        bg = True
+        effect = effect[:-11]
+    attr, val = _terminfo_params[effect]
+    if attr:
+        return curses.tigetstr(val)
+    elif bg:
+        return curses.tparm(curses.tigetstr('setab'), val)
+    else:
+        return curses.tparm(curses.tigetstr('setaf'), val)
+
 def render_effects(text, effects):
     'Wrap text in commands to turn on each effect.'
     if not text:
         return text
-    start = [str(_effects[e]) for e in ['none'] + effects.split()]
-    start = '\033[' + ';'.join(start) + 'm'
-    stop = '\033[' + str(_effects['none']) + 'm'
+    if not _terminfo_params:
+        start = [str(_effects[e]) for e in ['none'] + effects.split()]
+        start = '\033[' + ';'.join(start) + 'm'
+        stop = '\033[' + str(_effects['none']) + 'm'
+    else:
+        start = ''.join(_effect_str(effect)
+                        for effect in ['none'] + effects.split())
+        stop = _effect_str('none')
     return ''.join([start, text, stop])
 
 def extstyles():
@@ -135,13 +284,15 @@
 
 def configstyles(ui):
     for status, cfgeffects in ui.configitems('color'):
-        if '.' not in status:
+        if '.' not in status or status.startswith('color.'):
             continue
         cfgeffects = ui.configlist('color', status)
         if cfgeffects:
             good = []
             for e in cfgeffects:
-                if e in _effects:
+                if not _terminfo_params and e in _effects:
+                    good.append(e)
+                elif e in _terminfo_params or e[:-11] in _terminfo_params:
                     good.append(e)
                 else:
                     ui.warn(_("ignoring unknown color/effect %r "
@@ -183,7 +334,7 @@
             s = _styles.get(l, '')
             if s:
                 effects.append(s)
-        effects = ''.join(effects)
+        effects = ' '.join(effects)
         if effects:
             return '\n'.join([render_effects(s, effects)
                               for s in msg.split('\n')])
@@ -191,33 +342,16 @@
 
 
 def uisetup(ui):
+    global _terminfo_params
     if ui.plain():
         return
-    mode = ui.config('color', 'mode', 'auto')
-    if mode == 'auto':
-        if os.name == 'nt' and 'TERM' not in os.environ:
-            # looks line a cmd.exe console, use win32 API or nothing
-            mode = w32effects and 'win32' or 'none'
-        else:
-            mode = 'ansi'
-    if mode == 'win32':
-        if w32effects is None:
-            # only warn if color.mode is explicitly set to win32
-            ui.warn(_('warning: failed to set color mode to %s\n') % mode)
-            return
-        _effects.update(w32effects)
-    elif mode != 'ansi':
-        return
     def colorcmd(orig, ui_, opts, cmd, cmdfunc):
-        coloropt = opts['color']
-        auto = coloropt == 'auto'
-        always = util.parsebool(coloropt)
-        if (always or
-            (always is None and
-             (auto and (os.environ.get('TERM') != 'dumb' and ui_.formatted())))):
+        mode = _modesetup(ui_, opts)
+        if mode:
             colorui._colormode = mode
-            colorui.__bases__ = (ui_.__class__,)
-            ui_.__class__ = colorui
+            if not issubclass(ui_.__class__, colorui):
+                colorui.__bases__ = (ui_.__class__,)
+                ui_.__class__ = colorui
             extstyles()
             configstyles(ui_)
         return orig(ui_, opts, cmd, cmdfunc)
@@ -348,13 +482,15 @@
 
         # Look for ANSI-like codes embedded in text
         m = re.match(ansire, text)
-        while m:
-            for sattr in m.group(1).split(';'):
-                if sattr:
-                    attr = mapcolor(int(sattr), attr)
-            _kernel32.SetConsoleTextAttribute(stdout, attr)
-            orig(m.group(2), **opts)
-            m = re.match(ansire, m.group(3))
 
-        # Explicity reset original attributes
-        _kernel32.SetConsoleTextAttribute(stdout, origattr)
+        try:
+            while m:
+                for sattr in m.group(1).split(';'):
+                    if sattr:
+                        attr = mapcolor(int(sattr), attr)
+                _kernel32.SetConsoleTextAttribute(stdout, attr)
+                orig(m.group(2), **opts)
+                m = re.match(ansire, m.group(3))
+        finally:
+            # Explicity reset original attributes
+            _kernel32.SetConsoleTextAttribute(stdout, origattr)
--- a/hgext/convert/__init__.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/hgext/convert/__init__.py	Sat Jun 18 17:03:01 2011 -0500
@@ -10,7 +10,7 @@
 import convcmd
 import cvsps
 import subversion
-from mercurial import commands
+from mercurial import commands, templatekw
 from mercurial.i18n import _
 
 # Commands definition was moved elsewhere to ease demandload job.
@@ -334,3 +334,34 @@
          ],
          _('hg debugcvsps [OPTION]... [PATH]...')),
 }
+
+def kwconverted(ctx, name):
+    rev = ctx.extra().get('convert_revision', '')
+    if rev.startswith('svn:'):
+        if name == 'svnrev':
+            return str(subversion.revsplit(rev)[2])
+        elif name == 'svnpath':
+            return subversion.revsplit(rev)[1]
+        elif name == 'svnuuid':
+            return subversion.revsplit(rev)[0]
+    return rev
+
+def kwsvnrev(repo, ctx, **args):
+    """:svnrev: String. Converted subversion revision number."""
+    return kwconverted(ctx, 'svnrev')
+
+def kwsvnpath(repo, ctx, **args):
+    """:svnpath: String. Converted subversion revision project path."""
+    return kwconverted(ctx, 'svnpath')
+
+def kwsvnuuid(repo, ctx, **args):
+    """:svnuuid: String. Converted subversion revision repository identifier."""
+    return kwconverted(ctx, 'svnuuid')
+
+def extsetup(ui):
+    templatekw.keywords['svnrev'] = kwsvnrev
+    templatekw.keywords['svnpath'] = kwsvnpath
+    templatekw.keywords['svnuuid'] = kwsvnuuid
+
+# tell hggettext to extract docstrings from these functions:
+i18nfunctions = [kwsvnrev, kwsvnpath, kwsvnuuid]
--- a/hgext/convert/common.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/hgext/convert/common.py	Sat Jun 18 17:03:01 2011 -0500
@@ -29,7 +29,7 @@
 
 def checktool(exe, name=None, abort=True):
     name = name or exe
-    if not util.find_exe(exe):
+    if not util.findexe(exe):
         exc = abort and util.Abort or MissingTool
         raise exc(_('cannot find required "%s" tool') % name)
 
@@ -151,6 +151,13 @@
         """
         return None
 
+    def getbookmarks(self):
+        """Return the bookmarks as a dictionary of name: revision
+
+        Bookmark names are to be UTF-8 strings.
+        """
+        return {}
+
 class converter_sink(object):
     """Conversion sink (target) interface"""
 
@@ -228,6 +235,13 @@
     def after(self):
         pass
 
+    def putbookmarks(self, bookmarks):
+        """Put bookmarks into sink.
+
+        bookmarks: {bookmarkname: sink_rev_id, ...}
+        where bookmarkname is an UTF-8 string.
+        """
+        pass
 
 class commandline(object):
     def __init__(self, ui, command):
@@ -240,7 +254,7 @@
     def postrun(self):
         pass
 
-    def _cmdline(self, cmd, *args, **kwargs):
+    def _cmdline(self, cmd, closestdin, *args, **kwargs):
         cmdline = [self.command, cmd] + list(args)
         for k, v in kwargs.iteritems():
             if len(k) == 1:
@@ -257,16 +271,23 @@
         cmdline = [util.shellquote(arg) for arg in cmdline]
         if not self.ui.debugflag:
             cmdline += ['2>', util.nulldev]
-        cmdline += ['<', util.nulldev]
+        if closestdin:
+            cmdline += ['<', util.nulldev]
         cmdline = ' '.join(cmdline)
         return cmdline
 
     def _run(self, cmd, *args, **kwargs):
-        cmdline = self._cmdline(cmd, *args, **kwargs)
+        return self._dorun(util.popen, cmd, True, *args, **kwargs)
+
+    def _run2(self, cmd, *args, **kwargs):
+        return self._dorun(util.popen2, cmd, False, *args, **kwargs)
+
+    def _dorun(self, openfunc, cmd, closestdin, *args, **kwargs):
+        cmdline = self._cmdline(cmd, closestdin, *args, **kwargs)
         self.ui.debug('running: %s\n' % (cmdline,))
         self.prerun()
         try:
-            return util.popen(cmdline)
+            return openfunc(cmdline)
         finally:
             self.postrun()
 
@@ -287,7 +308,7 @@
             if output:
                 self.ui.warn(_('%s error:\n') % self.command)
                 self.ui.warn(output)
-            msg = util.explain_exit(status)[0]
+            msg = util.explainexit(status)[0]
             raise util.Abort('%s %s' % (self.command, msg))
 
     def run0(self, cmd, *args, **kwargs):
@@ -322,8 +343,9 @@
         self._argmax = self._argmax / 2 - 1
         return self._argmax
 
-    def limit_arglist(self, arglist, cmd, *args, **kwargs):
-        limit = self.getargmax() - len(self._cmdline(cmd, *args, **kwargs))
+    def limit_arglist(self, arglist, cmd, closestdin, *args, **kwargs):
+        cmdlen = len(self._cmdline(cmd, closestdin, *args, **kwargs))
+        limit = self.getargmax() - cmdlen
         bytes = 0
         fl = []
         for fn in arglist:
@@ -339,7 +361,7 @@
             yield fl
 
     def xargs(self, arglist, cmd, *args, **kwargs):
-        for l in self.limit_arglist(arglist, cmd, *args, **kwargs):
+        for l in self.limit_arglist(arglist, cmd, True, *args, **kwargs):
             self.run0(cmd, *(list(args) + l), **kwargs)
 
 class mapfile(dict):
--- a/hgext/convert/convcmd.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/hgext/convert/convcmd.py	Sat Jun 18 17:03:01 2011 -0500
@@ -378,6 +378,16 @@
                     if tagsparents:
                         self.map[tagsparents[0][0]] = nrev
 
+            bookmarks = self.source.getbookmarks()
+            cbookmarks = {}
+            for k in bookmarks:
+                v = bookmarks[k]
+                if self.map.get(v, SKIPREV) != SKIPREV:
+                    cbookmarks[k] = self.map[v]
+
+            if c and cbookmarks:
+                self.dest.putbookmarks(cbookmarks)
+
             self.writeauthormap()
         finally:
             self.cleanup()
--- a/hgext/convert/cvs.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/hgext/convert/cvs.py	Sat Jun 18 17:03:01 2011 -0500
@@ -227,7 +227,7 @@
 
         data = ""
         mode = None
-        while 1:
+        while True:
             line = self.readp.readline()
             if line.startswith("Created ") or line.startswith("Updated "):
                 self.readp.readline() # path
--- a/hgext/convert/darcs.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/hgext/convert/darcs.py	Sat Jun 18 17:03:01 2011 -0500
@@ -7,7 +7,7 @@
 
 from common import NoRepo, checktool, commandline, commit, converter_source
 from mercurial.i18n import _
-from mercurial import encoding, util
+from mercurial import util
 import os, shutil, tempfile, re
 
 # The naming drift of ElementTree is fun!
@@ -191,7 +191,7 @@
         if rev != self.lastrev:
             raise util.Abort(_('internal calling inconsistency'))
         path = os.path.join(self.tmppath, name)
-        data = open(path, 'rb').read()
+        data = util.readfile(path)
         mode = os.lstat(path).st_mode
         mode = (mode & 0111) and 'x' or ''
         return data, mode
--- a/hgext/convert/git.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/hgext/convert/git.py	Sat Jun 18 17:03:01 2011 -0500
@@ -17,19 +17,27 @@
     # cannot remove environment variable. Just assume none have
     # both issues.
     if hasattr(os, 'unsetenv'):
-        def gitopen(self, s):
+        def gitopen(self, s, noerr=False):
             prevgitdir = os.environ.get('GIT_DIR')
             os.environ['GIT_DIR'] = self.path
             try:
-                return util.popen(s, 'rb')
+                if noerr:
+                    (stdin, stdout, stderr) = util.popen3(s)
+                    return stdout
+                else:
+                    return util.popen(s, 'rb')
             finally:
                 if prevgitdir is None:
                     del os.environ['GIT_DIR']
                 else:
                     os.environ['GIT_DIR'] = prevgitdir
     else:
-        def gitopen(self, s):
-            return util.popen('GIT_DIR=%s %s' % (self.path, s), 'rb')
+        def gitopen(self, s, noerr=False):
+            if noerr:
+                (sin, so, se) = util.popen3('GIT_DIR=%s %s' % (self.path, s))
+                return so
+            else:
+                util.popen('GIT_DIR=%s %s' % (self.path, s), 'rb')
 
     def gitread(self, s):
         fh = self.gitopen(s)
@@ -168,3 +176,30 @@
             raise util.Abort(_('cannot read changes in %s') % version)
 
         return changes
+
+    def getbookmarks(self):
+        bookmarks = {}
+
+        # Interesting references in git are prefixed
+        prefix = 'refs/heads/'
+        prefixlen = len(prefix)
+
+        # factor two commands
+        gitcmd = { 'remote/': 'git ls-remote --heads origin',
+                          '': 'git show-ref'}
+
+        # Origin heads
+        for reftype in gitcmd:
+            try:
+                fh = self.gitopen(gitcmd[reftype], noerr=True)
+                for line in fh:
+                    line = line.strip()
+                    rev, name = line.split(None, 1)
+                    if not name.startswith(prefix):
+                        continue
+                    name = '%s%s' % (reftype, name[prefixlen:])
+                    bookmarks[name] = rev
+            except:
+                pass
+
+        return bookmarks
--- a/hgext/convert/gnuarch.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/hgext/convert/gnuarch.py	Sat Jun 18 17:03:01 2011 -0500
@@ -36,10 +36,10 @@
 
         # Could use checktool, but we want to check for baz or tla.
         self.execmd = None
-        if util.find_exe('baz'):
+        if util.findexe('baz'):
             self.execmd = 'baz'
         else:
-            if util.find_exe('tla'):
+            if util.findexe('tla'):
                 self.execmd = 'tla'
             else:
                 raise util.Abort(_('cannot find a GNU Arch tool'))
--- a/hgext/convert/hg.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/hgext/convert/hg.py	Sat Jun 18 17:03:01 2011 -0500
@@ -21,7 +21,7 @@
 import os, time, cStringIO
 from mercurial.i18n import _
 from mercurial.node import bin, hex, nullid
-from mercurial import hg, util, context, error
+from mercurial import hg, util, context, bookmarks, error
 
 from common import NoRepo, commit, converter_source, converter_sink
 
@@ -112,7 +112,7 @@
             self.after()
             for pbranch, heads in missings.iteritems():
                 pbranchpath = os.path.join(self.path, pbranch)
-                prepo = hg.repository(self.ui, pbranchpath)
+                prepo = hg.peer(self.ui, {}, pbranchpath)
                 self.ui.note(_('pulling from %s into %s\n') % (pbranch, branch))
                 self.repo.pull(prepo, [prepo.lookup(h) for h in heads])
             self.before()
@@ -214,6 +214,16 @@
     def setfilemapmode(self, active):
         self.filemapmode = active
 
+    def putbookmarks(self, updatedbookmark):
+        if not len(updatedbookmark):
+            return
+
+        self.ui.status(_("updating bookmarks\n"))
+        for bookmark in updatedbookmark:
+            self.repo._bookmarks[bookmark] = bin(updatedbookmark[bookmark])
+            bookmarks.write(self.repo)
+
+
 class mercurial_source(converter_source):
     def __init__(self, ui, path, rev=None):
         converter_source.__init__(self, ui, path, rev)
@@ -277,10 +287,9 @@
         parents = self.parents(ctx)
         if not parents:
             files = sorted(ctx.manifest())
-            if self.ignoreerrors:
-                # calling getcopies() is a simple way to detect missing
-                # revlogs and populate self.ignored
-                self.getcopies(ctx, parents, files)
+            # getcopies() is not needed for roots, but it is a simple way to
+            # detect missing revlogs and abort on errors or populate self.ignored
+            self.getcopies(ctx, parents, files)
             return [(f, rev) for f in files if f not in self.ignored], {}
         if self._changescache and self._changescache[0] == rev:
             m, a, r = self._changescache[1]
@@ -374,3 +383,6 @@
             return hex(self.repo.lookup(rev))
         except error.RepoError:
             return None
+
+    def getbookmarks(self):
+        return bookmarks.listbookmarks(self.repo)
--- a/hgext/convert/monotone.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/hgext/convert/monotone.py	Sat Jun 18 17:03:01 2011 -0500
@@ -19,13 +19,17 @@
 
         self.ui = ui
         self.path = path
+        self.automatestdio = False
+        self.rev = rev
 
         norepo = NoRepo(_("%s does not look like a monotone repository")
                         % path)
         if not os.path.exists(os.path.join(path, '_MTN')):
             # Could be a monotone repository (SQLite db file)
             try:
-                header = file(path, 'rb').read(16)
+                f = file(path, 'rb')
+                header = f.read(16)
+                f.close()
             except:
                 header = ''
             if header != 'SQLite format 3\x00':
@@ -64,18 +68,103 @@
 
         checktool('mtn', abort=False)
 
-        # test if there are any revisions
-        self.rev = None
-        try:
-            self.getheads()
-        except:
-            raise norepo
-        self.rev = rev
+    def mtnrun(self, *args, **kwargs):
+        if self.automatestdio:
+            return self.mtnrunstdio(*args, **kwargs)
+        else:
+            return self.mtnrunsingle(*args, **kwargs)
 
-    def mtnrun(self, *args, **kwargs):
+    def mtnrunsingle(self, *args, **kwargs):
         kwargs['d'] = self.path
         return self.run0('automate', *args, **kwargs)
 
+    def mtnrunstdio(self, *args, **kwargs):
+        # Prepare the command in automate stdio format
+        command = []
+        for k, v in kwargs.iteritems():
+            command.append("%s:%s" % (len(k), k))
+            if v:
+                command.append("%s:%s" % (len(v), v))
+        if command:
+            command.insert(0, 'o')
+            command.append('e')
+
+        command.append('l')
+        for arg in args:
+            command += "%s:%s" % (len(arg), arg)
+        command.append('e')
+        command = ''.join(command)
+
+        self.ui.debug("mtn: sending '%s'\n" % command)
+        self.mtnwritefp.write(command)
+        self.mtnwritefp.flush()
+
+        return self.mtnstdioreadcommandoutput(command)
+
+    def mtnstdioreadpacket(self):
+        read = None
+        commandnbr = ''
+        while read != ':':
+            read = self.mtnreadfp.read(1)
+            if not read:
+                raise util.Abort(_('bad mtn packet - no end of commandnbr'))
+            commandnbr += read
+        commandnbr = commandnbr[:-1]
+
+        stream = self.mtnreadfp.read(1)
+        if stream not in 'mewptl':
+            raise util.Abort(_('bad mtn packet - bad stream type %s' % stream))
+
+        read = self.mtnreadfp.read(1)
+        if read != ':':
+            raise util.Abort(_('bad mtn packet - no divider before size'))
+
+        read = None
+        lengthstr = ''
+        while read != ':':
+            read = self.mtnreadfp.read(1)
+            if not read:
+                raise util.Abort(_('bad mtn packet - no end of packet size'))
+            lengthstr += read
+        try:
+            length = long(lengthstr[:-1])
+        except TypeError:
+            raise util.Abort(_('bad mtn packet - bad packet size %s')
+                % lengthstr)
+
+        read = self.mtnreadfp.read(length)
+        if len(read) != length:
+            raise util.Abort(_("bad mtn packet - unable to read full packet "
+                "read %s of %s") % (len(read), length))
+
+        return (commandnbr, stream, length, read)
+
+    def mtnstdioreadcommandoutput(self, command):
+        retval = []
+        while True:
+            commandnbr, stream, length, output = self.mtnstdioreadpacket()
+            self.ui.debug('mtn: read packet %s:%s:%s\n' %
+                (commandnbr, stream, length))
+
+            if stream == 'l':
+                # End of command
+                if output != '0':
+                    raise util.Abort(_("mtn command '%s' returned %s") %
+                        (command, output))
+                break
+            elif stream in 'ew':
+                # Error, warning output
+                self.ui.warn(_('%s error:\n') % self.command)
+                self.ui.warn(output)
+            elif stream == 'p':
+                # Progress messages
+                self.ui.debug('mtn: ' + output)
+            elif stream == 'm':
+                # Main stream - command output
+                retval.append(output)
+
+        return ''.join(retval)
+
     def mtnloadmanifest(self, rev):
         if self.manifest_rev == rev:
             return
@@ -204,14 +293,18 @@
         return data, attr
 
     def getcommit(self, rev):
-        certs   = self.mtngetcerts(rev)
+        extra = {}
+        certs = self.mtngetcerts(rev)
+        if certs.get('suspend') == certs["branch"]:
+            extra['close'] = '1'
         return commit(
             author=certs["author"],
             date=util.datestr(util.strdate(certs["date"], "%Y-%m-%dT%H:%M:%S")),
             desc=certs["changelog"],
             rev=rev,
             parents=self.mtnrun("parents", rev).splitlines(),
-            branch=certs["branch"])
+            branch=certs["branch"],
+            extra=extra)
 
     def gettags(self):
         tags = {}
@@ -225,3 +318,43 @@
         # This function is only needed to support --filemap
         # ... and we don't support that
         raise NotImplementedError()
+
+    def before(self):
+        # Check if we have a new enough version to use automate stdio
+        version = 0.0
+        try:
+            versionstr = self.mtnrunsingle("interface_version")
+            version = float(versionstr)
+        except Exception:
+            raise util.Abort(_("unable to determine mtn automate interface "
+                "version"))
+
+        if version >= 12.0:
+            self.automatestdio = True
+            self.ui.debug("mtn automate version %s - using automate stdio\n" %
+                version)
+
+            # launch the long-running automate stdio process
+            self.mtnwritefp, self.mtnreadfp = self._run2('automate', 'stdio',
+                '-d', self.path)
+            # read the headers
+            read = self.mtnreadfp.readline()
+            if read != 'format-version: 2\n':
+                raise util.Abort(_('mtn automate stdio header unexpected: %s')
+                    % read)
+            while read != '\n':
+                read = self.mtnreadfp.readline()
+                if not read:
+                    raise util.Abort(_("failed to reach end of mtn automate "
+                        "stdio headers"))
+        else:
+            self.ui.debug("mtn automate version %s - not using automate stdio "
+                "(automate >= 12.0 - mtn >= 0.46 is needed)\n" % version)
+
+    def after(self):
+        if self.automatestdio:
+            self.mtnwritefp.close()
+            self.mtnwritefp = None
+            self.mtnreadfp.close()
+            self.mtnreadfp = None
+
--- a/hgext/convert/subversion.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/hgext/convert/subversion.py	Sat Jun 18 17:03:01 2011 -0500
@@ -10,7 +10,7 @@
 import urllib
 import urllib2
 
-from mercurial import strutil, util, encoding
+from mercurial import strutil, scmutil, util, encoding
 from mercurial.i18n import _
 
 # Subversion stuff. Works best with very recent Python SVN bindings
@@ -41,6 +41,15 @@
 class SvnPathNotFound(Exception):
     pass
 
+def revsplit(rev):
+    """Parse a revision string and return (uuid, path, revnum)."""
+    url, revnum = rev.rsplit('@', 1)
+    parts = url.split('/', 1)
+    mod = ''
+    if len(parts) > 1:
+        mod = '/' + parts[1]
+    return parts[0][4:], mod, int(revnum)
+
 def geturl(path):
     try:
         return svn.client.url_from_path(svn.core.svn_path_canonicalize(path))
@@ -103,8 +112,8 @@
     """Fetch SVN log in a subprocess and channel them back to parent to
     avoid memory collection issues.
     """
-    util.set_binary(sys.stdin)
-    util.set_binary(sys.stdout)
+    util.setbinary(sys.stdin)
+    util.setbinary(sys.stdout)
     args = decodeargs(sys.stdin.read())
     get_log_child(sys.stdout, *args)
 
@@ -259,6 +268,7 @@
             except ValueError:
                 raise util.Abort(_('svn: revision %s is not an integer') % rev)
 
+        self.trunkname = self.ui.config('convert', 'svn.trunk', 'trunk').strip('/')
         self.startrev = self.ui.config('convert', 'svn.startrev', default=0)
         try:
             self.startrev = int(self.startrev)
@@ -268,7 +278,10 @@
             raise util.Abort(_('svn: start revision %s is not an integer')
                              % self.startrev)
 
-        self.head = self.latest(self.module, latest)
+        try:
+            self.head = self.latest(self.module, latest)
+        except SvnPathNotFound:
+            self.head = None
         if not self.head:
             raise util.Abort(_('no revision found in module %s')
                              % self.module)
@@ -285,7 +298,7 @@
     def setrevmap(self, revmap):
         lastrevs = {}
         for revid in revmap.iterkeys():
-            uuid, module, revnum = self.revsplit(revid)
+            uuid, module, revnum = revsplit(revid)
             lastrevnum = lastrevs.setdefault(module, revnum)
             if revnum > lastrevnum:
                 lastrevs[module] = revnum
@@ -380,7 +393,7 @@
             files, self.removed, copies = self.expandpaths(rev, paths, parents)
         else:
             # Perform a full checkout on roots
-            uuid, module, revnum = self.revsplit(rev)
+            uuid, module, revnum = revsplit(rev)
             entries = svn.client.ls(self.baseurl + urllib.quote(module),
                                     optrev(revnum), True, self.ctx)
             files = [n for n, e in entries.iteritems()
@@ -402,7 +415,7 @@
 
     def getcommit(self, rev):
         if rev not in self.commits:
-            uuid, module, revnum = self.revsplit(rev)
+            uuid, module, revnum = revsplit(rev)
             self.module = module
             self.reparent(module)
             # We assume that:
@@ -529,16 +542,6 @@
     def revnum(self, rev):
         return int(rev.split('@')[-1])
 
-    def revsplit(self, rev):
-        url, revnum = rev.rsplit('@', 1)
-        revnum = int(revnum)
-        parts = url.split('/', 1)
-        uuid = parts.pop(0)[4:]
-        mod = ''
-        if parts:
-            mod = '/' + parts[0]
-        return uuid, mod, revnum
-
     def latest(self, path, stop=0):
         """Find the latest revid affecting path, up to stop. It may return
         a revision in a different module, since a branch may be moved without
@@ -605,7 +608,7 @@
         changed, removed = set(), set()
         copies = {}
 
-        new_module, revnum = self.revsplit(rev)[1:]
+        new_module, revnum = revsplit(rev)[1:]
         if new_module != self.module:
             self.module = new_module
             self.reparent(self.module)
@@ -622,7 +625,7 @@
                     continue
                 # Copy sources not in parent revisions cannot be
                 # represented, ignore their origin for now
-                pmodule, prevnum = self.revsplit(parents[0])[1:]
+                pmodule, prevnum = revsplit(parents[0])[1:]
                 if ent.copyfrom_rev < prevnum:
                     continue
                 copyfrom_path = self.getrelpath(ent.copyfrom_path, pmodule)
@@ -633,7 +636,7 @@
                 copies[self.recode(entrypath)] = self.recode(copyfrom_path)
             elif kind == 0: # gone, but had better be a deleted *file*
                 self.ui.debug("gone from %s\n" % ent.copyfrom_rev)
-                pmodule, prevnum = self.revsplit(parents[0])[1:]
+                pmodule, prevnum = revsplit(parents[0])[1:]
                 parentpath = pmodule + "/" + entrypath
                 fromkind = self._checkpath(entrypath, prevnum, pmodule)
 
@@ -659,7 +662,7 @@
                 if ent.action == 'R' and parents:
                     # If a directory is replacing a file, mark the previous
                     # file as deleted
-                    pmodule, prevnum = self.revsplit(parents[0])[1:]
+                    pmodule, prevnum = revsplit(parents[0])[1:]
                     pkind = self._checkpath(entrypath, prevnum, pmodule)
                     if pkind == svn.core.svn_node_file:
                         removed.add(self.recode(entrypath))
@@ -681,7 +684,7 @@
                     continue
                 # Copy sources not in parent revisions cannot be
                 # represented, ignore their origin for now
-                pmodule, prevnum = self.revsplit(parents[0])[1:]
+                pmodule, prevnum = revsplit(parents[0])[1:]
                 if ent.copyfrom_rev < prevnum:
                     continue
                 copyfrompath = self.getrelpath(ent.copyfrom_path, pmodule)
@@ -736,7 +739,7 @@
                     # ent.copyfrom_rev may not be the actual last revision
                     previd = self.latest(newpath, ent.copyfrom_rev)
                     if previd is not None:
-                        prevmodule, prevnum = self.revsplit(previd)[1:]
+                        prevmodule, prevnum = revsplit(previd)[1:]
                         if prevnum >= self.startrev:
                             parents = [previd]
                             self.ui.note(
@@ -761,9 +764,8 @@
             author = author and self.recode(author) or ''
             try:
                 branch = self.module.split("/")[-1]
-                trunkname = self.ui.config('convert', 'svn.trunk', 'trunk')
-                if branch == trunkname.strip('/'):
-                    branch = ''
+                if branch == self.trunkname:
+                    branch = None
             except IndexError:
                 branch = None
 
@@ -834,7 +836,7 @@
             raise IOError()
         mode = ''
         try:
-            new_module, revnum = self.revsplit(rev)[1:]
+            new_module, revnum = revsplit(rev)[1:]
             if self.module != new_module:
                 self.module = new_module
                 self.reparent(self.module)
@@ -944,6 +946,7 @@
 
 class svn_sink(converter_sink, commandline):
     commit_re = re.compile(r'Committed revision (\d+).', re.M)
+    uuid_re = re.compile(r'Repository UUID:\s*(\S+)', re.M)
 
     def prerun(self):
         if self.wc:
@@ -964,8 +967,6 @@
 
     def __init__(self, ui, path):
 
-        if svn is None:
-            raise MissingTool(_('Could not load Subversion python bindings'))
         converter_sink.__init__(self, ui, path)
         commandline.__init__(self, ui, 'svn')
         self.delete = []
@@ -1000,20 +1001,20 @@
             self.run0('checkout', path, wcpath)
 
             self.wc = wcpath
-        self.opener = util.opener(self.wc)
-        self.wopener = util.opener(self.wc)
+        self.opener = scmutil.opener(self.wc)
+        self.wopener = scmutil.opener(self.wc)
         self.childmap = mapfile(ui, self.join('hg-childmap'))
-        self.is_exec = util.checkexec(self.wc) and util.is_exec or None
+        self.is_exec = util.checkexec(self.wc) and util.isexec or None
 
         if created:
             hook = os.path.join(created, 'hooks', 'pre-revprop-change')
             fp = open(hook, 'w')
             fp.write(pre_revprop_change)
             fp.close()
-            util.set_flags(hook, False, True)
+            util.setflags(hook, False, True)
 
-        xport = transport.SvnRaTransport(url=geturl(path))
-        self.uuid = svn.ra.get_uuid(xport.ra)
+        output = self.run0('info')
+        self.uuid = self.uuid_re.search(output).group(1).strip()
 
     def wjoin(self, *names):
         return os.path.join(self.wc, *names)
@@ -1027,7 +1028,7 @@
                     os.unlink(filename)
             except OSError:
                 pass
-            self.wopener(filename, 'w').write(data)
+            self.wopener.write(filename, data)
 
             if self.is_exec:
                 was_exec = self.is_exec(self.wjoin(filename))
@@ -1037,7 +1038,7 @@
                 # systematically is just as expensive and much simpler.
                 was_exec = 'x' not in flags
 
-            util.set_flags(self.wjoin(filename), False, 'x' in flags)
+            util.setflags(self.wjoin(filename), False, 'x' in flags)
             if was_exec:
                 if 'x' not in flags:
                     self.delexec.append(filename)
--- a/hgext/eol.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/hgext/eol.py	Sat Jun 18 17:03:01 2011 -0500
@@ -73,11 +73,13 @@
 only need to these filters until you have prepared a ``.hgeol`` file.
 
 The ``win32text.forbid*`` hooks provided by the win32text extension
-have been unified into a single hook named ``eol.hook``. The hook will
-lookup the expected line endings from the ``.hgeol`` file, which means
-you must migrate to a ``.hgeol`` file first before using the hook.
-Remember to enable the eol extension in the repository where you
-install the hook.
+have been unified into a single hook named ``eol.checkheadshook``. The
+hook will lookup the expected line endings from the ``.hgeol`` file,
+which means you must migrate to a ``.hgeol`` file first before using
+the hook. ``eol.checkheadshook`` only checks heads, intermediate
+invalid revisions will be pushed. To forbid them completely, use the
+``eol.checkallhook`` hook. These hooks are best used as
+``pretxnchangegroup`` hooks.
 
 See :hg:`help patterns` for more information about the glob patterns
 used.
@@ -127,36 +129,119 @@
     'cleverdecode:': tocrlf
 }
 
+class eolfile(object):
+    def __init__(self, ui, root, data):
+        self._decode = {'LF': 'to-lf', 'CRLF': 'to-crlf', 'BIN': 'is-binary'}
+        self._encode = {'LF': 'to-lf', 'CRLF': 'to-crlf', 'BIN': 'is-binary'}
 
-def hook(ui, repo, node, hooktype, **kwargs):
-    """verify that files have expected EOLs"""
+        self.cfg = config.config()
+        # Our files should not be touched. The pattern must be
+        # inserted first override a '** = native' pattern.
+        self.cfg.set('patterns', '.hg*', 'BIN')
+        # We can then parse the user's patterns.
+        self.cfg.parse('.hgeol', data)
+
+        isrepolf = self.cfg.get('repository', 'native') != 'CRLF'
+        self._encode['NATIVE'] = isrepolf and 'to-lf' or 'to-crlf'
+        iswdlf = ui.config('eol', 'native', os.linesep) in ('LF', '\n')
+        self._decode['NATIVE'] = iswdlf and 'to-lf' or 'to-crlf'
+
+        include = []
+        exclude = []
+        for pattern, style in self.cfg.items('patterns'):
+            key = style.upper()
+            if key == 'BIN':
+                exclude.append(pattern)
+            else:
+                include.append(pattern)
+        # This will match the files for which we need to care
+        # about inconsistent newlines.
+        self.match = match.match(root, '', [], include, exclude)
+
+    def setfilters(self, ui):
+        for pattern, style in self.cfg.items('patterns'):
+            key = style.upper()
+            try:
+                ui.setconfig('decode', pattern, self._decode[key])
+                ui.setconfig('encode', pattern, self._encode[key])
+            except KeyError:
+                ui.warn(_("ignoring unknown EOL style '%s' from %s\n")
+                        % (style, self.cfg.source('patterns', pattern)))
+
+    def checkrev(self, repo, ctx, files):
+        failed = []
+        for f in (files or ctx.files()):
+            if f not in ctx:
+                continue
+            for pattern, style in self.cfg.items('patterns'):
+                if not match.match(repo.root, '', [pattern])(f):
+                    continue
+                target = self._encode[style.upper()]
+                data = ctx[f].data()
+                if (target == "to-lf" and "\r\n" in data
+                    or target == "to-crlf" and singlelf.search(data)):
+                    failed.append((str(ctx), target, f))
+                break
+        return failed
+
+def parseeol(ui, repo, nodes):
+    try:
+        for node in nodes:
+            try:
+                if node is None:
+                    # Cannot use workingctx.data() since it would load
+                    # and cache the filters before we configure them.
+                    data = repo.wfile('.hgeol').read()
+                else:
+                    data = repo[node]['.hgeol'].data()
+                return eolfile(ui, repo.root, data)
+            except (IOError, LookupError):
+                pass
+    except error.ParseError, inst:
+        ui.warn(_("warning: ignoring .hgeol file due to parse error "
+                  "at %s: %s\n") % (inst.args[1], inst.args[0]))
+    return None
+
+def _checkhook(ui, repo, node, headsonly):
+    # Get revisions to check and touched files at the same time
     files = set()
+    revs = set()
     for rev in xrange(repo[node].rev(), len(repo)):
-        files.update(repo[rev].files())
-    tip = repo['tip']
-    for f in files:
-        if f not in tip:
-            continue
-        for pattern, target in ui.configitems('encode'):
-            if match.match(repo.root, '', [pattern])(f):
-                data = tip[f].data()
-                if target == "to-lf" and "\r\n" in data:
-                    raise util.Abort(_("%s should not have CRLF line endings")
-                                     % f)
-                elif target == "to-crlf" and singlelf.search(data):
-                    raise util.Abort(_("%s should not have LF line endings")
-                                     % f)
-                # Ignore other rules for this file
-                break
+        revs.add(rev)
+        if headsonly:
+            ctx = repo[rev]
+            files.update(ctx.files())
+            for pctx in ctx.parents():
+                revs.discard(pctx.rev())
+    failed = []
+    for rev in revs:
+        ctx = repo[rev]
+        eol = parseeol(ui, repo, [ctx.node()])
+        if eol:
+            failed.extend(eol.checkrev(repo, ctx, files))
 
+    if failed:
+        eols = {'to-lf': 'CRLF', 'to-crlf': 'LF'}
+        msgs = []
+        for node, target, f in failed:
+            msgs.append(_("  %s in %s should not have %s line endings") %
+                        (f, node, eols[target]))
+        raise util.Abort(_("end-of-line check failed:\n") + "\n".join(msgs))
+
+def checkallhook(ui, repo, node, hooktype, **kwargs):
+    """verify that files have expected EOLs"""
+    _checkhook(ui, repo, node, False)
+
+def checkheadshook(ui, repo, node, hooktype, **kwargs):
+    """verify that files have expected EOLs"""
+    _checkhook(ui, repo, node, True)
+
+# "checkheadshook" used to be called "hook"
+hook = checkheadshook
 
 def preupdate(ui, repo, hooktype, parent1, parent2):
     #print "preupdate for %s: %s -> %s" % (repo.root, parent1, parent2)
-    try:
-        repo.readhgeol(parent1)
-    except error.ParseError, inst:
-        ui.warn(_("warning: ignoring .hgeol file due to parse error "
-                  "at %s: %s\n") % (inst.args[1], inst.args[0]))
+    repo.loadeol([parent1])
     return False
 
 def uisetup(ui):
@@ -184,66 +269,15 @@
 
     class eolrepo(repo.__class__):
 
-        _decode = {'LF': 'to-lf', 'CRLF': 'to-crlf', 'BIN': 'is-binary'}
-        _encode = {'LF': 'to-lf', 'CRLF': 'to-crlf', 'BIN': 'is-binary'}
-
-        def readhgeol(self, node=None, data=None):
-            if data is None:
-                try:
-                    if node is None:
-                        data = self.wfile('.hgeol').read()
-                    else:
-                        data = self[node]['.hgeol'].data()
-                except (IOError, LookupError):
-                    return None
-
-            if self.ui.config('eol', 'native', os.linesep) in ('LF', '\n'):
-                self._decode['NATIVE'] = 'to-lf'
-            else:
-                self._decode['NATIVE'] = 'to-crlf'
-
-            eol = config.config()
-            # Our files should not be touched. The pattern must be
-            # inserted first override a '** = native' pattern.
-            eol.set('patterns', '.hg*', 'BIN')
-            # We can then parse the user's patterns.
-            eol.parse('.hgeol', data)
-
-            if eol.get('repository', 'native') == 'CRLF':
-                self._encode['NATIVE'] = 'to-crlf'
-            else:
-                self._encode['NATIVE'] = 'to-lf'
-
-            for pattern, style in eol.items('patterns'):
-                key = style.upper()
-                try:
-                    self.ui.setconfig('decode', pattern, self._decode[key])
-                    self.ui.setconfig('encode', pattern, self._encode[key])
-                except KeyError:
-                    self.ui.warn(_("ignoring unknown EOL style '%s' from %s\n")
-                                 % (style, eol.source('patterns', pattern)))
-
-            include = []
-            exclude = []
-            for pattern, style in eol.items('patterns'):
-                key = style.upper()
-                if key == 'BIN':
-                    exclude.append(pattern)
-                else:
-                    include.append(pattern)
-
-            # This will match the files for which we need to care
-            # about inconsistent newlines.
-            return match.match(self.root, '', [], include, exclude)
+        def loadeol(self, nodes):
+            eol = parseeol(self.ui, self, nodes)
+            if eol is None:
+                return None
+            eol.setfilters(self.ui)
+            return eol.match
 
         def _hgcleardirstate(self):
-            try:
-                self._eolfile = self.readhgeol() or self.readhgeol('tip')
-            except error.ParseError, inst:
-                ui.warn(_("warning: ignoring .hgeol file due to parse error "
-                          "at %s: %s\n") % (inst.args[1], inst.args[0]))
-                self._eolfile = None
-
+            self._eolfile = self.loadeol([None, 'tip'])
             if not self._eolfile:
                 self._eolfile = util.never
                 return
--- a/hgext/extdiff.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/hgext/extdiff.py	Sat Jun 18 17:03:01 2011 -0500
@@ -13,7 +13,7 @@
 non-option arguments: paths to directories containing snapshots of
 files to compare.
 
-The extdiff extension also allows to configure new diff commands, so
+The extdiff extension also allows you to configure new diff commands, so
 you do not need to type :hg:`extdiff -p kdiff3` always. ::
 
   [extdiff]
@@ -40,6 +40,7 @@
   $parent1, $plabel1 - filename, descriptive label of first parent
   $child,   $clabel  - filename, descriptive label of child revision
   $parent2, $plabel2 - filename, descriptive label of second parent
+  $root              - repository root
   $parent is an alias for $parent1.
 
 The extdiff extension will look in your [diff-tools] and [merge-tools]
@@ -61,7 +62,7 @@
 
 from mercurial.i18n import _
 from mercurial.node import short, nullid
-from mercurial import cmdutil, util, commands, encoding
+from mercurial import scmutil, scmutil, util, commands, encoding
 import os, shlex, shutil, tempfile, re
 
 def snapshot(ui, repo, files, node, tmproot):
@@ -81,7 +82,7 @@
     else:
         ui.note(_('making snapshot of %d files from working directory\n') %
             (len(files)))
-    wopener = util.opener(base)
+    wopener = scmutil.opener(base)
     fns_and_mtime = []
     ctx = repo[node]
     for fn in files:
@@ -96,9 +97,9 @@
         if 'l' in fctx.flags():
             wopener.symlink(data, wfn)
         else:
-            wopener(wfn, 'w').write(data)
+            wopener.write(wfn, data)
             if 'x' in fctx.flags():
-                util.set_flags(dest, False, True)
+                util.setflags(dest, False, True)
         if node is None:
             fns_and_mtime.append((dest, repo.wjoin(fn),
                                   os.lstat(dest).st_mtime))
@@ -122,12 +123,12 @@
         msg = _('cannot specify --rev and --change at the same time')
         raise util.Abort(msg)
     elif change:
-        node2 = repo.lookup(change)
+        node2 = scmutil.revsingle(repo, change, None).node()
         node1a, node1b = repo.changelog.parents(node2)
     else:
-        node1a, node2 = cmdutil.revpair(repo, revs)
+        node1a, node2 = scmutil.revpair(repo, revs)
         if not revs:
-            node1b = repo.dirstate.parents()[1]
+            node1b = repo.dirstate.p2()
         else:
             node1b = nullid
 
@@ -136,7 +137,7 @@
         if node1b == nullid:
             do3way = False
 
-    matcher = cmdutil.match(repo, pats, opts)
+    matcher = scmutil.match(repo[node2], pats, opts)
     mod_a, add_a, rem_a = map(set, repo.status(node1a, node2, matcher)[:3])
     if do3way:
         mod_b, add_b, rem_b = map(set, repo.status(node1b, node2, matcher)[:3])
@@ -188,14 +189,14 @@
         # Handle bogus modifies correctly by checking if the files exist
         if len(common) == 1:
             common_file = util.localpath(common.pop())
-            dir1a = os.path.join(dir1a, common_file)
+            dir1a = os.path.join(tmproot, dir1a, common_file)
             label1a = common_file + rev1a
-            if not os.path.isfile(os.path.join(tmproot, dir1a)):
+            if not os.path.isfile(dir1a):
                 dir1a = os.devnull
             if do3way:
-                dir1b = os.path.join(dir1b, common_file)
+                dir1b = os.path.join(tmproot, dir1b, common_file)
                 label1b = common_file + rev1b
-                if not os.path.isfile(os.path.join(tmproot, dir1b)):
+                if not os.path.isfile(dir1b):
                     dir1b = os.devnull
             dir2 = os.path.join(dir2root, dir2, common_file)
             label2 = common_file + rev2
@@ -205,7 +206,8 @@
         # returned for parent2
         replace = dict(parent=dir1a, parent1=dir1a, parent2=dir1b,
                        plabel1=label1a, plabel2=label1b,
-                       clabel=label2, child=dir2)
+                       clabel=label2, child=dir2,
+                       root=repo.root)
         def quote(match):
             key = match.group()[1:]
             if not do3way and key == 'parent2':
@@ -213,7 +215,7 @@
             return util.shellquote(replace[key])
 
         # Match parent2 first, so 'parent1?' will match both parent1 and parent
-        regex = '\$(parent2|parent1?|child|plabel1|plabel2|clabel)'
+        regex = '\$(parent2|parent1?|child|plabel1|plabel2|clabel|root)'
         if not do3way and not re.search(regex, args):
             args += ' $parent1 $child'
         args = re.sub(regex, quote, args)
--- a/hgext/fetch.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/hgext/fetch.py	Sat Jun 18 17:03:01 2011 -0500
@@ -9,7 +9,7 @@
 
 from mercurial.i18n import _
 from mercurial.node import nullid, short
-from mercurial import commands, cmdutil, hg, util, url, error
+from mercurial import commands, cmdutil, hg, util, error
 from mercurial.lock import release
 
 def fetch(ui, repo, source='default', **opts):
@@ -63,10 +63,9 @@
             raise util.Abort(_('multiple heads in this branch '
                                '(use "hg heads ." and "hg merge" to merge)'))
 
-        other = hg.repository(hg.remoteui(repo, opts),
-                              ui.expandpath(source))
+        other = hg.peer(repo, opts, ui.expandpath(source))
         ui.status(_('pulling from %s\n') %
-                  url.hidepassword(ui.expandpath(source)))
+                  util.hidepassword(ui.expandpath(source)))
         revs = None
         if opts['rev']:
             try:
@@ -123,9 +122,9 @@
 
         if not err:
             # we don't translate commit messages
-            message = (cmdutil.logmessage(opts) or
+            message = (cmdutil.logmessage(ui, opts) or
                        ('Automated merge with %s' %
-                        url.removeauth(other.url())))
+                        util.removeauth(other.url())))
             editor = cmdutil.commiteditor
             if opts.get('force_editor') or opts.get('edit'):
                 editor = cmdutil.commitforceeditor
--- a/hgext/gpg.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/hgext/gpg.py	Sat Jun 18 17:03:01 2011 -0500
@@ -6,10 +6,13 @@
 '''commands to sign and verify changesets'''
 
 import os, tempfile, binascii
-from mercurial import util, commands, match
+from mercurial import util, commands, match, cmdutil
 from mercurial import node as hgnode
 from mercurial.i18n import _
 
+cmdtable = {}
+command = cmdutil.command(cmdtable)
+
 class gpg(object):
     def __init__(self, path, key=None):
         self.path = path
@@ -135,6 +138,7 @@
         validkeys.append((key[1], key[2], key[3]))
     return validkeys
 
+@command("sigs", [], _('hg sigs'))
 def sigs(ui, repo):
     """list signed changesets"""
     mygpg = newgpg(ui)
@@ -159,6 +163,7 @@
             r = "%5d:%s" % (rev, hgnode.hex(repo.changelog.node(rev)))
             ui.write("%-30s %s\n" % (keystr(ui, k), r))
 
+@command("sigcheck", [], _('hg sigcheck REVISION'))
 def check(ui, repo, rev):
     """verify all the signatures there may be for a particular revision"""
     mygpg = newgpg(ui)
@@ -191,6 +196,16 @@
     else:
         return user
 
+@command("sign",
+         [('l', 'local', None, _('make the signature local')),
+          ('f', 'force', None, _('sign even if the sigfile is modified')),
+          ('', 'no-commit', None, _('do not commit the sigfile after signing')),
+          ('k', 'key', '',
+           _('the key id to sign with'), _('ID')),
+          ('m', 'message', '',
+           _('commit message'), _('TEXT')),
+         ] + commands.commitopts2,
+         _('hg sign [OPTION]... [REVISION]...'))
 def sign(ui, repo, *revs, **opts):
     """add a signature for the current or given revision
 
@@ -234,7 +249,7 @@
 
     # write it
     if opts['local']:
-        repo.opener("localsigs", "ab").write(sigmessage)
+        repo.opener.append("localsigs", sigmessage)
         return
 
     msigs = match.exact(repo.root, '', ['.hgsigs'])
@@ -272,19 +287,3 @@
     else:
         raise util.Abort(_("unknown signature version"))
 
-cmdtable = {
-    "sign":
-        (sign,
-         [('l', 'local', None, _('make the signature local')),
-          ('f', 'force', None, _('sign even if the sigfile is modified')),
-          ('', 'no-commit', None, _('do not commit the sigfile after signing')),
-          ('k', 'key', '',
-           _('the key id to sign with'), _('ID')),
-          ('m', 'message', '',
-           _('commit message'), _('TEXT')),
-         ] + commands.commitopts2,
-         _('hg sign [OPTION]... [REVISION]...')),
-    "sigcheck": (check, [], _('hg sigcheck REVISION')),
-    "sigs": (sigs, [], _('hg sigs')),
-}
-
--- a/hgext/graphlog.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/hgext/graphlog.py	Sat Jun 18 17:03:01 2011 -0500
@@ -12,17 +12,19 @@
 revision graph is also shown.
 '''
 
-import os
-from mercurial.cmdutil import revrange, show_changeset
+from mercurial.cmdutil import show_changeset
 from mercurial.commands import templateopts
 from mercurial.i18n import _
 from mercurial.node import nullrev
-from mercurial import cmdutil, commands, extensions
+from mercurial import cmdutil, commands, extensions, scmutil
 from mercurial import hg, util, graphmod
 
+cmdtable = {}
+command = cmdutil.command(cmdtable)
+
 ASCIIDATA = 'ASC'
 
-def asciiedges(seen, rev, parents):
+def asciiedges(type, char, lines, seen, rev, parents):
     """adds edge info to changelog DAG walk suitable for ascii()"""
     if rev not in seen:
         seen.append(rev)
@@ -37,16 +39,33 @@
             newparents.append(parent)
 
     ncols = len(seen)
-    seen[nodeidx:nodeidx + 1] = newparents
-    edges = [(nodeidx, seen.index(p)) for p in knownparents]
+    nextseen = seen[:]
+    nextseen[nodeidx:nodeidx + 1] = newparents
+    edges = [(nodeidx, nextseen.index(p)) for p in knownparents]
+
+    while len(newparents) > 2:
+        # ascii() only knows how to add or remove a single column between two
+        # calls. Nodes with more than two parents break this constraint so we
+        # introduce intermediate expansion lines to grow the active node list
+        # slowly.
+        edges.append((nodeidx, nodeidx))
+        edges.append((nodeidx, nodeidx + 1))
+        nmorecols = 1
+        yield (type, char, lines, (nodeidx, edges, ncols, nmorecols))
+        char = '\\'
+        lines = []
+        nodeidx += 1
+        ncols += 1
+        edges = []
+        del newparents[0]
 
     if len(newparents) > 0:
         edges.append((nodeidx, nodeidx))
     if len(newparents) > 1:
         edges.append((nodeidx, nodeidx + 1))
-
-    nmorecols = len(seen) - ncols
-    return nodeidx, edges, ncols, nmorecols
+    nmorecols = len(nextseen) - ncols
+    seen[:] = nextseen
+    yield (type, char, lines, (nodeidx, edges, ncols, nmorecols))
 
 def fix_long_right_edges(edges):
     for (i, (start, end)) in enumerate(edges):
@@ -208,20 +227,71 @@
 
 def get_revs(repo, rev_opt):
     if rev_opt:
-        revs = revrange(repo, rev_opt)
+        revs = scmutil.revrange(repo, rev_opt)
         if len(revs) == 0:
             return (nullrev, nullrev)
         return (max(revs), min(revs))
     else:
         return (len(repo) - 1, 0)
 
-def check_unsupported_flags(opts):
-    for op in ["follow", "follow_first", "date", "copies", "keyword", "remove",
-               "only_merges", "user", "branch", "only_branch", "prune",
-               "newest_first", "no_merges", "include", "exclude"]:
+def check_unsupported_flags(pats, opts):
+    for op in ["follow_first", "copies", "newest_first"]:
         if op in opts and opts[op]:
-            raise util.Abort(_("--graph option is incompatible with --%s")
+            raise util.Abort(_("-G/--graph option is incompatible with --%s")
                              % op.replace("_", "-"))
+    if pats and opts.get('follow'):
+        raise util.Abort(_("-G/--graph option is incompatible with --follow "
+                           "with file argument"))
+
+def revset(pats, opts):
+    """Return revset str built of revisions, log options and file patterns.
+    """
+    opt2revset = {
+        'follow': (0, 'follow()'),
+        'no_merges': (0, 'not merge()'),
+        'only_merges': (0, 'merge()'),
+        'removed': (0, 'removes("*")'),
+        'date': (1, 'date($)'),
+        'branch': (2, 'branch($)'),
+        'exclude': (2, 'not file($)'),
+        'include': (2, 'file($)'),
+        'keyword': (2, 'keyword($)'),
+        'only_branch': (2, 'branch($)'),
+        'prune': (2, 'not ($ or ancestors($))'),
+        'user': (2, 'user($)'),
+        }
+    optrevset = []
+    revset = []
+    for op, val in opts.iteritems():
+        if not val:
+            continue
+        if op == 'rev':
+            # Already a revset
+            revset.extend(val)
+        if op not in opt2revset:
+            continue
+        arity, revop = opt2revset[op]
+        revop = revop.replace('$', '%(val)r')
+        if arity == 0:
+            optrevset.append(revop)
+        elif arity == 1:
+            optrevset.append(revop % {'val': val})
+        else:
+            for f in val:
+                optrevset.append(revop % {'val': f})
+
+    for path in pats:
+        optrevset.append('file(%r)' % path)
+
+    if revset or optrevset:
+        if revset:
+            revset = ['(' + ' or '.join(revset) + ')']
+        if optrevset:
+            revset.append('(' + ' and '.join(optrevset) + ')')
+        revset = ' and '.join(revset)
+    else:
+        revset = 'all()'
+    return revset
 
 def generate(ui, dag, displayer, showparents, edgefn):
     seen, state = [], asciistate()
@@ -230,10 +300,19 @@
         displayer.show(ctx)
         lines = displayer.hunk.pop(rev).split('\n')[:-1]
         displayer.flush(rev)
-        ascii(ui, state, type, char, lines, edgefn(seen, rev, parents))
+        edges = edgefn(type, char, lines, seen, rev, parents)
+        for type, char, lines, coldata in edges:
+            ascii(ui, state, type, char, lines, coldata)
     displayer.close()
 
-def graphlog(ui, repo, path=None, **opts):
+@command('glog',
+    [('l', 'limit', '',
+     _('limit number of changes displayed'), _('NUM')),
+    ('p', 'patch', False, _('show patch')),
+    ('r', 'rev', [], _('show the specified revision or range'), _('REV')),
+    ] + templateopts,
+    _('hg glog [OPTION]... [FILE]'))
+def graphlog(ui, repo, *pats, **opts):
     """show revision history alongside an ASCII revision graph
 
     Print a revision history alongside a revision graph drawn with
@@ -243,20 +322,13 @@
     directory.
     """
 
-    check_unsupported_flags(opts)
-    limit = cmdutil.loglimit(opts)
-    start, stop = get_revs(repo, opts["rev"])
-    if start == nullrev:
-        return
+    check_unsupported_flags(pats, opts)
 
-    if path:
-        path = util.canonpath(repo.root, os.getcwd(), path)
-    if path: # could be reset in canonpath
-        revdag = graphmod.filerevs(repo, path, start, stop, limit)
-    else:
-        if limit is not None:
-            stop = max(stop, start - limit + 1)
-        revdag = graphmod.revisions(repo, start, stop)
+    revs = sorted(scmutil.revrange(repo, [revset(pats, opts)]), reverse=1)
+    limit = cmdutil.loglimit(opts)
+    if limit is not None:
+        revs = revs[:limit]
+    revdag = graphmod.dagwalker(repo, revs)
 
     displayer = show_changeset(ui, repo, opts, buffered=True)
     showparents = [ctx.node() for ctx in repo[None].parents()]
@@ -279,7 +351,7 @@
     directory.
     """
 
-    check_unsupported_flags(opts)
+    check_unsupported_flags([], opts)
     o = hg._outgoing(ui, repo, dest, opts)
     if o is None:
         return
@@ -301,7 +373,7 @@
     def subreporecurse():
         return 1
 
-    check_unsupported_flags(opts)
+    check_unsupported_flags([], opts)
     def display(other, chlist, displayer):
         revdag = graphrevs(other, chlist, opts)
         showparents = [ctx.node() for ctx in repo[None].parents()]
@@ -311,31 +383,15 @@
 
 def uisetup(ui):
     '''Initialize the extension.'''
-    _wrapcmd(ui, 'log', commands.table, graphlog)
-    _wrapcmd(ui, 'incoming', commands.table, gincoming)
-    _wrapcmd(ui, 'outgoing', commands.table, goutgoing)
+    _wrapcmd('log', commands.table, graphlog)
+    _wrapcmd('incoming', commands.table, gincoming)
+    _wrapcmd('outgoing', commands.table, goutgoing)
 
-def _wrapcmd(ui, cmd, table, wrapfn):
+def _wrapcmd(cmd, table, wrapfn):
     '''wrap the command'''
     def graph(orig, *args, **kwargs):
         if kwargs['graph']:
-            try:
-                return wrapfn(*args, **kwargs)
-            except TypeError, e:
-                if len(args) > wrapfn.func_code.co_argcount:
-                    raise util.Abort(_('--graph option allows at most one file'))
+            return wrapfn(*args, **kwargs)
         return orig(*args, **kwargs)
     entry = extensions.wrapcommand(table, cmd, graph)
     entry[1].append(('G', 'graph', None, _("show the revision DAG")))
-
-cmdtable = {
-    "glog":
-        (graphlog,
-         [('l', 'limit', '',
-           _('limit number of changes displayed'), _('NUM')),
-          ('p', 'patch', False, _('show patch')),
-          ('r', 'rev', [],
-           _('show the specified revision or range'), _('REV')),
-         ] + templateopts,
-         _('hg glog [OPTION]... [FILE]')),
-}
--- a/hgext/hgcia.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/hgext/hgcia.py	Sat Jun 18 17:03:01 2011 -0500
@@ -18,7 +18,7 @@
   # Append a diffstat to the log message (optional)
   #diffstat = False
   # Template to use for log messages (optional)
-  #template = {desc}\\n{baseurl}/rev/{node}-- {diffstat}
+  #template = {desc}\\n{baseurl}{webroot}/rev/{node}-- {diffstat}
   # Style to use (optional)
   #style = foo
   # The URL of the CIA notification service (optional)
@@ -28,6 +28,8 @@
   #url = http://cia.vc/
   # print message instead of sending it (optional)
   #test = False
+  # number of slashes to strip for url paths
+  #strip = 0
 
   [hooks]
   # one of these:
@@ -66,6 +68,8 @@
         self.cia = cia
         self.ctx = ctx
         self.url = self.cia.url
+        if self.url:
+            self.url += self.cia.root
 
     def fileelem(self, path, uri, action):
         if uri:
@@ -75,7 +79,7 @@
 
     def fileelems(self):
         n = self.ctx.node()
-        f = self.cia.repo.status(self.ctx.parents()[0].node(), n)
+        f = self.cia.repo.status(self.ctx.p1().node(), n)
         url = self.url or ''
         elems = []
         for path in f[0]:
@@ -120,7 +124,9 @@
         diffstat = self.cia.diffstat and self.diffstat() or ''
         self.cia.ui.pushbuffer()
         self.cia.templater.show(self.ctx, changes=self.ctx.changeset(),
-                                url=self.cia.url, diffstat=diffstat)
+                                baseurl=self.cia.ui.config('web', 'baseurl'),
+                                url=self.url, diffstat=diffstat,
+                                webroot=self.cia.root)
         return self.cia.ui.popbuffer()
 
     def xml(self):
@@ -184,6 +190,8 @@
         self.emailfrom = self.ui.config('email', 'from')
         self.dryrun = self.ui.configbool('cia', 'test')
         self.url = self.ui.config('web', 'baseurl')
+        self.stripcount = int(self.ui.config('cia', 'strip', 0))
+        self.root = self.strip(self.repo.root)
 
         style = self.ui.config('cia', 'style')
         template = self.ui.config('cia', 'template')
@@ -195,6 +203,19 @@
         t.use_template(template)
         self.templater = t
 
+    def strip(self, path):
+        '''strip leading slashes from local path, turn into web-safe path.'''
+
+        path = util.pconvert(path)
+        count = self.stripcount
+        while count > 0:
+            c = path.find('/')
+            if c == -1:
+                break
+            path = path[c + 1:]
+            count -= 1
+        return path
+
     def sendrpc(self, msg):
         srv = xmlrpclib.Server(self.ciaurl)
         res = srv.hub.deliver(msg)
--- a/hgext/hgk.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/hgext/hgk.py	Sat Jun 18 17:03:01 2011 -0500
@@ -35,7 +35,7 @@
 '''
 
 import os
-from mercurial import commands, util, patch, revlog, cmdutil
+from mercurial import commands, util, patch, revlog, scmutil
 from mercurial.node import nullid, nullrev, short
 from mercurial.i18n import _
 
@@ -45,7 +45,7 @@
         assert node2 is not None
         mmap = repo[node1].manifest()
         mmap2 = repo[node2].manifest()
-        m = cmdutil.match(repo, files)
+        m = scmutil.match(repo[node1], files)
         modified, added, removed  = repo.status(node1, node2, m)[:3]
         empty = short(nullid)
 
@@ -81,7 +81,7 @@
         if opts['patch']:
             if opts['pretty']:
                 catcommit(ui, repo, node2, "")
-            m = cmdutil.match(repo, files)
+            m = scmutil.match(repo[node1], files)
             chunks = patch.diff(repo, node1, node2, match=m,
                                 opts=patch.diffopts(ui, {'git': True}))
             for chunk in chunks:
--- a/hgext/inotify/linuxserver.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/hgext/inotify/linuxserver.py	Sat Jun 18 17:03:01 2011 -0500
@@ -44,7 +44,7 @@
 def _explain_watch_limit(ui, dirstate, rootabs):
     path = '/proc/sys/fs/inotify/max_user_watches'
     try:
-        limit = int(file(path).read())
+        limit = int(util.readfile(path))
     except IOError, err:
         if err.errno != errno.ENOENT:
             raise
--- a/hgext/keyword.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/hgext/keyword.py	Sat Jun 18 17:03:01 2011 -0500
@@ -60,11 +60,11 @@
 control run :hg:`kwdemo`. See :hg:`help templates` for a list of
 available templates and filters.
 
-Three additional date template filters are provided::
+Three additional date template filters are provided:
 
-    utcdate      "2006/09/18 15:13:13"
-    svnutcdate   "2006-09-18 15:13:13Z"
-    svnisodate   "2006-09-18 08:13:13 -700 (Mon, 18 Sep 2006)"
+:``utcdate``:    "2006/09/18 15:13:13"
+:``svnutcdate``: "2006-09-18 15:13:13Z"
+:``svnisodate``: "2006-09-18 08:13:13 -700 (Mon, 18 Sep 2006)"
 
 The default template mappings (view with :hg:`kwdemo -d`) can be
 replaced with customized keywords and templates. Again, run
@@ -83,12 +83,16 @@
 
 from mercurial import commands, context, cmdutil, dispatch, filelog, extensions
 from mercurial import localrepo, match, patch, templatefilters, templater, util
+from mercurial import scmutil
 from mercurial.hgweb import webcommands
 from mercurial.i18n import _
 import os, re, shutil, tempfile
 
 commands.optionalrepo += ' kwdemo'
 
+cmdtable = {}
+command = cmdutil.command(cmdtable)
+
 # hg commands that do not act on keywords
 nokwcommands = ('add addremove annotate bundle export grep incoming init log'
                 ' outgoing push tip verify convert email glog')
@@ -109,11 +113,26 @@
 }
 
 # date like in cvs' $Date
-utcdate = lambda x: util.datestr((x[0], 0), '%Y/%m/%d %H:%M:%S')
+def utcdate(text):
+    ''':utcdate: Date. Returns a UTC-date in this format: "2009/08/18 11:00:13".
+    '''
+    return util.datestr((text[0], 0), '%Y/%m/%d %H:%M:%S')
 # date like in svn's $Date
-svnisodate = lambda x: util.datestr(x, '%Y-%m-%d %H:%M:%S %1%2 (%a, %d %b %Y)')
+def svnisodate(text):
+    ''':svnisodate: Date. Returns a date in this format: "2009-08-18 13:00:13
+    +0200 (Tue, 18 Aug 2009)".
+    '''
+    return util.datestr(text, '%Y-%m-%d %H:%M:%S %1%2 (%a, %d %b %Y)')
 # date like in svn's $Id
-svnutcdate = lambda x: util.datestr((x[0], 0), '%Y-%m-%d %H:%M:%SZ')
+def svnutcdate(text):
+    ''':svnutcdate: Date. Returns a UTC-date in this format: "2009-08-18
+    11:00:13Z".
+    '''
+    return util.datestr((text[0], 0), '%Y-%m-%d %H:%M:%SZ')
+
+templatefilters.filters.update({'utcdate': utcdate,
+                                'svnisodate': svnisodate,
+                                'svnutcdate': svnutcdate})
 
 # make keyword tools accessible
 kwtools = {'templater': None, 'hgcmd': ''}
@@ -176,9 +195,6 @@
                                   for k, v in kwmaps)
         else:
             self.templates = _defaultkwmaps(self.ui)
-        templatefilters.filters.update({'utcdate': utcdate,
-                                        'svnisodate': svnisodate,
-                                        'svnutcdate': svnutcdate})
 
     @util.propertycache
     def escape(self):
@@ -310,7 +326,7 @@
     '''Bails out if [keyword] configuration is not active.
     Returns status of working directory.'''
     if kwt:
-        return repo.status(match=cmdutil.match(repo, pats, opts), clean=True,
+        return repo.status(match=scmutil.match(repo[None], pats, opts), clean=True,
                            unknown=opts.get('unknown') or opts.get('all'))
     if ui.configitems('keyword'):
         raise util.Abort(_('[keyword] patterns cannot match'))
@@ -332,6 +348,11 @@
     finally:
         wlock.release()
 
+@command('kwdemo',
+         [('d', 'default', None, _('show default keyword template maps')),
+          ('f', 'rcfile', '',
+           _('read maps from rcfile'), _('FILE'))],
+         _('hg kwdemo [-d] [-f RCFILE] [TEMPLATEMAP]...'))
 def demo(ui, repo, *args, **opts):
     '''print [keywordmaps] configuration and an expansion example
 
@@ -400,7 +421,7 @@
     demoitems('keywordset', ui.configitems('keywordset'))
     demoitems('keywordmaps', kwmaps.iteritems())
     keywords = '$' + '$\n$'.join(sorted(kwmaps.keys())) + '$\n'
-    repo.wopener(fn, 'w').write(keywords)
+    repo.wopener.write(fn, keywords)
     repo[None].add([fn])
     ui.note(_('\nkeywords written to %s:\n') % fn)
     ui.note(keywords)
@@ -415,6 +436,7 @@
     ui.write(repo.wread(fn))
     shutil.rmtree(tmpdir, ignore_errors=True)
 
+@command('kwexpand', commands.walkopts, _('hg kwexpand [OPTION]... [FILE]...'))
 def expand(ui, repo, *pats, **opts):
     '''expand keywords in the working directory
 
@@ -425,6 +447,12 @@
     # 3rd argument sets expansion to True
     _kwfwrite(ui, repo, True, *pats, **opts)
 
+@command('kwfiles',
+         [('A', 'all', None, _('show keyword status flags of all files')),
+          ('i', 'ignore', None, _('show files excluded from expansion')),
+          ('u', 'unknown', None, _('only show unknown (not tracked) files')),
+         ] + commands.walkopts,
+         _('hg kwfiles [OPTION]... [FILE]...'))
 def files(ui, repo, *pats, **opts):
     '''show files configured for keyword expansion
 
@@ -471,6 +499,7 @@
         for f in filenames:
             ui.write(fmt % repo.pathto(f, cwd), label='kwfiles.' + kwstate)
 
+@command('kwshrink', commands.walkopts, _('hg kwshrink [OPTION]... [FILE]...'))
 def shrink(ui, repo, *pats, **opts):
     '''revert expanded keywords in the working directory
 
@@ -566,11 +595,10 @@
                 wlock.release()
 
     # monkeypatches
-    def kwpatchfile_init(orig, self, ui, fname, opener,
-                         missing=False, eolmode=None):
+    def kwpatchfile_init(orig, self, ui, gp, backend, store, eolmode=None):
         '''Monkeypatch/wrap patch.patchfile.__init__ to avoid
         rejects or conflicts due to expanded keywords in working dir.'''
-        orig(self, ui, fname, opener, missing, eolmode)
+        orig(self, ui, gp, backend, store, eolmode)
         # shrink keywords read from working dir
         self.lines = kwt.shrinklines(self.fname, self.lines)
 
@@ -607,8 +635,8 @@
             expansion. '''
             source = repo.dirstate.copied(dest)
             if 'l' in wctx.flags(source):
-                source = util.canonpath(repo.root, cwd,
-                                        os.path.realpath(source))
+                source = scmutil.canonpath(repo.root, cwd,
+                                           os.path.realpath(source))
             return kwt.match(source)
 
         candidates = [f for f in repo.dirstate.copies() if
@@ -660,23 +688,3 @@
             pass
 
     repo.__class__ = kwrepo
-
-cmdtable = {
-    'kwdemo':
-        (demo,
-         [('d', 'default', None, _('show default keyword template maps')),
-          ('f', 'rcfile', '',
-           _('read maps from rcfile'), _('FILE'))],
-         _('hg kwdemo [-d] [-f RCFILE] [TEMPLATEMAP]...')),
-    'kwexpand': (expand, commands.walkopts,
-                 _('hg kwexpand [OPTION]... [FILE]...')),
-    'kwfiles':
-        (files,
-         [('A', 'all', None, _('show keyword status flags of all files')),
-          ('i', 'ignore', None, _('show files excluded from expansion')),
-          ('u', 'unknown', None, _('only show unknown (not tracked) files')),
-         ] + commands.walkopts,
-         _('hg kwfiles [OPTION]... [FILE]...')),
-    'kwshrink': (shrink, commands.walkopts,
-                 _('hg kwshrink [OPTION]... [FILE]...')),
-}
--- a/hgext/mq.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/hgext/mq.py	Sat Jun 18 17:03:01 2011 -0500
@@ -45,12 +45,18 @@
 from mercurial.i18n import _
 from mercurial.node import bin, hex, short, nullid, nullrev
 from mercurial.lock import release
-from mercurial import commands, cmdutil, hg, patch, util
+from mercurial import commands, cmdutil, hg, scmutil, util, revset
 from mercurial import repair, extensions, url, error
-import os, sys, re, errno, shutil
+from mercurial import patch as patchmod
+import os, re, errno, shutil
 
 commands.norepo += " qclone"
 
+seriesopts = [('s', 'summary', None, _('print first line of patch header'))]
+
+cmdtable = {}
+command = cmdutil.command(cmdtable)
+
 # Patch names looks like unix-file names.
 # They must be joinable with queue directory and result in the patch path.
 normname = util.normpath
@@ -259,16 +265,16 @@
         except IOError:
             curpath = os.path.join(path, 'patches')
         self.path = patchdir or curpath
-        self.opener = util.opener(self.path)
+        self.opener = scmutil.opener(self.path)
         self.ui = ui
-        self.applied_dirty = 0
-        self.series_dirty = 0
+        self.applieddirty = 0
+        self.seriesdirty = 0
         self.added = []
-        self.series_path = "series"
-        self.status_path = "status"
-        self.guards_path = "guards"
-        self.active_guards = None
-        self.guards_dirty = False
+        self.seriespath = "series"
+        self.statuspath = "status"
+        self.guardspath = "guards"
+        self.activeguards = None
+        self.guardsdirty = False
         # Handle mq.git as a bool with extended values
         try:
             gitmode = ui.configbool('mq', 'git', None)
@@ -281,7 +287,7 @@
 
     @util.propertycache
     def applied(self):
-        if os.path.exists(self.join(self.status_path)):
+        if os.path.exists(self.join(self.statuspath)):
             def parselines(lines):
                 for l in lines:
                     entry = l.split(':', 1)
@@ -291,37 +297,37 @@
                     elif l.strip():
                         self.ui.warn(_('malformated mq status line: %s\n') % entry)
                     # else we ignore empty lines
-            lines = self.opener(self.status_path).read().splitlines()
+            lines = self.opener.read(self.statuspath).splitlines()
             return list(parselines(lines))
         return []
 
     @util.propertycache
-    def full_series(self):
-        if os.path.exists(self.join(self.series_path)):
-            return self.opener(self.series_path).read().splitlines()
+    def fullseries(self):
+        if os.path.exists(self.join(self.seriespath)):
+            return self.opener.read(self.seriespath).splitlines()
         return []
 
     @util.propertycache
     def series(self):
-        self.parse_series()
+        self.parseseries()
         return self.series
 
     @util.propertycache
-    def series_guards(self):
-        self.parse_series()
-        return self.series_guards
+    def seriesguards(self):
+        self.parseseries()
+        return self.seriesguards
 
     def invalidate(self):
-        for a in 'applied full_series series series_guards'.split():
+        for a in 'applied fullseries series seriesguards'.split():
             if a in self.__dict__:
                 delattr(self, a)
-        self.applied_dirty = 0
-        self.series_dirty = 0
-        self.guards_dirty = False
-        self.active_guards = None
+        self.applieddirty = 0
+        self.seriesdirty = 0
+        self.guardsdirty = False
+        self.activeguards = None
 
     def diffopts(self, opts={}, patchfn=None):
-        diffopts = patch.diffopts(self.ui, opts)
+        diffopts = patchmod.diffopts(self.ui, opts)
         if self.gitmode == 'auto':
             diffopts.upgrade = True
         elif self.gitmode == 'keep':
@@ -354,21 +360,21 @@
     def join(self, *p):
         return os.path.join(self.path, *p)
 
-    def find_series(self, patch):
+    def findseries(self, patch):
         def matchpatch(l):
             l = l.split('#', 1)[0]
             return l.strip() == patch
-        for index, l in enumerate(self.full_series):
+        for index, l in enumerate(self.fullseries):
             if matchpatch(l):
                 return index
         return None
 
     guard_re = re.compile(r'\s?#([-+][^-+# \t\r\n\f][^# \t\r\n\f]*)')
 
-    def parse_series(self):
+    def parseseries(self):
         self.series = []
-        self.series_guards = []
-        for l in self.full_series:
+        self.seriesguards = []
+        for l in self.fullseries:
             h = l.find('#')
             if h == -1:
                 patch = l
@@ -382,11 +388,11 @@
             if patch:
                 if patch in self.series:
                     raise util.Abort(_('%s appears more than once in %s') %
-                                     (patch, self.join(self.series_path)))
+                                     (patch, self.join(self.seriespath)))
                 self.series.append(patch)
-                self.series_guards.append(self.guard_re.findall(comment))
-
-    def check_guard(self, guard):
+                self.seriesguards.append(self.guard_re.findall(comment))
+
+    def checkguard(self, guard):
         if not guard:
             return _('guard cannot be an empty string')
         bad_chars = '# \t\r\n\f'
@@ -398,67 +404,67 @@
             if c in guard:
                 return _('invalid character in guard %r: %r') % (guard, c)
 
-    def set_active(self, guards):
+    def setactive(self, guards):
         for guard in guards:
-            bad = self.check_guard(guard)
+            bad = self.checkguard(guard)
             if bad:
                 raise util.Abort(bad)
         guards = sorted(set(guards))
         self.ui.debug('active guards: %s\n' % ' '.join(guards))
-        self.active_guards = guards
-        self.guards_dirty = True
+        self.activeguards = guards
+        self.guardsdirty = True
 
     def active(self):
-        if self.active_guards is None:
-            self.active_guards = []
+        if self.activeguards is None:
+            self.activeguards = []
             try:
-                guards = self.opener(self.guards_path).read().split()
+                guards = self.opener.read(self.guardspath).split()
             except IOError, err:
                 if err.errno != errno.ENOENT:
                     raise
                 guards = []
             for i, guard in enumerate(guards):
-                bad = self.check_guard(guard)
+                bad = self.checkguard(guard)
                 if bad:
                     self.ui.warn('%s:%d: %s\n' %
-                                 (self.join(self.guards_path), i + 1, bad))
+                                 (self.join(self.guardspath), i + 1, bad))
                 else:
-                    self.active_guards.append(guard)
-        return self.active_guards
-
-    def set_guards(self, idx, guards):
+                    self.activeguards.append(guard)
+        return self.activeguards
+
+    def setguards(self, idx, guards):
         for g in guards:
             if len(g) < 2:
                 raise util.Abort(_('guard %r too short') % g)
             if g[0] not in '-+':
                 raise util.Abort(_('guard %r starts with invalid char') % g)
-            bad = self.check_guard(g[1:])
+            bad = self.checkguard(g[1:])
             if bad:
                 raise util.Abort(bad)
-        drop = self.guard_re.sub('', self.full_series[idx])
-        self.full_series[idx] = drop + ''.join([' #' + g for g in guards])
-        self.parse_series()
-        self.series_dirty = True
+        drop = self.guard_re.sub('', self.fullseries[idx])
+        self.fullseries[idx] = drop + ''.join([' #' + g for g in guards])
+        self.parseseries()
+        self.seriesdirty = True
 
     def pushable(self, idx):
         if isinstance(idx, str):
             idx = self.series.index(idx)
-        patchguards = self.series_guards[idx]
+        patchguards = self.seriesguards[idx]
         if not patchguards:
             return True, None
         guards = self.active()
         exactneg = [g for g in patchguards if g[0] == '-' and g[1:] in guards]
         if exactneg:
-            return False, exactneg[0]
+            return False, repr(exactneg[0])
         pos = [g for g in patchguards if g[0] == '+']
         exactpos = [g for g in pos if g[1:] in guards]
         if pos:
             if exactpos:
-                return True, exactpos[0]
-            return False, pos
+                return True, repr(exactpos[0])
+            return False, ' '.join(map(repr, pos))
         return True, ''
 
-    def explain_pushable(self, idx, all_patches=False):
+    def explainpushable(self, idx, all_patches=False):
         write = all_patches and self.ui.write or self.ui.warn
         if all_patches or self.ui.verbose:
             if isinstance(idx, str):
@@ -473,28 +479,28 @@
                         write(_('allowing %s - no matching negative guards\n') %
                               self.series[idx])
                     else:
-                        write(_('allowing %s - guarded by %r\n') %
+                        write(_('allowing %s - guarded by %s\n') %
                               (self.series[idx], why))
             if not pushable:
                 if why:
-                    write(_('skipping %s - guarded by %r\n') %
+                    write(_('skipping %s - guarded by %s\n') %
                           (self.series[idx], why))
                 else:
                     write(_('skipping %s - no matching guards\n') %
                           self.series[idx])
 
-    def save_dirty(self):
-        def write_list(items, path):
+    def savedirty(self):
+        def writelist(items, path):
             fp = self.opener(path, 'w')
             for i in items:
                 fp.write("%s\n" % i)
             fp.close()
-        if self.applied_dirty:
-            write_list(map(str, self.applied), self.status_path)
-        if self.series_dirty:
-            write_list(self.full_series, self.series_path)
-        if self.guards_dirty:
-            write_list(self.active_guards, self.guards_path)
+        if self.applieddirty:
+            writelist(map(str, self.applied), self.statuspath)
+        if self.seriesdirty:
+            writelist(self.fullseries, self.seriespath)
+        if self.guardsdirty:
+            writelist(self.activeguards, self.guardspath)
         if self.added:
             qrepo = self.qrepo()
             if qrepo:
@@ -513,7 +519,7 @@
     def printdiff(self, repo, diffopts, node1, node2=None, files=None,
                   fp=None, changes=None, opts={}):
         stat = opts.get('stat')
-        m = cmdutil.match(repo, files, opts)
+        m = scmutil.match(repo[node1], files, opts)
         cmdutil.diffordiffstat(self.ui, repo, diffopts, node1, node2,  m,
                                changes, stat, fp)
 
@@ -581,7 +587,7 @@
             n = repo.commit('[mq]: merge marker', force=True)
             self.removeundo(repo)
             self.applied.append(statusentry(n, pname))
-            self.applied_dirty = 1
+            self.applieddirty = 1
 
         head = self.qparents(repo)
 
@@ -592,7 +598,7 @@
                 return (1, None)
             pushable, reason = self.pushable(patch)
             if not pushable:
-                self.explain_pushable(patch, all_patches=True)
+                self.explainpushable(patch, all_patches=True)
                 continue
             info = mergeq.isapplied(patch)
             if not info:
@@ -602,26 +608,25 @@
             err, head = self.mergeone(repo, mergeq, head, patch, rev, diffopts)
             if head:
                 self.applied.append(statusentry(head, patch))
-                self.applied_dirty = 1
+                self.applieddirty = 1
             if err:
                 return (err, head)
-        self.save_dirty()
+        self.savedirty()
         return (0, head)
 
     def patch(self, repo, patchfile):
         '''Apply patchfile  to the working directory.
         patchfile: name of patch file'''
-        files = {}
+        files = set()
         try:
-            fuzz = patch.patch(patchfile, self.ui, strip=1, cwd=repo.root,
-                               files=files, eolmode=None)
+            fuzz = patchmod.patch(self.ui, repo, patchfile, strip=1,
+                                  files=files, eolmode=None)
+            return (True, list(files), fuzz)
         except Exception, inst:
             self.ui.note(str(inst) + '\n')
             if not self.ui.verbose:
                 self.ui.warn(_("patch failed, unable to continue (try -v)\n"))
-            return (False, files, False)
-
-        return (True, files, fuzz)
+            return (False, list(files), False)
 
     def apply(self, repo, series, list=False, update_status=True,
               strict=False, patchdir=None, merge=None, all_files=None):
@@ -634,7 +639,7 @@
                 ret = self._apply(repo, series, list, update_status,
                                   strict, patchdir, merge, all_files=all_files)
                 tr.close()
-                self.save_dirty()
+                self.savedirty()
                 return ret
             except:
                 try:
@@ -659,14 +664,14 @@
         for patchname in series:
             pushable, reason = self.pushable(patchname)
             if not pushable:
-                self.explain_pushable(patchname, all_patches=True)
+                self.explainpushable(patchname, all_patches=True)
                 continue
             self.ui.status(_("applying %s\n") % patchname)
             pf = os.path.join(patchdir, patchname)
 
             try:
                 ph = patchheader(self.join(patchname), self.plainmode)
-            except:
+            except IOError:
                 self.ui.warn(_("unable to read %s\n") % patchname)
                 err = 1
                 break
@@ -706,8 +711,7 @@
                 p1, p2 = repo.dirstate.parents()
                 repo.dirstate.setparents(p1, merge)
 
-            files = cmdutil.updatedir(self.ui, repo, files)
-            match = cmdutil.matchfiles(repo, files or [])
+            match = scmutil.matchfiles(repo, files or [])
             n = repo.commit(message, ph.user, ph.date, match=match, force=True)
 
             if n is None:
@@ -731,19 +735,36 @@
         if not keep:
             r = self.qrepo()
             if r:
-                r[None].remove(patches, True)
-            else:
-                for p in patches:
-                    os.unlink(self.join(p))
+                r[None].forget(patches)
+            for p in patches:
+                os.unlink(self.join(p))
 
         if numrevs:
+            qfinished = self.applied[:numrevs]
             del self.applied[:numrevs]
-            self.applied_dirty = 1
-
-        for i in sorted([self.find_series(p) for p in patches], reverse=True):
-            del self.full_series[i]
-        self.parse_series()
-        self.series_dirty = 1
+            self.applieddirty = 1
+
+        unknown = []
+
+        for (i, p) in sorted([(self.findseries(p), p) for p in patches],
+                             reverse=True):
+            if i is not None:
+                del self.fullseries[i]
+            else:
+                unknown.append(p)
+
+        if unknown:
+            if numrevs:
+                rev  = dict((entry.name, entry.node) for entry in qfinished)
+                for p in unknown:
+                    msg = _('revision %s refers to unknown patches: %s\n')
+                    self.ui.warn(msg % (short(rev[p]), p))
+            else:
+                msg = _('unknown patches: %s\n')
+                raise util.Abort(''.join(msg % p for p in unknown))
+
+        self.parseseries()
+        self.seriesdirty = 1
 
     def _revpatches(self, repo, revs):
         firstrev = repo[self.applied[0].node].rev()
@@ -793,7 +814,7 @@
         if opts.get('rev'):
             if not self.applied:
                 raise util.Abort(_('no patches applied'))
-            revs = cmdutil.revrange(repo, opts.get('rev'))
+            revs = scmutil.revrange(repo, opts.get('rev'))
             if len(revs) > 1 and revs[0] > revs[1]:
                 revs.reverse()
             revpatches = self._revpatches(repo, revs)
@@ -802,7 +823,7 @@
 
         self._cleanup(realpatches, numrevs, opts.get('keep'))
 
-    def check_toppatch(self, repo):
+    def checktoppatch(self, repo):
         if self.applied:
             top = self.applied[-1].node
             patch = self.applied[-1].name
@@ -812,7 +833,7 @@
             return top, patch
         return None, None
 
-    def check_substate(self, repo):
+    def checksubstate(self, repo):
         '''return list of subrepos at a different revision than substate.
         Abort if any subrepos have uncommitted changes.'''
         inclsubs = []
@@ -825,21 +846,40 @@
                 inclsubs.append(s)
         return inclsubs
 
-    def check_localchanges(self, repo, force=False, refresh=True):
+    def localchangesfound(self, refresh=True):
+        if refresh:
+            raise util.Abort(_("local changes found, refresh first"))
+        else:
+            raise util.Abort(_("local changes found"))
+
+    def checklocalchanges(self, repo, force=False, refresh=True):
         m, a, r, d = repo.status()[:4]
         if (m or a or r or d) and not force:
-            if refresh:
-                raise util.Abort(_("local changes found, refresh first"))
-            else:
-                raise util.Abort(_("local changes found"))
+            self.localchangesfound(refresh)
         return m, a, r, d
 
     _reserved = ('series', 'status', 'guards', '.', '..')
-    def check_reserved_name(self, name):
-        if (name in self._reserved or name.startswith('.hg')
-            or name.startswith('.mq') or '#' in name or ':' in name):
+    def checkreservedname(self, name):
+        if name in self._reserved:
             raise util.Abort(_('"%s" cannot be used as the name of a patch')
                              % name)
+        for prefix in ('.hg', '.mq'):
+            if name.startswith(prefix):
+                raise util.Abort(_('patch name cannot begin with "%s"')
+                                 % prefix)
+        for c in ('#', ':'):
+            if c in name:
+                raise util.Abort(_('"%s" cannot be used in the name of a patch')
+                                 % c)
+
+    def checkpatchname(self, name, force=False):
+        self.checkreservedname(name)
+        if not force and os.path.exists(self.join(name)):
+            if os.path.isdir(self.join(name)):
+                raise util.Abort(_('"%s" already exists as a directory')
+                                 % name)
+            else:
+                raise util.Abort(_('patch "%s" already exists') % name)
 
     def new(self, repo, patchfn, *pats, **opts):
         """options:
@@ -851,21 +891,15 @@
         if date:
             date = util.parsedate(date)
         diffopts = self.diffopts({'git': opts.get('git')})
-        self.check_reserved_name(patchfn)
-        if os.path.exists(self.join(patchfn)):
-            if os.path.isdir(self.join(patchfn)):
-                raise util.Abort(_('"%s" already exists as a directory')
-                                 % patchfn)
-            else:
-                raise util.Abort(_('patch "%s" already exists') % patchfn)
-
-        inclsubs = self.check_substate(repo)
+        if opts.get('checkname', True):
+            self.checkpatchname(patchfn)
+        inclsubs = self.checksubstate(repo)
         if inclsubs:
             inclsubs.append('.hgsubstate')
         if opts.get('include') or opts.get('exclude') or pats:
             if inclsubs:
                 pats = list(pats or []) + inclsubs
-            match = cmdutil.match(repo, pats, opts)
+            match = scmutil.match(repo[None], pats, opts)
             # detect missing files in pats
             def badfn(f, msg):
                 if f != '.hgsubstate': # .hgsubstate is auto-created
@@ -873,13 +907,13 @@
             match.bad = badfn
             m, a, r, d = repo.status(match=match)[:4]
         else:
-            m, a, r, d = self.check_localchanges(repo, force=True)
-            match = cmdutil.matchfiles(repo, m + a + r + inclsubs)
+            m, a, r, d = self.checklocalchanges(repo, force=True)
+            match = scmutil.matchfiles(repo, m + a + r + inclsubs)
         if len(repo[None].parents()) > 1:
             raise util.Abort(_('cannot manage merge changesets'))
         commitfiles = m + a + r
-        self.check_toppatch(repo)
-        insert = self.full_series_end()
+        self.checktoppatch(repo)
+        insert = self.fullseriesend()
         wlock = repo.wlock()
         try:
             try:
@@ -899,7 +933,7 @@
                 else:
                     p.write("# HG changeset patch\n")
                     p.write("# Parent "
-                            + hex(repo[None].parents()[0].node()) + "\n")
+                            + hex(repo[None].p1().node()) + "\n")
                     if user:
                         p.write("# User " + user + "\n")
                     if date:
@@ -911,17 +945,17 @@
                 if n is None:
                     raise util.Abort(_("repo commit failed"))
                 try:
-                    self.full_series[insert:insert] = [patchfn]
+                    self.fullseries[insert:insert] = [patchfn]
                     self.applied.append(statusentry(n, patchfn))
-                    self.parse_series()
-                    self.series_dirty = 1
-                    self.applied_dirty = 1
+                    self.parseseries()
+                    self.seriesdirty = 1
+                    self.applieddirty = 1
                     if msg:
                         msg = msg + "\n\n"
                         p.write(msg)
                     if commitfiles:
                         parent = self.qparents(repo, n)
-                        chunks = patch.diff(repo, node1=parent, node2=n,
+                        chunks = patchmod.diff(repo, node1=parent, node2=n,
                                             match=match, opts=diffopts)
                         for chunk in chunks:
                             p.write(chunk)
@@ -952,7 +986,7 @@
             lock = repo.lock()
 
             if update:
-                self.check_localchanges(repo, force=force, refresh=False)
+                self.checklocalchanges(repo, force=force, refresh=False)
                 urev = self.qparents(repo, revs[0])
                 hg.clean(repo, urev)
                 repo.dirstate.write()
@@ -982,7 +1016,7 @@
     def lookup(self, patch, strict=False):
         patch = patch and str(patch)
 
-        def partial_name(s):
+        def partialname(s):
             if s in self.series:
                 return s
             matches = [x for x in self.series if s in x]
@@ -995,7 +1029,7 @@
                 return matches[0]
             if self.series and self.applied:
                 if s == 'qtip':
-                    return self.series[self.series_end(True)-1]
+                    return self.series[self.seriesend(True)-1]
                 if s == 'qbase':
                     return self.series[0]
             return None
@@ -1015,12 +1049,12 @@
                     return self.series[sno]
 
             if not strict:
-                res = partial_name(patch)
+                res = partialname(patch)
                 if res:
                     return res
                 minus = patch.rfind('-')
                 if minus >= 0:
-                    res = partial_name(patch[:minus])
+                    res = partialname(patch[:minus])
                     if res:
                         i = self.series.index(res)
                         try:
@@ -1032,7 +1066,7 @@
                                 return self.series[i - off]
                 plus = patch.rfind('+')
                 if plus >= 0:
-                    res = partial_name(patch[:plus])
+                    res = partialname(patch[:plus])
                     if res:
                         i = self.series.index(res)
                         try:
@@ -1054,7 +1088,7 @@
                 heads += ls
             if not heads:
                 heads = [nullid]
-            if repo.dirstate.parents()[0] not in heads and not exact:
+            if repo.dirstate.p1() not in heads and not exact:
                 self.ui.status(_("(working directory not at a head)\n"))
 
             if not self.series:
@@ -1075,12 +1109,12 @@
 
                 pushable, reason = self.pushable(patch)
                 if pushable:
-                    if self.series.index(patch) < self.series_end():
+                    if self.series.index(patch) < self.seriesend():
                         raise util.Abort(
                             _("cannot push to a previous patch: %s") % patch)
                 else:
                     if reason:
-                        reason = _('guarded by %r') % reason
+                        reason = _('guarded by %s') % reason
                     else:
                         reason = _('no matching guards')
                     self.ui.warn(_("cannot push '%s' - %s\n") % (patch, reason))
@@ -1096,12 +1130,10 @@
             # qpush without an argument is an error (nothing to
             # apply). This allows a loop of "...while hg qpush..." to
             # work as it detects an error when done
-            start = self.series_end()
+            start = self.seriesend()
             if start == len(self.series):
                 self.ui.warn(_('patch series already fully applied\n'))
                 return 1
-            if not force:
-                self.check_localchanges(repo)
 
             if exact:
                 if move:
@@ -1118,21 +1150,21 @@
             if move:
                 if not patch:
                     raise util.Abort(_("please specify the patch to move"))
-                for i, rpn in enumerate(self.full_series[start:]):
+                for i, rpn in enumerate(self.fullseries[start:]):
                     # strip markers for patch guards
                     if self.guard_re.split(rpn, 1)[0] == patch:
                         break
                 index = start + i
-                assert index < len(self.full_series)
-                fullpatch = self.full_series[index]
-                del self.full_series[index]
-                self.full_series.insert(start, fullpatch)
-                self.parse_series()
-                self.series_dirty = 1
-
-            self.applied_dirty = 1
+                assert index < len(self.fullseries)
+                fullpatch = self.fullseries[index]
+                del self.fullseries[index]
+                self.fullseries.insert(start, fullpatch)
+                self.parseseries()
+                self.seriesdirty = 1
+
+            self.applieddirty = 1
             if start > 0:
-                self.check_toppatch(repo)
+                self.checktoppatch(repo)
             if not patch:
                 patch = self.series[start]
                 end = start + 1
@@ -1140,6 +1172,19 @@
                 end = self.series.index(patch, start) + 1
 
             s = self.series[start:end]
+
+            if not force:
+                mm, aa, rr, dd = repo.status()[:4]
+                wcfiles = set(mm + aa + rr + dd)
+                if wcfiles:
+                    for patchname in s:
+                        pf = os.path.join(self.path, patchname)
+                        patchfiles = patchmod.changedfiles(self.ui, repo, pf)
+                        if wcfiles.intersection(patchfiles):
+                            self.localchangesfound(self.applied)
+            elif mergeq:
+                self.checklocalchanges(refresh=self.applied)
+
             all_files = set()
             try:
                 if mergeq:
@@ -1148,7 +1193,7 @@
                     ret = self.apply(repo, s, list, all_files=all_files)
             except:
                 self.ui.warn(_('cleaning up working directory...'))
-                node = repo.dirstate.parents()[0]
+                node = repo.dirstate.p1()
                 hg.revert(repo, node, None)
                 # only remove unknown files that we know we touched or
                 # created while patching
@@ -1220,14 +1265,11 @@
                         break
                 update = needupdate
 
-            if not force and update:
-                self.check_localchanges(repo)
-
-            self.applied_dirty = 1
+            self.applieddirty = 1
             end = len(self.applied)
             rev = self.applied[start].node
             if update:
-                top = self.check_toppatch(repo)[0]
+                top = self.checktoppatch(repo)[0]
 
             try:
                 heads = repo.changelog.heads(rev)
@@ -1245,6 +1287,12 @@
                 qp = self.qparents(repo, rev)
                 ctx = repo[qp]
                 m, a, r, d = repo.status(qp, top)[:4]
+                parentfiles = set(m + a + r + d)
+                if not force and parentfiles:
+                    mm, aa, rr, dd = repo.status()[:4]
+                    wcfiles = set(mm + aa + rr + dd)
+                    if wcfiles.intersection(parentfiles):
+                        self.localchangesfound()
                 if d:
                     raise util.Abort(_("deletions found between repo revs"))
                 for f in a:
@@ -1253,7 +1301,7 @@
                     except OSError, e:
                         if e.errno != errno.ENOENT:
                             raise
-                    repo.dirstate.forget(f)
+                    repo.dirstate.drop(f)
                 for f in m + r:
                     fctx = ctx[f]
                     repo.wwrite(f, fctx.data(), fctx.flags())
@@ -1271,7 +1319,7 @@
             wlock.release()
 
     def diff(self, repo, pats, opts):
-        top, patch = self.check_toppatch(repo)
+        top, patch = self.checktoppatch(repo)
         if not top:
             self.ui.write(_("no patches applied\n"))
             return
@@ -1295,12 +1343,12 @@
         wlock = repo.wlock()
 
         try:
-            self.check_toppatch(repo)
+            self.checktoppatch(repo)
             (top, patchfn) = (self.applied[-1].node, self.applied[-1].name)
             if repo.changelog.heads(top) != [top]:
                 raise util.Abort(_("cannot refresh a revision with children"))
 
-            inclsubs = self.check_substate(repo)
+            inclsubs = self.checksubstate(repo)
 
             cparents = repo.changelog.parents(top)
             patchparent = self.qparents(repo, top)
@@ -1332,17 +1380,17 @@
             changes = repo.changelog.read(top)
             man = repo.manifest.read(changes[0])
             aaa = aa[:]
-            matchfn = cmdutil.match(repo, pats, opts)
+            matchfn = scmutil.match(repo[None], pats, opts)
             # in short mode, we only diff the files included in the
             # patch already plus specified files
             if opts.get('short'):
                 # if amending a patch, we start with existing
                 # files plus specified files - unfiltered
-                match = cmdutil.matchfiles(repo, mm + aa + dd + matchfn.files())
+                match = scmutil.matchfiles(repo, mm + aa + dd + matchfn.files())
                 # filter with inc/exl options
-                matchfn = cmdutil.match(repo, opts=opts)
+                matchfn = scmutil.match(repo[None], opts=opts)
             else:
-                match = cmdutil.matchall(repo)
+                match = scmutil.matchall(repo)
             m, a, r, d = repo.status(match=match)[:4]
             mm = set(mm)
             aa = set(aa)
@@ -1380,8 +1428,8 @@
             r = list(dd)
             a = list(aa)
             c = [filter(matchfn, l) for l in (m, a, r)]
-            match = cmdutil.matchfiles(repo, set(c[0] + c[1] + c[2] + inclsubs))
-            chunks = patch.diff(repo, patchparent, match=match,
+            match = scmutil.matchfiles(repo, set(c[0] + c[1] + c[2] + inclsubs))
+            chunks = patchmod.diff(repo, patchparent, match=match,
                                 changes=c, opts=diffopts)
             for chunk in chunks:
                 patchf.write(chunk)
@@ -1431,7 +1479,7 @@
                 for f in mm:
                     repo.dirstate.normallookup(f)
                 for f in forget:
-                    repo.dirstate.forget(f)
+                    repo.dirstate.drop(f)
 
                 if not msg:
                     if not ph.message:
@@ -1446,7 +1494,7 @@
                 # assumes strip can roll itself back if interrupted
                 repo.dirstate.setparents(*cparents)
                 self.applied.pop()
-                self.applied_dirty = 1
+                self.applieddirty = 1
                 self.strip(repo, [top], update=False,
                            backup='strip')
             except:
@@ -1463,7 +1511,7 @@
             except:
                 ctx = repo[cparents[0]]
                 repo.dirstate.rebuild(ctx.node(), ctx.manifest())
-                self.save_dirty()
+                self.savedirty()
                 self.ui.warn(_('refresh interrupted while patch was popped! '
                                '(revert --all, qpush to recover)\n'))
                 raise
@@ -1486,7 +1534,7 @@
         if patch and patch not in self.series:
             raise util.Abort(_("patch %s is not in series file") % patch)
         if not patch:
-            start = self.series_end()
+            start = self.seriesend()
         else:
             start = self.series.index(patch) + 1
         unapplied = []
@@ -1494,7 +1542,7 @@
             pushable, reason = self.pushable(i)
             if pushable:
                 unapplied.append((i, self.series[i]))
-            self.explain_pushable(i)
+            self.explainpushable(i)
         return unapplied
 
     def qseries(self, repo, missing=None, start=0, length=None, status=None,
@@ -1545,8 +1593,8 @@
                 for f in files:
                     fl = os.path.join(d, f)
                     if (fl not in self.series and
-                        fl not in (self.status_path, self.series_path,
-                                   self.guards_path)
+                        fl not in (self.statuspath, self.seriespath,
+                                   self.guardspath)
                         and not fl.startswith('.')):
                         msng_list.append(fl)
             for x in sorted(msng_list):
@@ -1590,11 +1638,11 @@
             self.ui.warn(_("No saved patch data found\n"))
             return 1
         self.ui.warn(_("restoring status: %s\n") % lines[0])
-        self.full_series = series
+        self.fullseries = series
         self.applied = applied
-        self.parse_series()
-        self.series_dirty = 1
-        self.applied_dirty = 1
+        self.parseseries()
+        self.seriesdirty = 1
+        self.applieddirty = 1
         heads = repo.changelog.heads()
         if delete:
             if rev not in heads:
@@ -1636,25 +1684,25 @@
             msg += "\nDirstate: %s %s" % (hex(pp[0]), hex(pp[1]))
         msg += "\n\nPatch Data:\n"
         msg += ''.join('%s\n' % x for x in self.applied)
-        msg += ''.join(':%s\n' % x for x in self.full_series)
+        msg += ''.join(':%s\n' % x for x in self.fullseries)
         n = repo.commit(msg, force=True)
         if not n:
             self.ui.warn(_("repo commit failed\n"))
             return 1
         self.applied.append(statusentry(n, '.hg.patches.save.line'))
-        self.applied_dirty = 1
+        self.applieddirty = 1
         self.removeundo(repo)
 
-    def full_series_end(self):
+    def fullseriesend(self):
         if self.applied:
             p = self.applied[-1].name
-            end = self.find_series(p)
+            end = self.findseries(p)
             if end is None:
-                return len(self.full_series)
+                return len(self.fullseries)
             return end + 1
         return 0
 
-    def series_end(self, all_patches=False):
+    def seriesend(self, all_patches=False):
         """If all_patches is False, return the index of the next pushable patch
         in the series, or the series length. If all_patches is True, return the
         index of the first patch past the last applied one.
@@ -1667,7 +1715,7 @@
                 p, reason = self.pushable(i)
                 if p:
                     break
-                self.explain_pushable(i)
+                self.explainpushable(i)
             return i
         if self.applied:
             p = self.applied[-1].name
@@ -1692,16 +1740,12 @@
             if patchname in self.series:
                 raise util.Abort(_('patch %s is already in the series file')
                                  % patchname)
-        def checkfile(patchname):
-            if not force and os.path.exists(self.join(patchname)):
-                raise util.Abort(_('patch "%s" already exists')
-                                 % patchname)
 
         if rev:
             if files:
                 raise util.Abort(_('option "-r" not valid when importing '
                                    'files'))
-            rev = cmdutil.revrange(repo, rev)
+            rev = scmutil.revrange(repo, rev)
             rev.sort(reverse=True)
         if (len(files) > 1 or len(rev) > 1) and patchname:
             raise util.Abort(_('option "-n" not valid when importing multiple '
@@ -1743,10 +1787,9 @@
 
                 if not patchname:
                     patchname = normname('%d.diff' % r)
-                self.check_reserved_name(patchname)
                 checkseries(patchname)
-                checkfile(patchname)
-                self.full_series.insert(0, patchname)
+                self.checkpatchname(patchname, force)
+                self.fullseries.insert(0, patchname)
 
                 patchf = self.opener(patchname, "w")
                 cmdutil.export(repo, [n], fp=patchf, opts=diffopts)
@@ -1757,23 +1800,22 @@
 
                 self.added.append(patchname)
                 patchname = None
-            self.parse_series()
-            self.applied_dirty = 1
-            self.series_dirty = True
+            self.parseseries()
+            self.applieddirty = 1
+            self.seriesdirty = True
 
         for i, filename in enumerate(files):
             if existing:
                 if filename == '-':
                     raise util.Abort(_('-e is incompatible with import from -'))
                 filename = normname(filename)
-                self.check_reserved_name(filename)
+                self.checkreservedname(filename)
                 originpath = self.join(filename)
                 if not os.path.isfile(originpath):
                     raise util.Abort(_("patch %s does not exist") % filename)
 
                 if patchname:
-                    self.check_reserved_name(patchname)
-                    checkfile(patchname)
+                    self.checkpatchname(patchname, force)
 
                     self.ui.write(_('renaming %s to %s\n')
                                         % (filename, patchname))
@@ -1782,38 +1824,41 @@
                     patchname = filename
 
             else:
+                if filename == '-' and not patchname:
+                    raise util.Abort(_('need --name to import a patch from -'))
+                elif not patchname:
+                    patchname = normname(os.path.basename(filename.rstrip('/')))
+                self.checkpatchname(patchname, force)
                 try:
                     if filename == '-':
-                        if not patchname:
-                            raise util.Abort(
-                                _('need --name to import a patch from -'))
-                        text = sys.stdin.read()
+                        text = self.ui.fin.read()
                     else:
                         fp = url.open(self.ui, filename)
                         text = fp.read()
                         fp.close()
                 except (OSError, IOError):
                     raise util.Abort(_("unable to read file %s") % filename)
-                if not patchname:
-                    patchname = normname(os.path.basename(filename))
-                self.check_reserved_name(patchname)
-                checkfile(patchname)
                 patchf = self.opener(patchname, "w")
                 patchf.write(text)
                 patchf.close()
             if not force:
                 checkseries(patchname)
             if patchname not in self.series:
-                index = self.full_series_end() + i
-                self.full_series[index:index] = [patchname]
-            self.parse_series()
-            self.series_dirty = True
+                index = self.fullseriesend() + i
+                self.fullseries[index:index] = [patchname]
+            self.parseseries()
+            self.seriesdirty = True
             self.ui.warn(_("adding %s to series file\n") % patchname)
             self.added.append(patchname)
             patchname = None
 
         self.removeundo(repo)
 
+@command("qdelete|qremove|qrm",
+         [('k', 'keep', None, _('keep patch file')),
+          ('r', 'rev', [],
+           _('stop managing a revision (DEPRECATED)'), _('REV'))],
+         _('hg qdelete [-k] [PATCH]...'))
 def delete(ui, repo, *patches, **opts):
     """remove patches from queue
 
@@ -1824,9 +1869,13 @@
     use the :hg:`qfinish` command."""
     q = repo.mq
     q.delete(repo, patches, opts)
-    q.save_dirty()
+    q.savedirty()
     return 0
 
+@command("qapplied",
+         [('1', 'last', None, _('show only the last patch'))
+          ] + seriesopts,
+         _('hg qapplied [-1] [-s] [PATCH]'))
 def applied(ui, repo, patch=None, **opts):
     """print the patches already applied
 
@@ -1839,7 +1888,7 @@
             raise util.Abort(_("patch %s is not in series file") % patch)
         end = q.series.index(patch) + 1
     else:
-        end = q.series_end(True)
+        end = q.seriesend(True)
 
     if opts.get('last') and not end:
         ui.write(_("no patches applied\n"))
@@ -1857,6 +1906,9 @@
               summary=opts.get('summary'))
 
 
+@command("qunapplied",
+         [('1', 'first', None, _('show only the first patch'))] + seriesopts,
+         _('hg qunapplied [-1] [-s] [PATCH]'))
 def unapplied(ui, repo, patch=None, **opts):
     """print the patches not yet applied
 
@@ -1868,7 +1920,7 @@
             raise util.Abort(_("patch %s is not in series file") % patch)
         start = q.series.index(patch) + 1
     else:
-        start = q.series_end(True)
+        start = q.seriesend(True)
 
     if start == len(q.series) and opts.get('first'):
         ui.write(_("all patches applied\n"))
@@ -1878,6 +1930,16 @@
     q.qseries(repo, start=start, length=length, status='U',
               summary=opts.get('summary'))
 
+@command("qimport",
+         [('e', 'existing', None, _('import file in patch directory')),
+          ('n', 'name', '',
+           _('name of patch file'), _('NAME')),
+          ('f', 'force', None, _('overwrite existing files')),
+          ('r', 'rev', [],
+           _('place existing revisions under mq control'), _('REV')),
+          ('g', 'git', None, _('use git extended diff format')),
+          ('P', 'push', None, _('qpush after importing'))],
+         _('hg qimport [-e] [-n NAME] [-f] [-g] [-P] [-r REV]... FILE...'))
 def qimport(ui, repo, *filename, **opts):
     """import a patch
 
@@ -1899,7 +1961,7 @@
     With -g/--git, patches imported with --rev will use the git diff
     format. See the diffs help topic for information on why this is
     important for preserving rename/copy information and permission
-    changes.
+    changes. Use :hg:`qfinish` to remove changesets from mq control.
 
     To import a patch from standard input, pass - as the patch file.
     When importing from standard input, a patch name must be specified
@@ -1917,7 +1979,7 @@
               existing=opts.get('existing'), force=opts.get('force'),
               rev=opts.get('rev'), git=opts.get('git'))
     finally:
-        q.save_dirty()
+        q.savedirty()
 
     if opts.get('push') and not opts.get('rev'):
         return q.push(repo, None)
@@ -1933,7 +1995,7 @@
     Returns 0 if initialization succeeded."""
     q = repo.mq
     r = q.init(repo, create)
-    q.save_dirty()
+    q.savedirty()
     if r:
         if not os.path.exists(r.wjoin('.hgignore')):
             fp = r.wopener('.hgignore', 'w')
@@ -1949,6 +2011,9 @@
         commands.add(ui, r)
     return 0
 
+@command("^qinit",
+         [('c', 'create-repo', None, _('create queue repository'))],
+         _('hg qinit [-c]'))
 def init(ui, repo, **opts):
     """init a new queue repository (DEPRECATED)
 
@@ -1962,6 +2027,15 @@
     commands. With -c, use :hg:`init --mq` instead."""
     return qinit(ui, repo, create=opts.get('create_repo'))
 
+@command("qclone",
+         [('', 'pull', None, _('use pull protocol to copy metadata')),
+          ('U', 'noupdate', None, _('do not update the new working directories')),
+          ('', 'uncompressed', None,
+           _('use uncompressed transfer (fast over LAN)')),
+          ('p', 'patches', '',
+           _('location of source patch repository'), _('REPO')),
+         ] + commands.remoteopts,
+         _('hg qclone [OPTION]... SOURCE [DEST]'))
 def clone(ui, source, dest=None, **opts):
     '''clone main and patch repository at same time
 
@@ -2010,13 +2084,13 @@
         except error.RepoError:
             pass
     ui.note(_('cloning main repository\n'))
-    sr, dr = hg.clone(ui, sr.url(), dest,
+    sr, dr = hg.clone(ui, opts, sr.url(), dest,
                       pull=opts.get('pull'),
                       rev=destrev,
                       update=False,
                       stream=opts.get('uncompressed'))
     ui.note(_('cloning patch repository\n'))
-    hg.clone(ui, opts.get('patches') or patchdir(sr), patchdir(dr),
+    hg.clone(ui, opts, opts.get('patches') or patchdir(sr), patchdir(dr),
              pull=opts.get('pull'), update=not opts.get('noupdate'),
              stream=opts.get('uncompressed'))
     if dr.local():
@@ -2028,6 +2102,9 @@
             ui.note(_('updating destination repository\n'))
             hg.update(dr, dr.changelog.tip())
 
+@command("qcommit|qci",
+         commands.table["^commit|ci"][1],
+         _('hg qcommit [OPTION]... [FILE]...'))
 def commit(ui, repo, *pats, **opts):
     """commit changes in the queue repository (DEPRECATED)
 
@@ -2038,6 +2115,10 @@
         raise util.Abort('no queue repository')
     commands.commit(r.ui, r, *pats, **opts)
 
+@command("qseries",
+         [('m', 'missing', None, _('print patches not in series')),
+         ] + seriesopts,
+          _('hg qseries [-ms]'))
 def series(ui, repo, **opts):
     """print the entire series file
 
@@ -2045,12 +2126,13 @@
     repo.mq.qseries(repo, missing=opts.get('missing'), summary=opts.get('summary'))
     return 0
 
+@command("qtop", seriesopts, _('hg qtop [-s]'))
 def top(ui, repo, **opts):
     """print the name of the current patch
 
     Returns 0 on success."""
     q = repo.mq
-    t = q.applied and q.series_end(True) or 0
+    t = q.applied and q.seriesend(True) or 0
     if t:
         q.qseries(repo, start=t - 1, length=1, status='A',
                   summary=opts.get('summary'))
@@ -2058,17 +2140,19 @@
         ui.write(_("no patches applied\n"))
         return 1
 
+@command("qnext", seriesopts, _('hg qnext [-s]'))
 def next(ui, repo, **opts):
     """print the name of the next patch
 
     Returns 0 on success."""
     q = repo.mq
-    end = q.series_end()
+    end = q.seriesend()
     if end == len(q.series):
         ui.write(_("all patches applied\n"))
         return 1
     q.qseries(repo, start=end, length=1, summary=opts.get('summary'))
 
+@command("qprev", seriesopts, _('hg qprev [-s]'))
 def prev(ui, repo, **opts):
     """print the name of the previous patch
 
@@ -2090,6 +2174,18 @@
     if not opts.get('date') and opts.get('currentdate'):
         opts['date'] = "%d %d" % util.makedate()
 
+@command("^qnew",
+         [('e', 'edit', None, _('edit commit message')),
+          ('f', 'force', None, _('import uncommitted changes (DEPRECATED)')),
+          ('g', 'git', None, _('use git extended diff format')),
+          ('U', 'currentuser', None, _('add "From: <current user>" to patch')),
+          ('u', 'user', '',
+           _('add "From: <USER>" to patch'), _('USER')),
+          ('D', 'currentdate', None, _('add "Date: <current date>" to patch')),
+          ('d', 'date', '',
+           _('add "Date: <DATE>" to patch'), _('DATE'))
+          ] + commands.walkopts + commands.commitopts,
+         _('hg qnew [-e] [-m TEXT] [-l FILE] PATCH [FILE]...'))
 def new(ui, repo, patch, *args, **opts):
     """create a new patch
 
@@ -2115,7 +2211,7 @@
 
     Returns 0 on successful creation of a new patch.
     """
-    msg = cmdutil.logmessage(opts)
+    msg = cmdutil.logmessage(ui, opts)
     def getmsg():
         return ui.edit(msg, opts.get('user') or ui.username())
     q = repo.mq
@@ -2126,9 +2222,24 @@
         opts['msg'] = msg
     setupheaderopts(ui, opts)
     q.new(repo, patch, *args, **opts)
-    q.save_dirty()
+    q.savedirty()
     return 0
 
+@command("^qrefresh",
+         [('e', 'edit', None, _('edit commit message')),
+          ('g', 'git', None, _('use git extended diff format')),
+          ('s', 'short', None,
+           _('refresh only files already in the patch and specified files')),
+          ('U', 'currentuser', None,
+           _('add/update author field in patch with current user')),
+          ('u', 'user', '',
+           _('add/update author field in patch with given user'), _('USER')),
+          ('D', 'currentdate', None,
+           _('add/update date field in patch with current date')),
+          ('d', 'date', '',
+           _('add/update date field in patch with given date'), _('DATE'))
+          ] + commands.walkopts + commands.commitopts,
+         _('hg qrefresh [-I] [-X] [-e] [-m TEXT] [-l FILE] [-s] [FILE]...'))
 def refresh(ui, repo, *pats, **opts):
     """update the current patch
 
@@ -2151,7 +2262,7 @@
     Returns 0 on success.
     """
     q = repo.mq
-    message = cmdutil.logmessage(opts)
+    message = cmdutil.logmessage(ui, opts)
     if opts.get('edit'):
         if not q.applied:
             ui.write(_("no patches applied\n"))
@@ -2162,14 +2273,19 @@
         ph = patchheader(q.join(patch), q.plainmode)
         message = ui.edit('\n'.join(ph.message), ph.user or ui.username())
         # We don't want to lose the patch message if qrefresh fails (issue2062)
-        msgfile = repo.opener('last-message.txt', 'wb')
-        msgfile.write(message)
-        msgfile.close()
+        repo.savecommitmessage(message)
     setupheaderopts(ui, opts)
-    ret = q.refresh(repo, pats, msg=message, **opts)
-    q.save_dirty()
-    return ret
-
+    wlock = repo.wlock()
+    try:
+        ret = q.refresh(repo, pats, msg=message, **opts)
+        q.savedirty()
+        return ret
+    finally:
+        wlock.release()
+
+@command("^qdiff",
+         commands.diffopts + commands.diffopts2 + commands.walkopts,
+         _('hg qdiff [OPTION]... [FILE]...'))
 def diff(ui, repo, *pats, **opts):
     """diff of the current patch and subsequent modifications
 
@@ -2188,6 +2304,11 @@
     repo.mq.diff(repo, pats, opts)
     return 0
 
+@command('qfold',
+         [('e', 'edit', None, _('edit patch header')),
+          ('k', 'keep', None, _('keep folded patch files')),
+         ] + commands.commitopts,
+         _('hg qfold [-e] [-k] [-m TEXT] [-l FILE] PATCH...'))
 def fold(ui, repo, *files, **opts):
     """fold the named patches into the current patch
 
@@ -2207,11 +2328,11 @@
 
     if not files:
         raise util.Abort(_('qfold requires at least one patch name'))
-    if not q.check_toppatch(repo)[0]:
+    if not q.checktoppatch(repo)[0]:
         raise util.Abort(_('no patches applied'))
-    q.check_localchanges(repo)
-
-    message = cmdutil.logmessage(opts)
+    q.checklocalchanges(repo)
+
+    message = cmdutil.logmessage(ui, opts)
     if opts.get('edit'):
         if message:
             raise util.Abort(_('option "-e" incompatible with "-m" or "-l"'))
@@ -2236,7 +2357,6 @@
         (patchsuccess, files, fuzz) = q.patch(repo, pf)
         if not patchsuccess:
             raise util.Abort(_('error folding patch %s') % p)
-        cmdutil.updatedir(ui, repo, files)
 
     if not message:
         ph = patchheader(q.join(parent), q.plainmode)
@@ -2250,10 +2370,17 @@
         message = ui.edit(message, user or ui.username())
 
     diffopts = q.patchopts(q.diffopts(), *patches)
-    q.refresh(repo, msg=message, git=diffopts.git)
-    q.delete(repo, patches, opts)
-    q.save_dirty()
-
+    wlock = repo.wlock()
+    try:
+        q.refresh(repo, msg=message, git=diffopts.git)
+        q.delete(repo, patches, opts)
+        q.savedirty()
+    finally:
+        wlock.release()
+
+@command("qgoto",
+         [('f', 'force', None, _('overwrite any local changes'))],
+         _('hg qgoto [OPTION]... PATCH'))
 def goto(ui, repo, patch, **opts):
     '''push or pop patches until named patch is at top of stack
 
@@ -2264,9 +2391,13 @@
         ret = q.pop(repo, patch, force=opts.get('force'))
     else:
         ret = q.push(repo, patch, force=opts.get('force'))
-    q.save_dirty()
+    q.savedirty()
     return ret
 
+@command("qguard",
+         [('l', 'list', None, _('list all patches and guards')),
+          ('n', 'none', None, _('drop all guards'))],
+         _('hg qguard [-l] [-n] [PATCH] [-- [+GUARD]... [-GUARD]...]'))
 def guard(ui, repo, *args, **opts):
     '''set or print guards for a patch
 
@@ -2289,7 +2420,7 @@
     Returns 0 on success.
     '''
     def status(idx):
-        guards = q.series_guards[idx] or ['unguarded']
+        guards = q.seriesguards[idx] or ['unguarded']
         if q.series[idx] in applied:
             state = 'applied'
         elif q.pushable(idx)[0]:
@@ -2328,14 +2459,15 @@
     if patch is None:
         raise util.Abort(_('no patch to work with'))
     if args or opts.get('none'):
-        idx = q.find_series(patch)
+        idx = q.findseries(patch)
         if idx is None:
             raise util.Abort(_('no patch named %s') % patch)
-        q.set_guards(idx, args)
-        q.save_dirty()
+        q.setguards(idx, args)
+        q.savedirty()
     else:
         status(q.series.index(q.lookup(patch)))
 
+@command("qheader", [], _('hg qheader [PATCH]'))
 def header(ui, repo, patch=None):
     """print the header of the topmost or specified patch
 
@@ -2377,6 +2509,16 @@
     newpath = path + ".%d" % (index + 1)
     return newpath
 
+@command("^qpush",
+         [('f', 'force', None, _('apply on top of local changes')),
+          ('e', 'exact', None, _('apply the target patch to its recorded parent')),
+          ('l', 'list', None, _('list patch name in commit text')),
+          ('a', 'all', None, _('apply all patches')),
+          ('m', 'merge', None, _('merge from another queue (DEPRECATED)')),
+          ('n', 'name', '',
+           _('merge queue name (DEPRECATED)'), _('NAME')),
+          ('', 'move', None, _('reorder patch series and apply only the patch'))],
+         _('hg qpush [-f] [-l] [-a] [--move] [PATCH | INDEX]'))
 def push(ui, repo, patch=None, **opts):
     """push the next patch onto the stack
 
@@ -2403,6 +2545,12 @@
                  exact=opts.get('exact'))
     return ret
 
+@command("^qpop",
+         [('a', 'all', None, _('pop all patches')),
+          ('n', 'name', '',
+           _('queue name to pop (DEPRECATED)'), _('NAME')),
+          ('f', 'force', None, _('forget any local changes to patched files'))],
+         _('hg qpop [-a] [-f] [PATCH | INDEX]'))
 def pop(ui, repo, patch=None, **opts):
     """pop the current patch off the stack
 
@@ -2421,9 +2569,10 @@
         q = repo.mq
     ret = q.pop(repo, patch, force=opts.get('force'), update=localupdate,
                 all=opts.get('all'))
-    q.save_dirty()
+    q.savedirty()
     return ret
 
+@command("qrename|qmv", [], _('hg qrename PATCH1 [PATCH2]'))
 def rename(ui, repo, patch, name=None, **opts):
     """rename a patch
 
@@ -2449,24 +2598,19 @@
     if os.path.isdir(absdest):
         name = normname(os.path.join(name, os.path.basename(patch)))
         absdest = q.join(name)
-    if os.path.exists(absdest):
-        raise util.Abort(_('%s already exists') % absdest)
-
-    if name in q.series:
-        raise util.Abort(
-            _('A patch named %s already exists in the series file') % name)
+    q.checkpatchname(name)
 
     ui.note(_('renaming %s to %s\n') % (patch, name))
-    i = q.find_series(patch)
-    guards = q.guard_re.findall(q.full_series[i])
-    q.full_series[i] = name + ''.join([' #' + g for g in guards])
-    q.parse_series()
-    q.series_dirty = 1
+    i = q.findseries(patch)
+    guards = q.guard_re.findall(q.fullseries[i])
+    q.fullseries[i] = name + ''.join([' #' + g for g in guards])
+    q.parseseries()
+    q.seriesdirty = 1
 
     info = q.isapplied(patch)
     if info:
         q.applied[info[0]] = statusentry(info[1], name)
-    q.applied_dirty = 1
+    q.applieddirty = 1
 
     destdir = os.path.dirname(absdest)
     if not os.path.isdir(destdir):
@@ -2478,18 +2622,22 @@
         wlock = r.wlock()
         try:
             if r.dirstate[patch] == 'a':
-                r.dirstate.forget(patch)
+                r.dirstate.drop(patch)
                 r.dirstate.add(name)
             else:
                 if r.dirstate[name] == 'r':
                     wctx.undelete([name])
                 wctx.copy(patch, name)
-                wctx.remove([patch], False)
+                wctx.forget([patch])
         finally:
             wlock.release()
 
-    q.save_dirty()
-
+    q.savedirty()
+
+@command("qrestore",
+         [('d', 'delete', None, _('delete save entry')),
+          ('u', 'update', None, _('update queue working directory'))],
+         _('hg qrestore [-d] [-u] REV'))
 def restore(ui, repo, rev, **opts):
     """restore the queue state saved by a revision (DEPRECATED)
 
@@ -2498,19 +2646,26 @@
     q = repo.mq
     q.restore(repo, rev, delete=opts.get('delete'),
               qupdate=opts.get('update'))
-    q.save_dirty()
+    q.savedirty()
     return 0
 
+@command("qsave",
+         [('c', 'copy', None, _('copy patch directory')),
+          ('n', 'name', '',
+           _('copy directory name'), _('NAME')),
+          ('e', 'empty', None, _('clear queue status file')),
+          ('f', 'force', None, _('force copy'))] + commands.commitopts,
+         _('hg qsave [-m TEXT] [-l FILE] [-c] [-n NAME] [-e] [-f]'))
 def save(ui, repo, **opts):
     """save current queue state (DEPRECATED)
 
     This command is deprecated, use :hg:`rebase` instead."""
     q = repo.mq
-    message = cmdutil.logmessage(opts)
+    message = cmdutil.logmessage(ui, opts)
     ret = q.save(repo, msg=message)
     if ret:
         return ret
-    q.save_dirty()
+    q.savedirty()
     if opts.get('copy'):
         path = q.path
         if opts.get('name'):
@@ -2528,11 +2683,21 @@
         util.copyfiles(path, newpath)
     if opts.get('empty'):
         try:
-            os.unlink(q.join(q.status_path))
+            os.unlink(q.join(q.statuspath))
         except:
             pass
     return 0
 
+@command("strip",
+         [('f', 'force', None, _('force removal of changesets, discard '
+                                 'uncommitted changes (no backup)')),
+          ('b', 'backup', None, _('bundle only changesets with local revision'
+                                  ' number greater than REV which are not'
+                                  ' descendants of REV (DEPRECATED)')),
+          ('n', 'no-backup', None, _('no backups')),
+          ('', 'nobackup', None, _('no backups (DEPRECATED)')),
+          ('k', 'keep', None, _("do not modify working copy during strip"))],
+          _('hg strip [-k] [-f] [-n] REV...'))
 def strip(ui, repo, *revs, **opts):
     """strip changesets and all their descendants from the repository
 
@@ -2565,7 +2730,7 @@
         backup = 'none'
 
     cl = repo.changelog
-    revs = set(cmdutil.revrange(repo, revs))
+    revs = set(scmutil.revrange(repo, revs))
     if not revs:
         raise util.Abort(_('empty revision set'))
 
@@ -2588,7 +2753,7 @@
         # refresh queue state if we're about to strip
         # applied patches
         if cl.rev(repo.lookup('qtip')) in strippedrevs:
-            q.applied_dirty = True
+            q.applieddirty = True
             start = 0
             end = len(q.applied)
             for i, statusentry in enumerate(q.applied):
@@ -2598,7 +2763,7 @@
                     start = i
                     break
             del q.applied[start:end]
-            q.save_dirty()
+            q.savedirty()
 
     revs = list(rootnodes)
     if update and opts.get('keep'):
@@ -2615,6 +2780,12 @@
                   force=opts.get('force'))
     return 0
 
+@command("qselect",
+         [('n', 'none', None, _('disable all guards')),
+          ('s', 'series', None, _('list all guards in series file')),
+          ('', 'pop', None, _('pop to before first guarded applied patch')),
+          ('', 'reapply', None, _('pop, then reapply patches'))],
+         _('hg qselect [OPTION]... [GUARD]...'))
 def select(ui, repo, *args, **opts):
     '''set or print guarded patches to push
 
@@ -2656,8 +2827,8 @@
         old_unapplied = q.unapplied(repo)
         old_guarded = [i for i in xrange(len(q.applied)) if
                        not q.pushable(i)[0]]
-        q.set_active(args)
-        q.save_dirty()
+        q.setactive(args)
+        q.savedirty()
         if not args:
             ui.status(_('guards deactivated\n'))
         if not opts.get('pop') and not opts.get('reapply'):
@@ -2675,7 +2846,7 @@
     elif opts.get('series'):
         guards = {}
         noguards = 0
-        for gs in q.series_guards:
+        for gs in q.seriesguards:
             if not gs:
                 noguards += 1
             for g in gs:
@@ -2718,8 +2889,11 @@
                 ui.status(_('reapplying unguarded patches\n'))
                 q.push(repo, reapply)
         finally:
-            q.save_dirty()
-
+            q.savedirty()
+
+@command("qfinish",
+         [('a', 'applied', None, _('finish all applied changesets'))],
+         _('hg qfinish [-a] [REV]...'))
 def finish(ui, repo, *revrange, **opts):
     """move applied patches into repository history
 
@@ -2748,11 +2922,19 @@
         ui.status(_('no patches applied\n'))
         return 0
 
-    revs = cmdutil.revrange(repo, revrange)
+    revs = scmutil.revrange(repo, revrange)
     q.finish(repo, revs)
-    q.save_dirty()
+    q.savedirty()
     return 0
 
+@command("qqueue",
+         [('l', 'list', False, _('list all available queues')),
+          ('c', 'create', False, _('create new queue')),
+          ('', 'rename', False, _('rename active queue')),
+          ('', 'delete', False, _('delete reference to queue')),
+          ('', 'purge', False, _('delete queue, and remove patch dir')),
+         ],
+         _('[OPTION] [QUEUE]'))
 def qqueue(ui, repo, name=None, **opts):
     '''manage multiple patch queues
 
@@ -2921,7 +3103,7 @@
         def mq(self):
             return queue(self.ui, self.join(""))
 
-        def abort_if_wdir_patched(self, errmsg, force=False):
+        def abortifwdirpatched(self, errmsg, force=False):
             if self.mq.applied and not force:
                 parents = self.dirstate.parents()
                 patches = [s.node for s in self.mq.applied]
@@ -2930,7 +3112,7 @@
 
         def commit(self, text="", user=None, date=None, match=None,
                    force=False, editor=False, extra={}):
-            self.abort_if_wdir_patched(
+            self.abortifwdirpatched(
                 _('cannot commit over an applied mq patch'),
                 force)
 
@@ -2961,8 +3143,8 @@
             mqtags = [(patch.node, patch.name) for patch in q.applied]
 
             try:
-                r = self.changelog.rev(mqtags[-1][0])
-            except error.RepoLookupError:
+                self.changelog.rev(mqtags[-1][0])
+            except error.LookupError:
                 self.ui.warn(_('mq status file refers to unknown node %s\n')
                              % short(mqtags[-1][0]))
                 return result
@@ -3015,9 +3197,9 @@
         repo.__class__ = mqrepo
 
 def mqimport(orig, ui, repo, *args, **kwargs):
-    if (hasattr(repo, 'abort_if_wdir_patched')
+    if (hasattr(repo, 'abortifwdirpatched')
         and not kwargs.get('no_commit', False)):
-        repo.abort_if_wdir_patched(_('cannot import over an applied patch'),
+        repo.abortifwdirpatched(_('cannot import over an applied patch'),
                                    kwargs.get('force'))
     return orig(ui, repo, *args, **kwargs)
 
@@ -3070,6 +3252,20 @@
         ui.note(_("mq:     (empty queue)\n"))
     return r
 
+def revsetmq(repo, subset, x):
+    """``mq()``
+    Changesets managed by MQ.
+    """
+    revset.getargs(x, 0, 0, _("mq takes no arguments"))
+    applied = set([repo[r.node].rev() for r in repo.mq.applied])
+    return [r for r in subset if r in applied]
+
+def extsetup(ui):
+    revset.symbols['mq'] = revsetmq
+
+# tell hggettext to extract docstrings from these functions:
+i18nfunctions = [revsetmq]
+
 def uisetup(ui):
     mqopt = [('', 'mq', None, _("operate on patch repository"))]
 
@@ -3079,7 +3275,7 @@
     entry = extensions.wrapcommand(commands.table, 'init', mqinit)
     entry[1].extend(mqopt)
 
-    nowrap = set(commands.norepo.split(" ") + ['qrecord'])
+    nowrap = set(commands.norepo.split(" "))
 
     def dotable(cmdtable):
         for cmd in cmdtable.keys():
@@ -3095,175 +3291,6 @@
         if extmodule.__file__ != __file__:
             dotable(getattr(extmodule, 'cmdtable', {}))
 
-seriesopts = [('s', 'summary', None, _('print first line of patch header'))]
-
-cmdtable = {
-    "qapplied":
-        (applied,
-         [('1', 'last', None, _('show only the last patch'))] + seriesopts,
-         _('hg qapplied [-1] [-s] [PATCH]')),
-    "qclone":
-        (clone,
-         [('', 'pull', None, _('use pull protocol to copy metadata')),
-          ('U', 'noupdate', None, _('do not update the new working directories')),
-          ('', 'uncompressed', None,
-           _('use uncompressed transfer (fast over LAN)')),
-          ('p', 'patches', '',
-           _('location of source patch repository'), _('REPO')),
-         ] + commands.remoteopts,
-         _('hg qclone [OPTION]... SOURCE [DEST]')),
-    "qcommit|qci":
-        (commit,
-         commands.table["^commit|ci"][1],
-         _('hg qcommit [OPTION]... [FILE]...')),
-    "^qdiff":
-        (diff,
-         commands.diffopts + commands.diffopts2 + commands.walkopts,
-         _('hg qdiff [OPTION]... [FILE]...')),
-    "qdelete|qremove|qrm":
-        (delete,
-         [('k', 'keep', None, _('keep patch file')),
-          ('r', 'rev', [],
-           _('stop managing a revision (DEPRECATED)'), _('REV'))],
-         _('hg qdelete [-k] [PATCH]...')),
-    'qfold':
-        (fold,
-         [('e', 'edit', None, _('edit patch header')),
-          ('k', 'keep', None, _('keep folded patch files')),
-         ] + commands.commitopts,
-         _('hg qfold [-e] [-k] [-m TEXT] [-l FILE] PATCH...')),
-    'qgoto':
-        (goto,
-         [('f', 'force', None, _('overwrite any local changes'))],
-         _('hg qgoto [OPTION]... PATCH')),
-    'qguard':
-        (guard,
-         [('l', 'list', None, _('list all patches and guards')),
-          ('n', 'none', None, _('drop all guards'))],
-         _('hg qguard [-l] [-n] [PATCH] [-- [+GUARD]... [-GUARD]...]')),
-    'qheader': (header, [], _('hg qheader [PATCH]')),
-    "qimport":
-        (qimport,
-         [('e', 'existing', None, _('import file in patch directory')),
-          ('n', 'name', '',
-           _('name of patch file'), _('NAME')),
-          ('f', 'force', None, _('overwrite existing files')),
-          ('r', 'rev', [],
-           _('place existing revisions under mq control'), _('REV')),
-          ('g', 'git', None, _('use git extended diff format')),
-          ('P', 'push', None, _('qpush after importing'))],
-         _('hg qimport [-e] [-n NAME] [-f] [-g] [-P] [-r REV]... FILE...')),
-    "^qinit":
-        (init,
-         [('c', 'create-repo', None, _('create queue repository'))],
-         _('hg qinit [-c]')),
-    "^qnew":
-        (new,
-         [('e', 'edit', None, _('edit commit message')),
-          ('f', 'force', None, _('import uncommitted changes (DEPRECATED)')),
-          ('g', 'git', None, _('use git extended diff format')),
-          ('U', 'currentuser', None, _('add "From: <current user>" to patch')),
-          ('u', 'user', '',
-           _('add "From: <USER>" to patch'), _('USER')),
-          ('D', 'currentdate', None, _('add "Date: <current date>" to patch')),
-          ('d', 'date', '',
-           _('add "Date: <DATE>" to patch'), _('DATE'))
-          ] + commands.walkopts + commands.commitopts,
-         _('hg qnew [-e] [-m TEXT] [-l FILE] PATCH [FILE]...')),
-    "qnext": (next, [] + seriesopts, _('hg qnext [-s]')),
-    "qprev": (prev, [] + seriesopts, _('hg qprev [-s]')),
-    "^qpop":
-        (pop,
-         [('a', 'all', None, _('pop all patches')),
-          ('n', 'name', '',
-           _('queue name to pop (DEPRECATED)'), _('NAME')),
-          ('f', 'force', None, _('forget any local changes to patched files'))],
-         _('hg qpop [-a] [-f] [PATCH | INDEX]')),
-    "^qpush":
-        (push,
-         [('f', 'force', None, _('apply on top of local changes')),
-          ('e', 'exact', None, _('apply the target patch to its recorded parent')),
-          ('l', 'list', None, _('list patch name in commit text')),
-          ('a', 'all', None, _('apply all patches')),
-          ('m', 'merge', None, _('merge from another queue (DEPRECATED)')),
-          ('n', 'name', '',
-           _('merge queue name (DEPRECATED)'), _('NAME')),
-          ('', 'move', None, _('reorder patch series and apply only the patch'))],
-         _('hg qpush [-f] [-l] [-a] [--move] [PATCH | INDEX]')),
-    "^qrefresh":
-        (refresh,
-         [('e', 'edit', None, _('edit commit message')),
-          ('g', 'git', None, _('use git extended diff format')),
-          ('s', 'short', None,
-           _('refresh only files already in the patch and specified files')),
-          ('U', 'currentuser', None,
-           _('add/update author field in patch with current user')),
-          ('u', 'user', '',
-           _('add/update author field in patch with given user'), _('USER')),
-          ('D', 'currentdate', None,
-           _('add/update date field in patch with current date')),
-          ('d', 'date', '',
-           _('add/update date field in patch with given date'), _('DATE'))
-          ] + commands.walkopts + commands.commitopts,
-         _('hg qrefresh [-I] [-X] [-e] [-m TEXT] [-l FILE] [-s] [FILE]...')),
-    'qrename|qmv':
-        (rename, [], _('hg qrename PATCH1 [PATCH2]')),
-    "qrestore":
-        (restore,
-         [('d', 'delete', None, _('delete save entry')),
-          ('u', 'update', None, _('update queue working directory'))],
-         _('hg qrestore [-d] [-u] REV')),
-    "qsave":
-        (save,
-         [('c', 'copy', None, _('copy patch directory')),
-          ('n', 'name', '',
-           _('copy directory name'), _('NAME')),
-          ('e', 'empty', None, _('clear queue status file')),
-          ('f', 'force', None, _('force copy'))] + commands.commitopts,
-         _('hg qsave [-m TEXT] [-l FILE] [-c] [-n NAME] [-e] [-f]')),
-    "qselect":
-        (select,
-         [('n', 'none', None, _('disable all guards')),
-          ('s', 'series', None, _('list all guards in series file')),
-          ('', 'pop', None, _('pop to before first guarded applied patch')),
-          ('', 'reapply', None, _('pop, then reapply patches'))],
-         _('hg qselect [OPTION]... [GUARD]...')),
-    "qseries":
-        (series,
-         [('m', 'missing', None, _('print patches not in series')),
-         ] + seriesopts,
-          _('hg qseries [-ms]')),
-     "strip":
-         (strip,
-         [('f', 'force', None, _('force removal of changesets, discard '
-                                 'uncommitted changes (no backup)')),
-          ('b', 'backup', None, _('bundle only changesets with local revision'
-                                  ' number greater than REV which are not'
-                                  ' descendants of REV (DEPRECATED)')),
-          ('n', 'no-backup', None, _('no backups')),
-          ('', 'nobackup', None, _('no backups (DEPRECATED)')),
-          ('k', 'keep', None, _("do not modify working copy during strip"))],
-          _('hg strip [-k] [-f] [-n] REV...')),
-     "qtop": (top, [] + seriesopts, _('hg qtop [-s]')),
-    "qunapplied":
-        (unapplied,
-         [('1', 'first', None, _('show only the first patch'))] + seriesopts,
-         _('hg qunapplied [-1] [-s] [PATCH]')),
-    "qfinish":
-        (finish,
-         [('a', 'applied', None, _('finish all applied changesets'))],
-         _('hg qfinish [-a] [REV]...')),
-    'qqueue':
-        (qqueue,
-         [
-             ('l', 'list', False, _('list all available queues')),
-             ('c', 'create', False, _('create new queue')),
-             ('', 'rename', False, _('rename active queue')),
-             ('', 'delete', False, _('delete reference to queue')),
-             ('', 'purge', False, _('delete queue, and remove patch dir')),
-         ],
-         _('[OPTION] [QUEUE]')),
-}
 
 colortable = {'qguard.negative': 'red',
               'qguard.positive': 'yellow',
--- a/hgext/notify.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/hgext/notify.py	Sat Jun 18 17:03:01 2011 -0500
@@ -21,6 +21,8 @@
   incoming.notify = python:hgext.notify.hook
   # batch emails when many changesets incoming at one time
   changegroup.notify = python:hgext.notify.hook
+  # batch emails when many changesets outgoing at one time (client side)
+  outgoing.notify = python:hgext.notify.hook
 
   [notify]
   # config items go here
@@ -37,7 +39,8 @@
   style = ...            # style file to use when formatting email
   template = ...         # template to use when formatting email
   incoming = ...         # template to use when run as incoming hook
-  changegroup = ...      # template when run as changegroup hook
+  outgoing = ...         # template to use when run as outgoing hook
+  changegroup = ...      # template to use when run as changegroup hook
   maxdiff = 300          # max lines of diffs to include (0=none, -1=all)
   maxsubject = 67        # truncate subject line longer than this
   diffstat = True        # add a diffstat before the diff content
@@ -249,7 +252,7 @@
     def diff(self, ctx, ref=None):
 
         maxdiff = int(self.ui.config('notify', 'maxdiff', 300))
-        prev = ctx.parents()[0].node()
+        prev = ctx.p1().node()
         ref = ref and ref.node() or ctx.node()
         chunks = patch.diff(self.repo, prev, ref, opts=patch.diffopts(self.ui))
         difflines = ''.join(chunks).splitlines()
@@ -290,7 +293,7 @@
     ui.pushbuffer()
     data = ''
     count = 0
-    if hooktype == 'changegroup':
+    if hooktype == 'changegroup' or hooktype == 'outgoing':
         start, end = ctx.rev(), len(repo)
         for rev in xrange(start, end):
             if n.node(repo[rev]):
--- a/hgext/pager.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/hgext/pager.py	Sat Jun 18 17:03:01 2011 -0500
@@ -60,7 +60,7 @@
 def _runpager(p):
     if not hasattr(os, 'fork'):
         sys.stdout = util.popen(p, 'wb')
-        if sys.stderr.isatty():
+        if util.isatty(sys.stderr):
             sys.stderr = sys.stdout
         return
     fdin, fdout = os.pipe()
@@ -68,7 +68,7 @@
     if pid == 0:
         os.close(fdin)
         os.dup2(fdout, sys.stdout.fileno())
-        if sys.stderr.isatty():
+        if util.isatty(sys.stderr):
             os.dup2(fdout, sys.stderr.fileno())
         os.close(fdout)
         return
@@ -86,12 +86,13 @@
             raise
 
 def uisetup(ui):
-    if ui.plain():
+    if ui.plain() or '--debugger' in sys.argv or not util.isatty(sys.stdout):
         return
 
     def pagecmd(orig, ui, options, cmd, cmdfunc):
         p = ui.config("pager", "pager", os.environ.get("PAGER"))
-        if p and sys.stdout.isatty() and '--debugger' not in sys.argv:
+
+        if p:
             attend = ui.configlist('pager', 'attend', attended)
             auto = options['pager'] == 'auto'
             always = util.parsebool(options['pager'])
--- a/hgext/parentrevspec.py	Wed Jun 01 16:32:48 2011 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,96 +0,0 @@
-# Mercurial extension to make it easy to refer to the parent of a revision
-#
-# Copyright (C) 2007 Alexis S. L. Carvalho <alexis@cecm.usp.br>
-#
-# This software may be used and distributed according to the terms of the
-# GNU General Public License version 2 or any later version.
-
-'''interpret suffixes to refer to ancestor revisions
-
-This extension allows you to use git-style suffixes to refer to the
-ancestors of a specific revision.
-
-For example, if you can refer to a revision as "foo", then::
-
-  foo^N = Nth parent of foo
-  foo^0 = foo
-  foo^1 = first parent of foo
-  foo^2 = second parent of foo
-  foo^  = foo^1
-
-  foo~N = Nth first grandparent of foo
-  foo~0 = foo
-  foo~1 = foo^1 = foo^ = first parent of foo
-  foo~2 = foo^1^1 = foo^^ = first parent of first parent of foo
-'''
-from mercurial import error
-
-def reposetup(ui, repo):
-    if not repo.local():
-        return
-
-    class parentrevspecrepo(repo.__class__):
-        def lookup(self, key):
-            try:
-                _super = super(parentrevspecrepo, self)
-                return _super.lookup(key)
-            except error.RepoError:
-                pass
-
-            circ = key.find('^')
-            tilde = key.find('~')
-            if circ < 0 and tilde < 0:
-                raise
-            elif circ >= 0 and tilde >= 0:
-                end = min(circ, tilde)
-            else:
-                end = max(circ, tilde)
-
-            cl = self.changelog
-            base = key[:end]
-            try:
-                node = _super.lookup(base)
-            except error.RepoError:
-                # eek - reraise the first error
-                return _super.lookup(key)
-
-            rev = cl.rev(node)
-            suffix = key[end:]
-            i = 0
-            while i < len(suffix):
-                # foo^N => Nth parent of foo
-                # foo^0 == foo
-                # foo^1 == foo^ == 1st parent of foo
-                # foo^2 == 2nd parent of foo
-                if suffix[i] == '^':
-                    j = i + 1
-                    p = cl.parentrevs(rev)
-                    if j < len(suffix) and suffix[j].isdigit():
-                        j += 1
-                        n = int(suffix[i + 1:j])
-                        if n > 2 or n == 2 and p[1] == -1:
-                            raise
-                    else:
-                        n = 1
-                    if n:
-                        rev = p[n - 1]
-                    i = j
-                # foo~N => Nth first grandparent of foo
-                # foo~0 = foo
-                # foo~1 = foo^1 == foo^ == 1st parent of foo
-                # foo~2 = foo^1^1 == foo^^ == 1st parent of 1st parent of foo
-                elif suffix[i] == '~':
-                    j = i + 1
-                    while j < len(suffix) and suffix[j].isdigit():
-                        j += 1
-                    if j == i + 1:
-                        raise
-                    n = int(suffix[i + 1:j])
-                    for k in xrange(n):
-                        rev = cl.parentrevs(rev)[0]
-                    i = j
-                else:
-                    raise
-            return cl.node(rev)
-
-    repo.__class__ = parentrevspecrepo
--- a/hgext/patchbomb.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/hgext/patchbomb.py	Sat Jun 18 17:03:01 2011 -0500
@@ -48,10 +48,14 @@
 import os, errno, socket, tempfile, cStringIO, time
 import email.MIMEMultipart, email.MIMEBase
 import email.Utils, email.Encoders, email.Generator
-from mercurial import cmdutil, commands, hg, mail, patch, util, discovery, url
+from mercurial import cmdutil, commands, hg, mail, patch, util, discovery
+from mercurial import scmutil
 from mercurial.i18n import _
 from mercurial.node import bin
 
+cmdtable = {}
+command = cmdutil.command(cmdtable)
+
 def prompt(ui, prompt, default=None, rest=':'):
     if not ui.interactive() and default is None:
         raise util.Abort(_("%s Please enter a valid value" % (prompt + rest)))
@@ -102,7 +106,7 @@
         while patchlines and not patchlines[0].strip():
             patchlines.pop(0)
 
-    ds = patch.diffstat(patchlines)
+    ds = patch.diffstat(patchlines, git=opts.get('git'))
     if opts.get('diffstat'):
         body += ds + '\n\n'
 
@@ -119,10 +123,10 @@
             if patchtags:
                 patchname = patchtags[0]
             elif total > 1:
-                patchname = cmdutil.make_filename(repo, '%b-%n.patch',
+                patchname = cmdutil.makefilename(repo, '%b-%n.patch',
                                                   binnode, seqno=idx, total=total)
             else:
-                patchname = cmdutil.make_filename(repo, '%b.patch', binnode)
+                patchname = cmdutil.makefilename(repo, '%b.patch', binnode)
         disposition = 'inline'
         if opts.get('attach'):
             disposition = 'attachment'
@@ -146,6 +150,40 @@
     msg['X-Mercurial-Node'] = node
     return msg, subj, ds
 
+emailopts = [
+    ('a', 'attach', None, _('send patches as attachments')),
+    ('i', 'inline', None, _('send patches as inline attachments')),
+    ('', 'bcc', [], _('email addresses of blind carbon copy recipients')),
+    ('c', 'cc', [], _('email addresses of copy recipients')),
+    ('', 'confirm', None, _('ask for confirmation before sending')),
+    ('d', 'diffstat', None, _('add diffstat output to messages')),
+    ('', 'date', '', _('use the given date as the sending date')),
+    ('', 'desc', '', _('use the given file as the series description')),
+    ('f', 'from', '', _('email address of sender')),
+    ('n', 'test', None, _('print messages that would be sent')),
+    ('m', 'mbox', '', _('write messages to mbox file instead of sending them')),
+    ('', 'reply-to', [], _('email addresses replies should be sent to')),
+    ('s', 'subject', '', _('subject of first message (intro or single patch)')),
+    ('', 'in-reply-to', '', _('message identifier to reply to')),
+    ('', 'flag', [], _('flags to add in subject prefixes')),
+    ('t', 'to', [], _('email addresses of recipients'))]
+
+@command('email',
+    [('g', 'git', None, _('use git extended diff format')),
+    ('', 'plain', None, _('omit hg patch header')),
+    ('o', 'outgoing', None,
+     _('send changes not found in the target repository')),
+    ('b', 'bundle', None, _('send changes not in target as a binary bundle')),
+    ('', 'bundlename', 'bundle',
+     _('name of the bundle attachment file'), _('NAME')),
+    ('r', 'rev', [], _('a revision to send'), _('REV')),
+    ('', 'force', None, _('run even when remote repository is unrelated '
+       '(with -b/--bundle)')),
+    ('', 'base', [], _('a base changeset to specify instead of a destination '
+       '(with -b/--bundle)'), _('REV')),
+    ('', 'intro', None, _('send an introduction email for a single patch')),
+    ] + emailopts + commands.remoteopts,
+    _('hg email [OPTION]... [DEST]...'))
 def patchbomb(ui, repo, *revs, **opts):
     '''send changesets by email
 
@@ -238,19 +276,18 @@
         dest = ui.expandpath(dest or 'default-push', dest or 'default')
         dest, branches = hg.parseurl(dest)
         revs, checkout = hg.addbranchrevs(repo, repo, branches, revs)
-        if revs:
-            revs = [repo.lookup(rev) for rev in revs]
-        other = hg.repository(hg.remoteui(repo, opts), dest)
-        ui.status(_('comparing with %s\n') % url.hidepassword(dest))
-        o = discovery.findoutgoing(repo, other)
+        other = hg.peer(repo, opts, dest)
+        ui.status(_('comparing with %s\n') % util.hidepassword(dest))
+        common, _anyinc, _heads = discovery.findcommonincoming(repo, other)
+        nodes = revs and map(repo.lookup, revs) or revs
+        o = repo.changelog.findmissing(common, heads=nodes)
         if not o:
             ui.status(_("no changes found\n"))
             return []
-        o = repo.changelog.nodesbetween(o, revs)[0]
         return [str(repo.changelog.rev(r)) for r in o]
 
     def getpatches(revs):
-        for r in cmdutil.revrange(repo, revs):
+        for r in scmutil.revrange(repo, revs):
             output = cStringIO.StringIO()
             cmdutil.export(repo, [r], fp=output,
                          opts=patch.diffopts(ui, opts))
@@ -512,52 +549,3 @@
 
     ui.progress(_('writing'), None)
     ui.progress(_('sending'), None)
-
-emailopts = [
-          ('a', 'attach', None, _('send patches as attachments')),
-          ('i', 'inline', None, _('send patches as inline attachments')),
-          ('', 'bcc', [], _('email addresses of blind carbon copy recipients')),
-          ('c', 'cc', [], _('email addresses of copy recipients')),
-          ('', 'confirm', None, _('ask for confirmation before sending')),
-          ('d', 'diffstat', None, _('add diffstat output to messages')),
-          ('', 'date', '', _('use the given date as the sending date')),
-          ('', 'desc', '', _('use the given file as the series description')),
-          ('f', 'from', '', _('email address of sender')),
-          ('n', 'test', None, _('print messages that would be sent')),
-          ('m', 'mbox', '',
-           _('write messages to mbox file instead of sending them')),
-          ('', 'reply-to', [], _('email addresses replies should be sent to')),
-          ('s', 'subject', '',
-           _('subject of first message (intro or single patch)')),
-          ('', 'in-reply-to', '',
-           _('message identifier to reply to')),
-          ('', 'flag', [], _('flags to add in subject prefixes')),
-          ('t', 'to', [], _('email addresses of recipients')),
-         ]
-
-
-cmdtable = {
-    "email":
-        (patchbomb,
-         [('g', 'git', None, _('use git extended diff format')),
-          ('', 'plain', None, _('omit hg patch header')),
-          ('o', 'outgoing', None,
-           _('send changes not found in the target repository')),
-          ('b', 'bundle', None,
-           _('send changes not in target as a binary bundle')),
-          ('', 'bundlename', 'bundle',
-           _('name of the bundle attachment file'), _('NAME')),
-          ('r', 'rev', [],
-           _('a revision to send'), _('REV')),
-          ('', 'force', None,
-           _('run even when remote repository is unrelated '
-             '(with -b/--bundle)')),
-          ('', 'base', [],
-           _('a base changeset to specify instead of a destination '
-             '(with -b/--bundle)'),
-           _('REV')),
-          ('', 'intro', None,
-           _('send an introduction email for a single patch')),
-         ] + emailopts + commands.remoteopts,
-         _('hg email [OPTION]... [DEST]...'))
-}
--- a/hgext/progress.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/hgext/progress.py	Sat Jun 18 17:03:01 2011 -0500
@@ -37,24 +37,23 @@
                      # disable is given
 
 Valid entries for the format field are topic, bar, number, unit,
-estimate, and item. item defaults to the last 20 characters of the
-item, but this can be changed by adding either ``-<num>`` which would
-take the last num characters, or ``+<num>`` for the first num
+estimate, speed, and item. item defaults to the last 20 characters of
+the item, but this can be changed by adding either ``-<num>`` which
+would take the last num characters, or ``+<num>`` for the first num
 characters.
 """
 
 import sys
 import time
 
+from mercurial import util
 from mercurial.i18n import _
-from mercurial import util
 
 def spacejoin(*args):
     return ' '.join(s for s in args if s)
 
 def shouldprint(ui):
-    return (getattr(sys.stderr, 'isatty', None) and
-            (sys.stderr.isatty() or ui.configbool('progress', 'assume-tty')))
+    return (util.isatty(sys.stderr) or ui.configbool('progress', 'assume-tty'))
 
 def fmtremaining(seconds):
     if seconds < 60:
@@ -152,6 +151,8 @@
                 add = unit
             elif indicator == 'estimate':
                 add = self.estimate(topic, pos, total, now)
+            elif indicator == 'speed':
+                add = self.speed(topic, pos, unit, now)
             if not needprogress:
                 head = spacejoin(head, add)
             else:
@@ -217,6 +218,15 @@
                 return fmtremaining(seconds)
         return ''
 
+    def speed(self, topic, pos, unit, now):
+        initialpos = self.startvals[topic]
+        delta = pos - initialpos
+        elapsed = now - self.starttimes[topic]
+        if elapsed > float(
+            self.ui.config('progress', 'estimate', default=2)):
+            return _('%d %s/sec') % (delta / elapsed, unit)
+        return ''
+
     def progress(self, topic, pos, item='', unit='', total=None):
         now = time.time()
         if pos is None:
@@ -239,7 +249,6 @@
             self.topicstates[topic] = pos, item, unit, total
             if now - self.lastprint >= self.refresh and self.topics:
                 self.lastprint = now
-                current = self.topics[-1]
                 self.show(now, topic, *self.topicstates[topic])
 
 def uisetup(ui):
--- a/hgext/purge.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/hgext/purge.py	Sat Jun 18 17:03:01 2011 -0500
@@ -25,10 +25,21 @@
 
 '''command to delete untracked files from the working directory'''
 
-from mercurial import util, commands, cmdutil
+from mercurial import util, commands, cmdutil, scmutil
 from mercurial.i18n import _
 import os, stat
 
+cmdtable = {}
+command = cmdutil.command(cmdtable)
+
+@command('purge|clean',
+    [('a', 'abort-on-err', None, _('abort if an error occurs')),
+    ('',  'all', None, _('purge ignored files too')),
+    ('p', 'print', None, _('print filenames instead of deleting them')),
+    ('0', 'print0', None, _('end filenames with NUL, for use with xargs'
+                            ' (implies -p/--print)')),
+    ] + commands.walkopts,
+    _('hg purge [OPTION]... [DIR]...'))
 def purge(ui, repo, *dirs, **opts):
     '''removes files not tracked by Mercurial
 
@@ -85,7 +96,7 @@
             os.remove(path)
 
     directories = []
-    match = cmdutil.match(repo, dirs, opts)
+    match = scmutil.match(repo[None], dirs, opts)
     match.dir = directories.append
     status = repo.status(match=match, ignored=opts['all'], unknown=True)
 
@@ -97,15 +108,3 @@
         if match(f) and not os.listdir(repo.wjoin(f)):
             ui.note(_('Removing directory %s\n') % f)
             remove(os.rmdir, f)
-
-cmdtable = {
-    'purge|clean':
-        (purge,
-         [('a', 'abort-on-err', None, _('abort if an error occurs')),
-          ('',  'all', None, _('purge ignored files too')),
-          ('p', 'print', None, _('print filenames instead of deleting them')),
-          ('0', 'print0', None, _('end filenames with NUL, for use with xargs'
-                                  ' (implies -p/--print)')),
-         ] + commands.walkopts,
-         _('hg purge [OPTION]... [DIR]...'))
-}
--- a/hgext/rebase.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/hgext/rebase.py	Sat Jun 18 17:03:01 2011 -0500
@@ -15,7 +15,7 @@
 '''
 
 from mercurial import hg, util, repair, merge, cmdutil, commands
-from mercurial import extensions, ancestor, copies, patch
+from mercurial import extensions, copies, patch
 from mercurial.commands import templateopts
 from mercurial.node import nullrev
 from mercurial.lock import release
@@ -24,6 +24,33 @@
 
 nullmerge = -2
 
+cmdtable = {}
+command = cmdutil.command(cmdtable)
+
+@command('rebase',
+    [('s', 'source', '',
+     _('rebase from the specified changeset'), _('REV')),
+    ('b', 'base', '',
+     _('rebase from the base of the specified changeset '
+       '(up to greatest common ancestor of base and dest)'),
+     _('REV')),
+    ('d', 'dest', '',
+     _('rebase onto the specified changeset'), _('REV')),
+    ('', 'collapse', False, _('collapse the rebased changesets')),
+    ('m', 'message', '',
+     _('use text as collapse commit message'), _('TEXT')),
+    ('l', 'logfile', '',
+     _('read collapse commit message from file'), _('FILE')),
+    ('', 'keep', False, _('keep original changesets')),
+    ('', 'keepbranches', False, _('keep original branch names')),
+    ('', 'detach', False, _('force detaching of source from its original '
+                            'branch')),
+    ('t', 'tool', '', _('specify merge tool')),
+    ('c', 'continue', False, _('continue an interrupted rebase')),
+    ('a', 'abort', False, _('abort an interrupted rebase'))] +
+     templateopts,
+    _('hg rebase [-s REV | -b REV] [-d REV] [options]\n'
+      'hg rebase {-a|-c}'))
 def rebase(ui, repo, **opts):
     """move changeset (and descendants) to a different branch
 
@@ -90,7 +117,8 @@
         contf = opts.get('continue')
         abortf = opts.get('abort')
         collapsef = opts.get('collapse', False)
-        extrafn = opts.get('extrafn')
+        collapsemsg = cmdutil.logmessage(ui, opts)
+        extrafn = opts.get('extrafn') # internal, used by e.g. hgsubversion
         keepf = opts.get('keep', False)
         keepbranchesf = opts.get('keepbranches', False)
         detachf = opts.get('detach', False)
@@ -98,6 +126,10 @@
         # other extensions
         keepopen = opts.get('keepopen', False)
 
+        if collapsemsg and not collapsef:
+            raise util.Abort(
+                _('message can only be specified with collapse'))
+
         if contf or abortf:
             if contf and abortf:
                 raise util.Abort(_('cannot use both abort and continue'))
@@ -109,6 +141,8 @@
             if srcf or basef or destf:
                 raise util.Abort(
                     _('abort and continue do not allow specifying revisions'))
+            if opts.get('tool', False):
+                ui.warn(_('tool option will be ignored\n'))
 
             (originalwd, target, state, skipped, collapsef, keepf,
                                 keepbranchesf, external) = restorestatus(repo)
@@ -125,7 +159,7 @@
                 if basef:
                     raise util.Abort(_('cannot specify a base with detach'))
 
-            cmdutil.bail_if_changed(repo)
+            cmdutil.bailifchanged(repo)
             result = buildstate(repo, destf, srcf, basef, detachf)
             if not result:
                 # Empty state built, nothing to rebase
@@ -138,8 +172,7 @@
                     external = checkexternal(repo, state, targetancestors)
 
         if keepbranchesf:
-            if extrafn:
-                raise util.Abort(_('cannot use both keepbranches and extrafn'))
+            assert not extrafn, 'cannot use both keepbranches and extrafn'
             def extrafn(ctx, extra):
                 extra['branch'] = ctx.branch()
 
@@ -163,10 +196,14 @@
                 if len(repo.parents()) == 2:
                     repo.ui.debug('resuming interrupted rebase\n')
                 else:
-                    stats = rebasenode(repo, rev, p1, p2, state)
-                    if stats and stats[3] > 0:
-                        raise util.Abort(_('unresolved conflicts (see hg '
-                                    'resolve, then hg rebase --continue)'))
+                    try:
+                        ui.setconfig('ui', 'forcemerge', opts.get('tool', ''))
+                        stats = rebasenode(repo, rev, p1, state)
+                        if stats and stats[3] > 0:
+                            raise util.Abort(_('unresolved conflicts (see hg '
+                                        'resolve, then hg rebase --continue)'))
+                    finally:
+                        ui.setconfig('ui', 'forcemerge', '')
                 updatedirstate(repo, rev, target, p2)
                 if not collapsef:
                     newrev = concludenode(repo, rev, p1, p2, extrafn=extrafn)
@@ -190,11 +227,14 @@
         if collapsef and not keepopen:
             p1, p2 = defineparents(repo, min(state), target,
                                                         state, targetancestors)
-            commitmsg = 'Collapsed revision'
-            for rebased in state:
-                if rebased not in skipped and state[rebased] != nullmerge:
-                    commitmsg += '\n* %s' % repo[rebased].description()
-            commitmsg = ui.edit(commitmsg, repo.ui.username())
+            if collapsemsg:
+                commitmsg = collapsemsg
+            else:
+                commitmsg = 'Collapsed revision'
+                for rebased in state:
+                    if rebased not in skipped and state[rebased] != nullmerge:
+                        commitmsg += '\n* %s' % repo[rebased].description()
+                commitmsg = ui.edit(commitmsg, repo.ui.username())
             newrev = concludenode(repo, rev, p1, external, commitmsg=commitmsg,
                                   extrafn=extrafn)
 
@@ -221,25 +261,6 @@
     finally:
         release(lock, wlock)
 
-def rebasemerge(repo, rev, first=False):
-    'return the correct ancestor'
-    oldancestor = ancestor.ancestor
-
-    def newancestor(a, b, pfunc):
-        if b == rev:
-            return repo[rev].parents()[0].rev()
-        return oldancestor(a, b, pfunc)
-
-    if not first:
-        ancestor.ancestor = newancestor
-    else:
-        repo.ui.debug("first revision, do not change ancestor\n")
-    try:
-        stats = merge.update(repo, rev, True, True, False)
-        return stats
-    finally:
-        ancestor.ancestor = oldancestor
-
 def checkexternal(repo, state, targetancestors):
     """Check whether one or more external revisions need to be taken in
     consideration. In the latter case, abort.
@@ -293,7 +314,7 @@
         repo.dirstate.invalidate()
         raise
 
-def rebasenode(repo, rev, p1, p2, state):
+def rebasenode(repo, rev, p1, state):
     'Rebase a single revision'
     # Merge phase
     # Update to target and merge it with local
@@ -304,9 +325,10 @@
         repo.ui.debug(" already in target\n")
     repo.dirstate.write()
     repo.ui.debug(" merge against %d:%s\n" % (repo[rev].rev(), repo[rev]))
-    first = repo[rev].rev() == repo[min(state)].rev()
-    stats = rebasemerge(repo, rev, first)
-    return stats
+    base = None
+    if repo[rev].rev() != repo[min(state)].rev():
+        base = repo[rev].p1().node()
+    return merge.update(repo, rev, True, True, False, base)
 
 def defineparents(repo, rev, target, state, targetancestors):
     'Return the new parent relationship of the revision that will be rebased'
@@ -354,7 +376,7 @@
     'Update rebased mq patches - finalize and then import them'
     mqrebase = {}
     mq = repo.mq
-    original_series = mq.full_series[:]
+    original_series = mq.fullseries[:]
 
     for p in mq.applied:
         rev = repo[p.node].rev()
@@ -374,15 +396,10 @@
                 mq.qimport(repo, (), patchname=name, git=isgit,
                                 rev=[str(state[rev])])
 
-        # Restore missing guards
-        for s in original_series:
-            pname = mq.guard_re.split(s, 1)[0]
-            if pname in mq.full_series:
-                repo.ui.debug('restoring guard for patch %s' % (pname))
-                mq.full_series.remove(pname)
-                mq.full_series.append(s)
-                mq.series_dirty = True
-        mq.save_dirty()
+        # restore old series to preserve guards
+        mq.fullseries = original_series
+        mq.series_dirty = True
+        mq.savedirty()
 
 def storestatus(repo, originalwd, target, state, collapse, keep, keepbranches,
                                                                 external):
@@ -486,9 +503,10 @@
 
     if src:
         commonbase = repo[src].ancestor(repo[dest])
+        samebranch = repo[src].branch() == repo[dest].branch()
         if commonbase == repo[src]:
             raise util.Abort(_('source is ancestor of destination'))
-        if commonbase == repo[dest]:
+        if samebranch and commonbase == repo[dest]:
             raise util.Abort(_('source is descendant of destination'))
         source = repo[src].rev()
         if detach:
@@ -535,7 +553,7 @@
             ui.debug('--update and --rebase are not compatible, ignoring '
                      'the update flag\n')
 
-        cmdutil.bail_if_changed(repo)
+        cmdutil.bailifchanged(repo)
         revsprepull = len(repo)
         origpostincoming = commands.postincoming
         def _dummy(*args, **kwargs):
@@ -554,35 +572,14 @@
                 # there was nothing to rebase we force an update
                 hg.update(repo, dest)
     else:
+        if opts.get('tool'):
+            raise util.Abort(_('--tool can only be used with --rebase'))
         orig(ui, repo, *args, **opts)
 
 def uisetup(ui):
     'Replace pull with a decorator to provide --rebase option'
     entry = extensions.wrapcommand(commands.table, 'pull', pullrebase)
     entry[1].append(('', 'rebase', None,
-                     _("rebase working directory to branch head"))
-)
-
-cmdtable = {
-"rebase":
-        (rebase,
-        [
-        ('s', 'source', '',
-         _('rebase from the specified changeset'), _('REV')),
-        ('b', 'base', '',
-         _('rebase from the base of the specified changeset '
-           '(up to greatest common ancestor of base and dest)'),
-         _('REV')),
-        ('d', 'dest', '',
-         _('rebase onto the specified changeset'), _('REV')),
-        ('', 'collapse', False, _('collapse the rebased changesets')),
-        ('', 'keep', False, _('keep original changesets')),
-        ('', 'keepbranches', False, _('keep original branch names')),
-        ('', 'detach', False, _('force detaching of source from its original '
-                                'branch')),
-        ('c', 'continue', False, _('continue an interrupted rebase')),
-        ('a', 'abort', False, _('abort an interrupted rebase'))] +
-         templateopts,
-        _('hg rebase [-s REV | -b REV] [-d REV] [options]\n'
-          'hg rebase {-a|-c}'))
-}
+                     _("rebase working directory to branch head")))
+    entry[1].append(('t', 'tool', '',
+                     _("specify merge tool for rebase")))
--- a/hgext/record.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/hgext/record.py	Sat Jun 18 17:03:01 2011 -0500
@@ -12,8 +12,20 @@
 from mercurial import util
 import copy, cStringIO, errno, os, re, shutil, tempfile
 
+cmdtable = {}
+command = cmdutil.command(cmdtable)
+
 lines_re = re.compile(r'@@ -(\d+),(\d+) \+(\d+),(\d+) @@\s*(.*)')
 
+diffopts = [
+    ('w', 'ignore-all-space', False,
+     _('ignore white space when comparing lines')),
+    ('b', 'ignore-space-change', None,
+     _('ignore changes in the amount of white space')),
+    ('B', 'ignore-blank-lines', None,
+     _('ignore changes whose lines are all blank')),
+]
+
 def scanpatch(fp):
     """like patch.iterhunks, but yield different events
 
@@ -324,10 +336,12 @@
         for i, chunk in enumerate(h.hunks):
             if skipfile is None and skipall is None:
                 chunk.pretty(ui)
-            msg = (total == 1
-                   and (_('record this change to %r?') % chunk.filename())
-                   or (_('record change %d/%d to %r?') %
-                       (pos - len(h.hunks) + i, total, chunk.filename())))
+            if total == 1:
+                msg = _('record this change to %r?') % chunk.filename()
+            else:
+                idx = pos - len(h.hunks) + i
+                msg = _('record change %d/%d to %r?') % (idx, total,
+                                                         chunk.filename())
             r, skipfile, skipall = prompt(skipfile, skipall, msg)
             if r:
                 if fixoffset:
@@ -339,6 +353,10 @@
     return sum([h for h in applied.itervalues()
                if h[0].special() or len(h) > 1], [])
 
+@command("record",
+         # same options as commit + white space diff options
+         commands.table['^commit|ci'][1][:] + diffopts,
+          _('hg record [OPTION]... [FILE]...'))
 def record(ui, repo, *pats, **opts):
     '''interactively select changes to commit
 
@@ -366,8 +384,20 @@
 
     This command is not available when committing a merge.'''
 
-    dorecord(ui, repo, commands.commit, *pats, **opts)
+    dorecord(ui, repo, commands.commit, 'commit', False, *pats, **opts)
+
+def qrefresh(ui, repo, *pats, **opts):
+    mq = extensions.find('mq')
 
+    def committomq(ui, repo, *pats, **opts):
+        # At this point the working copy contains only changes that
+        # were accepted. All other changes were reverted.
+        # We can't pass *pats here since qrefresh will undo all other
+        # changed files in the patch that aren't in pats.
+        mq.refresh(ui, repo, **opts)
+
+    # backup all changed files
+    dorecord(ui, repo, committomq, 'qrefresh', True, *pats, **opts)
 
 def qrecord(ui, repo, patch, *pats, **opts):
     '''interactively record a new patch
@@ -381,15 +411,18 @@
     except KeyError:
         raise util.Abort(_("'mq' extension not loaded"))
 
+    repo.mq.checkpatchname(patch)
+
     def committomq(ui, repo, *pats, **opts):
+        opts['checkname'] = False
         mq.new(ui, repo, patch, *pats, **opts)
 
-    dorecord(ui, repo, committomq, *pats, **opts)
-
+    dorecord(ui, repo, committomq, 'qnew', False, *pats, **opts)
 
-def dorecord(ui, repo, commitfunc, *pats, **opts):
+def dorecord(ui, repo, commitfunc, cmdsuggest, backupall, *pats, **opts):
     if not ui.interactive():
-        raise util.Abort(_('running non-interactively, use commit instead'))
+        raise util.Abort(_('running non-interactively, use %s instead') %
+                         cmdsuggest)
 
     def recordfunc(ui, repo, message, match, opts):
         """This is generic record driver.
@@ -412,7 +445,10 @@
                                '(use "hg commit" instead)'))
 
         changes = repo.status(match=match)[:3]
-        diffopts = mdiff.diffopts(git=True, nodates=True)
+        diffopts = mdiff.diffopts(git=True, nodates=True,
+                                  ignorews=opts.get('ignore_all_space'),
+                                  ignorewsamount=opts.get('ignore_space_change'),
+                                  ignoreblanklines=opts.get('ignore_blank_lines'))
         chunks = patch.diff(repo, changes=changes, opts=diffopts)
         fp = cStringIO.StringIO()
         fp.write(''.join(chunks))
@@ -438,18 +474,22 @@
         modified = set(changes[0])
 
         # 2. backup changed files, so we can restore them in the end
+        if backupall:
+            tobackup = changed
+        else:
+            tobackup = [f for f in newfiles if f in modified]
+
         backups = {}
-        backupdir = repo.join('record-backups')
-        try:
-            os.mkdir(backupdir)
-        except OSError, err:
-            if err.errno != errno.EEXIST:
-                raise
+        if tobackup:
+            backupdir = repo.join('record-backups')
+            try:
+                os.mkdir(backupdir)
+            except OSError, err:
+                if err.errno != errno.EEXIST:
+                    raise
         try:
             # backup continues
-            for f in newfiles:
-                if f not in modified:
-                    continue
+            for f in tobackup:
                 fd, tmpname = tempfile.mkstemp(prefix=f.replace('/', '_')+'.',
                                                dir=backupdir)
                 os.close(fd)
@@ -467,7 +507,7 @@
 
             # 3a. apply filtered patch to clean repo  (clean)
             if backups:
-                hg.revert(repo, repo.dirstate.parents()[0],
+                hg.revert(repo, repo.dirstate.p1(),
                           lambda key: key in backups)
 
             # 3b. (apply)
@@ -475,10 +515,7 @@
                 try:
                     ui.debug('applying patch\n')
                     ui.debug(fp.getvalue())
-                    pfiles = {}
-                    patch.internalpatch(fp, ui, 1, repo.root, files=pfiles,
-                                        eolmode=None)
-                    cmdutil.updatedir(ui, repo, pfiles)
+                    patch.internalpatch(ui, repo, fp, 1, eolmode=None)
                 except patch.PatchError, err:
                     raise util.Abort(str(err))
             del fp
@@ -513,7 +550,8 @@
                     # writing it.
                     shutil.copystat(tmpname, repo.wjoin(realname))
                     os.unlink(tmpname)
-                os.rmdir(backupdir)
+                if tobackup:
+                    os.rmdir(backupdir)
             except OSError:
                 pass
 
@@ -529,12 +567,9 @@
     finally:
         ui.write = oldwrite
 
-cmdtable = {
-    "record":
-        (record, commands.table['^commit|ci'][1], # same options as commit
-         _('hg record [OPTION]... [FILE]...')),
-}
-
+cmdtable["qrecord"] = \
+    (qrecord, [], # placeholder until mq is available
+     _('hg qrecord [OPTION]... PATCH [FILE]...'))
 
 def uisetup(ui):
     try:
@@ -542,11 +577,22 @@
     except KeyError:
         return
 
-    qcmdtable = {
-    "qrecord":
-        (qrecord, mq.cmdtable['^qnew'][1], # same options as qnew
-         _('hg qrecord [OPTION]... PATCH [FILE]...')),
-    }
+    cmdtable["qrecord"] = \
+        (qrecord,
+         # same options as qnew, but copy them so we don't get
+         # -i/--interactive for qrecord and add white space diff options
+         mq.cmdtable['^qnew'][1][:] + diffopts,
+         _('hg qrecord [OPTION]... PATCH [FILE]...'))
 
-    cmdtable.update(qcmdtable)
+    _wrapcmd('qnew', mq.cmdtable, qrecord, _("interactively record a new patch"))
+    _wrapcmd('qrefresh', mq.cmdtable, qrefresh,
+             _("interactively select changes to refresh"))
 
+def _wrapcmd(cmd, table, wrapfn, msg):
+    '''wrap the command'''
+    def wrapper(orig, *args, **kwargs):
+        if kwargs['interactive']:
+            return wrapfn(*args, **kwargs)
+        return orig(*args, **kwargs)
+    entry = extensions.wrapcommand(table, cmd, wrapper)
+    entry[1].append(('i', 'interactive', None, msg))
--- a/hgext/relink.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/hgext/relink.py	Sat Jun 18 17:03:01 2011 -0500
@@ -38,9 +38,8 @@
     """
     if not hasattr(util, 'samefile') or not hasattr(util, 'samedevice'):
         raise util.Abort(_('hardlinks are not supported on this system'))
-    src = hg.repository(
-        hg.remoteui(repo, opts),
-        ui.expandpath(origin or 'default-relink', origin or 'default'))
+    src = hg.repository(ui, 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))
@@ -132,7 +131,7 @@
         bak = dst + '.bak'
         os.rename(dst, bak)
         try:
-            util.os_link(src, dst)
+            util.oslink(src, dst)
         except OSError:
             os.rename(bak, dst)
             raise
@@ -172,8 +171,8 @@
 
     ui.progress(_('relinking'), None)
 
-    ui.status(_('relinked %d files (%d bytes reclaimed)\n') %
-              (relinked, savedbytes))
+    ui.status(_('relinked %d files (%s reclaimed)\n') %
+              (relinked, util.bytecount(savedbytes)))
 
 cmdtable = {
     'relink': (
--- a/hgext/schemes.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/hgext/schemes.py	Sat Jun 18 17:03:01 2011 -0500
@@ -40,8 +40,9 @@
 same name.
 """
 
-import re
-from mercurial import hg, templater
+import os, re
+from mercurial import extensions, hg, templater, util
+from mercurial.i18n import _
 
 
 class ShortRepository(object):
@@ -58,6 +59,7 @@
         return '<ShortRepository: %s>' % self.scheme
 
     def instance(self, ui, url, create):
+        # Should this use urlmod.url(), or is manual parsing better?
         url = url.split('://', 1)[1]
         parts = url.split('/', self.parts)
         if len(parts) > self.parts:
@@ -67,7 +69,13 @@
             tail = ''
         context = dict((str(i + 1), v) for i, v in enumerate(parts))
         url = ''.join(self.templater.process(self.url, context)) + tail
-        return hg._lookup(url).instance(ui, url, create)
+        return hg._peerlookup(url).instance(ui, url, create)
+
+def hasdriveletter(orig, path):
+    for scheme in schemes:
+        if path.startswith(scheme + ':'):
+            return False
+    return orig(path)
 
 schemes = {
     'py': 'http://hg.python.org/',
@@ -81,4 +89,10 @@
     schemes.update(dict(ui.configitems('schemes')))
     t = templater.engine(lambda x: x)
     for scheme, url in schemes.items():
+        if (os.name == 'nt' and len(scheme) == 1 and scheme.isalpha()
+            and os.path.exists('%s:\\' % scheme)):
+            raise util.Abort(_('custom scheme %s:// conflicts with drive '
+                               'letter %s:\\\n') % (scheme, scheme.upper()))
         hg.schemes[scheme] = ShortRepository(url, scheme, t)
+
+    extensions.wrapfunction(util, 'hasdriveletter', hasdriveletter)
--- a/hgext/transplant.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/hgext/transplant.py	Sat Jun 18 17:03:01 2011 -0500
@@ -15,9 +15,13 @@
 
 from mercurial.i18n import _
 import os, tempfile
-from mercurial import bundlerepo, cmdutil, hg, merge, match
-from mercurial import patch, revlog, util, error
-from mercurial import revset
+from mercurial.node import short
+from mercurial import bundlerepo, hg, merge, match
+from mercurial import patch, revlog, scmutil, util, error, cmdutil
+from mercurial import revset, templatekw
+
+cmdtable = {}
+command = cmdutil.command(cmdtable)
 
 class transplantentry(object):
     def __init__(self, lnode, rnode):
@@ -31,7 +35,7 @@
         self.opener = opener
 
         if not opener:
-            self.opener = util.opener(self.path)
+            self.opener = scmutil.opener(self.path)
         self.transplants = {}
         self.dirty = False
         self.read()
@@ -39,7 +43,7 @@
     def read(self):
         abspath = os.path.join(self.path, self.transplantfile)
         if self.transplantfile and os.path.exists(abspath):
-            for line in self.opener(self.transplantfile).read().splitlines():
+            for line in self.opener.read(self.transplantfile).splitlines():
                 lnode, rnode = map(revlog.bin, line.split(':'))
                 list = self.transplants.setdefault(rnode, [])
                 list.append(transplantentry(lnode, rnode))
@@ -74,7 +78,7 @@
     def __init__(self, ui, repo):
         self.ui = ui
         self.path = repo.join('transplant')
-        self.opener = util.opener(self.path)
+        self.opener = scmutil.opener(self.path)
         self.transplants = transplants(self.path, 'transplants',
                                        opener=self.opener)
 
@@ -107,7 +111,7 @@
             lock = repo.lock()
             for rev in revs:
                 node = revmap[rev]
-                revstr = '%s:%s' % (rev, revlog.short(node))
+                revstr = '%s:%s' % (rev, short(node))
 
                 if self.applied(repo, node, p1):
                     self.ui.warn(_('skipping already applied revision %s\n') %
@@ -140,7 +144,7 @@
 
                 if parents[1] != revlog.nullid:
                     self.ui.note(_('skipping merge changeset %s:%s\n')
-                                 % (rev, revlog.short(node)))
+                                 % (rev, short(node)))
                     patchfile = None
                 else:
                     fd, patchfile = tempfile.mkstemp(prefix='hg-transplant-')
@@ -160,11 +164,11 @@
                                           filter=opts.get('filter'))
                         if n and domerge:
                             self.ui.status(_('%s merged at %s\n') % (revstr,
-                                      revlog.short(n)))
+                                      short(n)))
                         elif n:
                             self.ui.status(_('%s transplanted to %s\n')
-                                           % (revlog.short(node),
-                                              revlog.short(n)))
+                                           % (short(node),
+                                              short(n)))
                     finally:
                         if patchfile:
                             os.unlink(patchfile)
@@ -177,12 +181,11 @@
             lock.release()
             wlock.release()
 
-    def filter(self, filter, changelog, patchfile):
+    def filter(self, filter, node, changelog, patchfile):
         '''arbitrarily rewrite changeset before applying it'''
 
         self.ui.status(_('filtering %s\n') % patchfile)
         user, date, msg = (changelog[1], changelog[2], changelog[4])
-
         fd, headerfile = tempfile.mkstemp(prefix='hg-transplant-')
         fp = os.fdopen(fd, 'w')
         fp.write("# HG changeset patch\n")
@@ -194,7 +197,9 @@
         try:
             util.system('%s %s %s' % (filter, util.shellquote(headerfile),
                                    util.shellquote(patchfile)),
-                        environ={'HGUSER': changelog[1]},
+                        environ={'HGUSER': changelog[1],
+                                 'HGREVISION': revlog.hex(node),
+                                 },
                         onerr=util.Abort, errprefix=_('filter failed'))
             user, date, msg = self.parselog(file(headerfile))[1:4]
         finally:
@@ -209,34 +214,30 @@
         date = "%d %d" % (time, timezone)
         extra = {'transplant_source': node}
         if filter:
-            (user, date, message) = self.filter(filter, cl, patchfile)
+            (user, date, message) = self.filter(filter, node, cl, patchfile)
 
         if log:
             # we don't translate messages inserted into commits
             message += '\n(transplanted from %s)' % revlog.hex(node)
 
-        self.ui.status(_('applying %s\n') % revlog.short(node))
+        self.ui.status(_('applying %s\n') % short(node))
         self.ui.note('%s %s\n%s\n' % (user, date, message))
 
         if not patchfile and not merge:
             raise util.Abort(_('can only omit patchfile if merging'))
         if patchfile:
             try:
-                files = {}
-                try:
-                    patch.patch(patchfile, self.ui, cwd=repo.root,
-                                files=files, eolmode=None)
-                    if not files:
-                        self.ui.warn(_('%s: empty changeset')
-                                     % revlog.hex(node))
-                        return None
-                finally:
-                    files = cmdutil.updatedir(self.ui, repo, files)
+                files = set()
+                patch.patch(self.ui, repo, patchfile, files=files, eolmode=None)
+                files = list(files)
+                if not files:
+                    self.ui.warn(_('%s: empty changeset') % revlog.hex(node))
+                    return None
             except Exception, inst:
                 seriespath = os.path.join(self.path, 'series')
                 if os.path.exists(seriespath):
                     os.unlink(seriespath)
-                p1 = repo.dirstate.parents()[0]
+                p1 = repo.dirstate.p1()
                 p2 = node
                 self.log(user, date, message, p1, p2, merge=merge)
                 self.ui.write(str(inst) + '\n')
@@ -270,8 +271,8 @@
         '''recover last transaction and apply remaining changesets'''
         if os.path.exists(os.path.join(self.path, 'journal')):
             n, node = self.recover(repo)
-            self.ui.status(_('%s transplanted as %s\n') % (revlog.short(node),
-                                                           revlog.short(n)))
+            self.ui.status(_('%s transplanted as %s\n') % (short(node),
+                                                           short(n)))
         seriespath = os.path.join(self.path, 'series')
         if not os.path.exists(seriespath):
             self.transplants.write()
@@ -317,7 +318,7 @@
         nodes = []
         merges = []
         cur = nodes
-        for line in self.opener('series').read().splitlines():
+        for line in self.opener.read('series').splitlines():
             if line.startswith('# Merges'):
                 cur = merges
                 continue
@@ -345,6 +346,8 @@
         message = []
         node = revlog.nullid
         inmsg = False
+        user = None
+        date = None
         for line in fp.read().splitlines():
             if inmsg:
                 message.append(line)
@@ -359,6 +362,8 @@
             elif not line.startswith('# '):
                 inmsg = True
                 message.append(line)
+        if None in (user, date):
+            raise util.Abort(_("filter corrupted changeset (no user or date)"))
         return (node, user, date, '\n'.join(message), parents)
 
     def log(self, user, date, message, p1, p2, merge=False):
@@ -448,6 +453,20 @@
     displayer.close()
     return (transplants, merges)
 
+@command('transplant',
+    [('s', 'source', '', _('pull patches from REPO'), _('REPO')),
+    ('b', 'branch', [],
+     _('pull patches from branch BRANCH'), _('BRANCH')),
+    ('a', 'all', None, _('pull all changesets up to BRANCH')),
+    ('p', 'prune', [], _('skip over REV'), _('REV')),
+    ('m', 'merge', [], _('merge at REV'), _('REV')),
+    ('', 'log', None, _('append transplant info to log message')),
+    ('c', 'continue', None, _('continue last transplant session '
+                              'after repair')),
+    ('', 'filter', '',
+     _('filter changesets through command'), _('CMD'))],
+    _('hg transplant [-s REPO] [-b BRANCH [-a]] [-p REV] '
+      '[-m REV] [REV]...'))
 def transplant(ui, repo, *revs, **opts):
     '''transplant changesets from another branch
 
@@ -489,10 +508,8 @@
     and then resume where you left off by calling :hg:`transplant
     --continue/-c`.
     '''
-    def incwalk(repo, incoming, branches, match=util.always):
-        if not branches:
-            branches = None
-        for node in repo.changelog.nodesbetween(incoming, branches)[0]:
+    def incwalk(repo, csets, match=util.always):
+        for node in csets:
             if match(node):
                 yield node
 
@@ -542,15 +559,16 @@
         if m or a or r or d:
             raise util.Abort(_('outstanding local changes'))
 
-    bundle = None
-    source = opts.get('source')
-    if source:
-        sourcerepo = ui.expandpath(source)
-        source = hg.repository(ui, sourcerepo)
-        source, incoming, bundle = bundlerepo.getremotechanges(ui, repo, source,
-                                    force=True)
+    sourcerepo = opts.get('source')
+    if sourcerepo:
+        source = hg.peer(ui, opts, ui.expandpath(sourcerepo))
+        branches = map(source.lookup, opts.get('branch', ()))
+        source, csets, cleanupfn = bundlerepo.getremotechanges(ui, repo, source,
+                                    onlyheads=branches, force=True)
     else:
         source = repo
+        branches = map(source.lookup, opts.get('branch', ()))
+        cleanupfn = None
 
     try:
         if opts.get('continue'):
@@ -560,20 +578,18 @@
         tf = tp.transplantfilter(repo, source, p1)
         if opts.get('prune'):
             prune = [source.lookup(r)
-                     for r in cmdutil.revrange(source, opts.get('prune'))]
+                     for r in scmutil.revrange(source, opts.get('prune'))]
             matchfn = lambda x: tf(x) and x not in prune
         else:
             matchfn = tf
-        branches = map(source.lookup, opts.get('branch', ()))
         merges = map(source.lookup, opts.get('merge', ()))
         revmap = {}
         if revs:
-            for r in cmdutil.revrange(source, revs):
+            for r in scmutil.revrange(source, revs):
                 revmap[int(r)] = source.lookup(r)
         elif opts.get('all') or not merges:
             if source != repo:
-                alltransplants = incwalk(source, incoming, branches,
-                                         match=matchfn)
+                alltransplants = incwalk(source, csets, match=matchfn)
             else:
                 alltransplants = transplantwalk(source, p1, branches,
                                                 match=matchfn)
@@ -589,9 +605,8 @@
 
         tp.apply(repo, source, revmap, merges, opts)
     finally:
-        if bundle:
-            source.close()
-            os.unlink(bundle)
+        if cleanupfn:
+            cleanupfn()
 
 def revsettransplanted(repo, subset, x):
     """``transplanted([set])``
@@ -601,35 +616,17 @@
       s = revset.getset(repo, subset, x)
     else:
       s = subset
-    cs = set()
-    for r in xrange(0, len(repo)):
-      if repo[r].extra().get('transplant_source'):
-        cs.add(r)
-    return [r for r in s if r in cs]
+    return [r for r in s if repo[r].extra().get('transplant_source')]
+
+def kwtransplanted(repo, ctx, **args):
+    """:transplanted: String. The node identifier of the transplanted
+    changeset if any."""
+    n = ctx.extra().get('transplant_source')
+    return n and revlog.hex(n) or ''
 
 def extsetup(ui):
     revset.symbols['transplanted'] = revsettransplanted
-
-cmdtable = {
-    "transplant":
-        (transplant,
-         [('s', 'source', '',
-           _('pull patches from REPO'), _('REPO')),
-          ('b', 'branch', [],
-           _('pull patches from branch BRANCH'), _('BRANCH')),
-          ('a', 'all', None, _('pull all changesets up to BRANCH')),
-          ('p', 'prune', [],
-           _('skip over REV'), _('REV')),
-          ('m', 'merge', [],
-           _('merge at REV'), _('REV')),
-          ('', 'log', None, _('append transplant info to log message')),
-          ('c', 'continue', None, _('continue last transplant session '
-                                    'after repair')),
-          ('', 'filter', '',
-           _('filter changesets through command'), _('CMD'))],
-         _('hg transplant [-s REPO] [-b BRANCH [-a]] [-p REV] '
-           '[-m REV] [REV]...'))
-}
+    templatekw.keywords['transplanted'] = kwtransplanted
 
 # tell hggettext to extract docstrings from these functions:
-i18nfunctions = [revsettransplanted]
+i18nfunctions = [revsettransplanted, kwtransplanted]
--- a/hgext/zeroconf/Zeroconf.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/hgext/zeroconf/Zeroconf.py	Sat Jun 18 17:03:01 2011 -0500
@@ -237,14 +237,14 @@
 		"""Class accessor"""
 		try:
 			return _CLASSES[clazz]
-		except:
+		except KeyError:
 			return "?(%s)" % (clazz)
 
 	def getType(self, type):
 		"""Type accessor"""
 		try:
 			return _TYPES[type]
-		except:
+		except KeyError:
 			return "?(%s)" % (type)
 
 	def toString(self, hdr, other):
@@ -360,7 +360,7 @@
 		"""String representation"""
 		try:
 			return socket.inet_ntoa(self.address)
-		except:
+		except Exception:
 			return self.address
 
 class DNSHinfo(DNSRecord):
@@ -591,7 +591,7 @@
 		next = -1
 		first = off
 
-		while 1:
+		while True:
 			len = ord(self.data[off])
 			off += 1
 			if len == 0:
@@ -790,7 +790,7 @@
 		"""Adds an entry"""
 		try:
 			list = self.cache[entry.key]
-		except:
+		except KeyError:
 			list = self.cache[entry.key] = []
 		list.append(entry)
 
@@ -799,7 +799,7 @@
 		try:
 			list = self.cache[entry.key]
 			list.remove(entry)
-		except:
+		except KeyError:
 			pass
 
 	def get(self, entry):
@@ -808,7 +808,7 @@
 		try:
 			list = self.cache[entry.key]
 			return list[list.index(entry)]
-		except:
+		except (KeyError, ValueError):
 			return None
 
 	def getByDetails(self, name, type, clazz):
@@ -821,7 +821,7 @@
 		"""Returns a list of entries whose key matches the name."""
 		try:
 			return self.cache[name]
-		except:
+		except KeyError:
 			return []
 
 	def entries(self):
@@ -829,7 +829,7 @@
 		def add(x, y): return x+y
 		try:
 			return reduce(add, self.cache.values())
-		except:
+		except Exception:
 			return []
 
 
@@ -869,10 +869,10 @@
 					for socket in rr:
 						try:
 							self.readers[socket].handle_read()
-						except:
+						except Exception:
 							if not globals()['_GLOBAL_DONE']:
 								traceback.print_exc()
-				except:
+				except Exception:
 					pass
 
 	def getReaders(self):
@@ -939,7 +939,7 @@
 		self.start()
 
 	def run(self):
-		while 1:
+		while True:
 			self.zeroconf.wait(10 * 1000)
 			if globals()['_GLOBAL_DONE']:
 				return
@@ -988,7 +988,7 @@
 					callback = lambda x: self.listener.removeService(x, self.type, record.alias)
 					self.list.append(callback)
 					return
-			except:
+			except Exception:
 				if not expired:
 					self.services[record.alias.lower()] = record
 					callback = lambda x: self.listener.addService(x, self.type, record.alias)
@@ -1003,7 +1003,7 @@
 		self.zeroconf.notifyAll()
 
 	def run(self):
-		while 1:
+		while True:
 			event = None
 			now = currentTimeMillis()
 			if len(self.list) == 0 and self.nextTime > now:
@@ -1117,7 +1117,7 @@
 					result[key] = value
 
 			self.properties = result
-		except:
+		except Exception:
 			traceback.print_exc()
 			self.properties = None
 
@@ -1255,7 +1255,7 @@
 		try:
 			self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
 			self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
-		except:
+		except Exception:
 			# SO_REUSEADDR should be equivalent to SO_REUSEPORT for
 			# multicast UDP sockets (p 731, "TCP/IP Illustrated,
 			# Volume 2"), but some BSD-derived systems require
@@ -1270,7 +1270,7 @@
 		self.socket.setsockopt(socket.SOL_IP, socket.IP_MULTICAST_LOOP, 1)
 		try:
 			self.socket.bind(self.group)
-		except:
+		except Exception:
 			# Some versions of linux raise an exception even though
 			# the SO_REUSE* options have been set, so ignore it
 			#
@@ -1370,7 +1370,7 @@
 				self.servicetypes[info.type]-=1
 			else:
 				del self.servicetypes[info.type]
-		except:
+		except KeyError:
 			pass
 		now = currentTimeMillis()
 		nextTime = now
@@ -1455,7 +1455,7 @@
 		try:
 			self.listeners.remove(listener)
 			self.notifyAll()
-		except:
+		except Exception:
 			pass
 
 	def updateRecord(self, now, rec):
@@ -1528,7 +1528,7 @@
 						out.addAnswer(msg, DNSText(question.name, _TYPE_TXT, _CLASS_IN | _CLASS_UNIQUE, _DNS_TTL, service.text))
 					if question.type == _TYPE_SRV:
 						out.addAdditionalAnswer(DNSAddress(service.server, _TYPE_A, _CLASS_IN | _CLASS_UNIQUE, _DNS_TTL, service.address))
-				except:
+				except Exception:
 					traceback.print_exc()
 
 		if out is not None and out.answers:
@@ -1541,7 +1541,7 @@
 		#temp = DNSIncoming(out.packet())
 		try:
 			self.socket.sendto(out.packet(), 0, (addr, port))
-		except:
+		except Exception:
 			# Ignore this, it may be a temporary loss of network connection
 			pass
 
--- a/i18n/da.po	Wed Jun 01 16:32:48 2011 -0500
+++ b/i18n/da.po	Sat Jun 18 17:03:01 2011 -0500
@@ -17,8 +17,8 @@
 msgstr ""
 "Project-Id-Version: Mercurial\n"
 "Report-Msgid-Bugs-To: <mercurial-devel@selenic.com>\n"
-"POT-Creation-Date: 2011-03-16 17:41+0100\n"
-"PO-Revision-Date: 2011-03-16 17:42+0100\n"
+"POT-Creation-Date: 2011-04-19 09:32+0200\n"
+"PO-Revision-Date: 2011-04-19 09:45+0200\n"
 "Last-Translator: <mg@lazybytes.net>\n"
 "Language-Team: Danish\n"
 "Language: Danish\n"
@@ -294,140 +294,231 @@
 
 msgid ""
 "This hook extension adds comments on bugs in Bugzilla when changesets\n"
-"that refer to bugs by Bugzilla ID are seen. The hook does not change\n"
-"bug status."
-msgstr ""
-
-msgid ""
-"The hook updates the Bugzilla database directly. Only Bugzilla\n"
-"installations using MySQL are supported."
-msgstr ""
-
-msgid ""
-"The hook relies on a Bugzilla script to send bug change notification\n"
-"emails. That script changes between Bugzilla versions; the\n"
-"'processmail' script used prior to 2.18 is replaced in 2.18 and\n"
-"subsequent versions by 'config/sendbugmail.pl'. Note that these will\n"
-"be run by Mercurial as the user pushing the change; you will need to\n"
-"ensure the Bugzilla install file permissions are set appropriately."
-msgstr ""
-
-msgid ""
-"The extension is configured through three different configuration\n"
-"sections. These keys are recognized in the [bugzilla] section:"
-msgstr ""
-
-msgid ""
-"host\n"
-"  Hostname of the MySQL server holding the Bugzilla database."
-msgstr ""
-
-msgid ""
-"db\n"
-"  Name of the Bugzilla database in MySQL. Default 'bugs'."
-msgstr ""
-
-msgid ""
-"user\n"
-"  Username to use to access MySQL server. Default 'bugs'."
-msgstr ""
-
-msgid ""
-"password\n"
+"that refer to bugs by Bugzilla ID are seen. The comment is formatted using\n"
+"the Mercurial template mechanism."
+msgstr ""
+
+msgid "The hook does not change bug status."
+msgstr ""
+
+msgid "Three basic modes of access to Bugzilla are provided:"
+msgstr ""
+
+msgid ""
+"1. Access via the Bugzilla XMLRPC interface. Requires Bugzilla 3.4 or later."
+msgstr ""
+
+msgid ""
+"2. Check data via the Bugzilla XMLRPC interface and submit bug change\n"
+"   via email to Bugzilla email interface. Requires Bugzilla 3.4 or later."
+msgstr ""
+
+msgid ""
+"3. Writing directly to the Bugzilla database. Only Bugzilla installations\n"
+"   using MySQL are supported. Requires Python MySQLdb."
+msgstr ""
+
+msgid ""
+"Writing directly to the database is susceptible to schema changes, and\n"
+"relies on a Bugzilla contrib script to send out bug change\n"
+"notification emails. This script runs as the user running Mercurial,\n"
+"must be run on the host with the Bugzilla install, and requires\n"
+"permission to read Bugzilla configuration details and the necessary\n"
+"MySQL user and password to have full access rights to the Bugzilla\n"
+"database. For these reasons this access mode is now considered\n"
+"deprecated, and will not be updated for new Bugzilla versions going\n"
+"forward."
+msgstr ""
+
+msgid ""
+"Access via XMLRPC needs a Bugzilla username and password to be specified\n"
+"in the configuration. Comments are added under that username. Since the\n"
+"configuration must be readable by all Mercurial users, it is recommended\n"
+"that the rights of that user are restricted in Bugzilla to the minimum\n"
+"necessary to add comments."
+msgstr ""
+
+msgid ""
+"Access via XMLRPC/email uses XMLRPC to query Bugzilla, but sends\n"
+"email to the Bugzilla email interface to submit comments to bugs.\n"
+"The From: address in the email is set to the email address of the Mercurial\n"
+"user, so the comment appears to come from the Mercurial user. In the event\n"
+"that the Mercurial user email is not recognised by Bugzilla as a Bugzilla\n"
+"user, the email associated with the Bugzilla username used to log into\n"
+"Bugzilla is used instead as the source of the comment."
+msgstr ""
+
+msgid "Configuration items common to all access modes:"
+msgstr ""
+
+msgid ""
+"bugzilla.version\n"
+"  This access type to use. Values recognised are:"
+msgstr ""
+
+msgid ""
+"  :``xmlrpc``:       Bugzilla XMLRPC interface.\n"
+"  :``xmlrpc+email``: Bugzilla XMLRPC and email interfaces.\n"
+"  :``3.0``:          MySQL access, Bugzilla 3.0 and later.\n"
+"  :``2.18``:         MySQL access, Bugzilla 2.18 and up to but not\n"
+"                     including 3.0.\n"
+"  :``2.16``:         MySQL access, Bugzilla 2.16 and up to but not\n"
+"                     including 2.18."
+msgstr ""
+
+msgid ""
+"bugzilla.regexp\n"
+"  Regular expression to match bug IDs in changeset commit message.\n"
+"  Must contain one \"()\" group. The default expression matches ``Bug\n"
+"  1234``, ``Bug no. 1234``, ``Bug number 1234``, ``Bugs 1234,5678``,\n"
+"  ``Bug 1234 and 5678`` and variations thereof. Matching is case\n"
+"  insensitive."
+msgstr ""
+
+msgid ""
+"bugzilla.style\n"
+"  The style file to use when formatting comments."
+msgstr ""
+
+msgid ""
+"bugzilla.template\n"
+"  Template to use when formatting comments. Overrides style if\n"
+"  specified. In addition to the usual Mercurial keywords, the\n"
+"  extension specifies:"
+msgstr ""
+
+msgid ""
+"  :``{bug}``:     The Bugzilla bug ID.\n"
+"  :``{root}``:    The full pathname of the Mercurial repository.\n"
+"  :``{webroot}``: Stripped pathname of the Mercurial repository.\n"
+"  :``{hgweb}``:   Base URL for browsing Mercurial repositories."
+msgstr ""
+
+msgid ""
+"  Default ``changeset {node|short} in repo {root} refers to bug\n"
+"  {bug}.\\ndetails:\\n\\t{desc|tabindent}``"
+msgstr ""
+
+msgid ""
+"bugzilla.strip\n"
+"  The number of path separator characters to strip from the front of\n"
+"  the Mercurial repository path (``{root}`` in templates) to produce\n"
+"  ``{webroot}``. For example, a repository with ``{root}``\n"
+"  ``/var/local/my-project`` with a strip of 2 gives a value for\n"
+"  ``{webroot}`` of ``my-project``. Default 0."
+msgstr ""
+
+msgid ""
+"web.baseurl\n"
+"  Base URL for browsing Mercurial repositories. Referenced from\n"
+"  templates as ``{hgweb}``."
+msgstr ""
+
+msgid "Configuration items common to XMLRPC+email and MySQL access modes:"
+msgstr ""
+
+msgid ""
+"bugzilla.usermap\n"
+"  Path of file containing Mercurial committer email to Bugzilla user email\n"
+"  mappings. If specified, the file should contain one mapping per\n"
+"  line::"
+msgstr ""
+
+msgid "    committer = Bugzilla user"
+msgstr ""
+
+msgid "  See also the ``[usermap]`` section."
+msgstr ""
+
+msgid ""
+"The ``[usermap]`` section is used to specify mappings of Mercurial\n"
+"committer email to Bugzilla user email. See also ``bugzilla.usermap``.\n"
+"Contains entries of the form ``committer = Bugzilla user``."
+msgstr ""
+
+msgid "XMLRPC access mode configuration:"
+msgstr ""
+
+msgid ""
+"bugzilla.bzurl\n"
+"  The base URL for the Bugzilla installation.\n"
+"  Default ``http://localhost/bugzilla``."
+msgstr ""
+
+msgid ""
+"bugzilla.user\n"
+"  The username to use to log into Bugzilla via XMLRPC. Default\n"
+"  ``bugs``."
+msgstr ""
+
+msgid ""
+"bugzilla.password\n"
+"  The password for Bugzilla login."
+msgstr ""
+
+msgid ""
+"XMLRPC+email access mode uses the XMLRPC access mode configuration items,\n"
+"and also:"
+msgstr ""
+
+msgid ""
+"bugzilla.bzemail\n"
+"  The Bugzilla email address."
+msgstr ""
+
+msgid ""
+"In addition, the Mercurial email settings must be configured. See the\n"
+"documentation in hgrc(5), sections ``[email]`` and ``[smtp]``."
+msgstr ""
+
+msgid "MySQL access mode configuration:"
+msgstr ""
+
+msgid ""
+"bugzilla.host\n"
+"  Hostname of the MySQL server holding the Bugzilla database.\n"
+"  Default ``localhost``."
+msgstr ""
+
+msgid ""
+"bugzilla.db\n"
+"  Name of the Bugzilla database in MySQL. Default ``bugs``."
+msgstr ""
+
+msgid ""
+"bugzilla.user\n"
+"  Username to use to access MySQL server. Default ``bugs``."
+msgstr ""
+
+msgid ""
+"bugzilla.password\n"
 "  Password to use to access MySQL server."
 msgstr ""
 
 msgid ""
-"timeout\n"
+"bugzilla.timeout\n"
 "  Database connection timeout (seconds). Default 5."
 msgstr ""
 
 msgid ""
-"version\n"
-"  Bugzilla version. Specify '3.0' for Bugzilla versions 3.0 and later,\n"
-"  '2.18' for Bugzilla versions from 2.18 and '2.16' for versions prior\n"
-"  to 2.18."
-msgstr ""
-
-msgid ""
-"bzuser\n"
+"bugzilla.bzuser\n"
 "  Fallback Bugzilla user name to record comments with, if changeset\n"
 "  committer cannot be found as a Bugzilla user."
 msgstr ""
 
 msgid ""
-"bzdir\n"
+"bugzilla.bzdir\n"
 "   Bugzilla install directory. Used by default notify. Default\n"
-"   '/var/www/html/bugzilla'."
-msgstr ""
-
-msgid ""
-"notify\n"
+"   ``/var/www/html/bugzilla``."
+msgstr ""
+
+msgid ""
+"bugzilla.notify\n"
 "  The command to run to get Bugzilla to send bug change notification\n"
-"  emails. Substitutes from a map with 3 keys, 'bzdir', 'id' (bug id)\n"
-"  and 'user' (committer bugzilla email). Default depends on version;\n"
-"  from 2.18 it is \"cd %(bzdir)s && perl -T contrib/sendbugmail.pl\n"
-"  %(id)s %(user)s\"."
-msgstr ""
-
-msgid ""
-"regexp\n"
-"  Regular expression to match bug IDs in changeset commit message.\n"
-"  Must contain one \"()\" group. The default expression matches 'Bug\n"
-"  1234', 'Bug no. 1234', 'Bug number 1234', 'Bugs 1234,5678', 'Bug\n"
-"  1234 and 5678' and variations thereof. Matching is case insensitive."
-msgstr ""
-
-msgid ""
-"style\n"
-"  The style file to use when formatting comments."
-msgstr ""
-
-msgid ""
-"template\n"
-"  Template to use when formatting comments. Overrides style if\n"
-"  specified. In addition to the usual Mercurial keywords, the\n"
-"  extension specifies::"
-msgstr ""
-
-msgid ""
-"    {bug}       The Bugzilla bug ID.\n"
-"    {root}      The full pathname of the Mercurial repository.\n"
-"    {webroot}   Stripped pathname of the Mercurial repository.\n"
-"    {hgweb}     Base URL for browsing Mercurial repositories."
-msgstr ""
-
-msgid ""
-"  Default 'changeset {node|short} in repo {root} refers '\n"
-"          'to bug {bug}.\\ndetails:\\n\\t{desc|tabindent}'"
-msgstr ""
-
-msgid ""
-"strip\n"
-"  The number of slashes to strip from the front of {root} to produce\n"
-"  {webroot}. Default 0."
-msgstr ""
-
-msgid ""
-"usermap\n"
-"  Path of file containing Mercurial committer ID to Bugzilla user ID\n"
-"  mappings. If specified, the file should contain one mapping per\n"
-"  line, \"committer\"=\"Bugzilla user\". See also the [usermap] section."
-msgstr ""
-
-msgid ""
-"The [usermap] section is used to specify mappings of Mercurial\n"
-"committer ID to Bugzilla user ID. See also [bugzilla].usermap.\n"
-"\"committer\"=\"Bugzilla user\""
-msgstr ""
-
-msgid "Finally, the [web] section supports one entry:"
-msgstr ""
-
-msgid ""
-"baseurl\n"
-"  Base URL for browsing Mercurial repositories. Reference from\n"
-"  templates as {hgweb}."
+"  emails. Substitutes from a map with 3 keys, ``bzdir``, ``id`` (bug\n"
+"  id) and ``user`` (committer bugzilla email). Default depends on\n"
+"  version; from 2.18 it is \"cd %(bzdir)s && perl -T\n"
+"  contrib/sendbugmail.pl %(id)s %(user)s\"."
 msgstr ""
 
 msgid "Activating the extension::"
@@ -446,13 +537,92 @@
 "    incoming.bugzilla = python:hgext.bugzilla.hook"
 msgstr ""
 
-msgid "Example configuration:"
-msgstr ""
-
-msgid ""
-"This example configuration is for a collection of Mercurial\n"
-"repositories in /var/local/hg/repos/ used with a local Bugzilla 3.2\n"
-"installation in /opt/bugzilla-3.2. ::"
+msgid "Example configurations:"
+msgstr "Eksempelkonfigurationer:"
+
+msgid ""
+"XMLRPC example configuration. This uses the Bugzilla at\n"
+"``http://my-project.org/bugzilla``, logging in as user\n"
+"``bugmail@my-project.org`` with password ``plugh``. It is used with a\n"
+"collection of Mercurial repositories in ``/var/local/hg/repos/``,\n"
+"with a web interface at ``http://my-project.org/hg``. ::"
+msgstr ""
+
+msgid ""
+"    [bugzilla]\n"
+"    bzurl=http://my-project.org/bugzilla\n"
+"    user=bugmail@my-project.org\n"
+"    password=plugh\n"
+"    version=xmlrpc\n"
+"    template=Changeset {node|short} in {root|basename}.\n"
+"             {hgweb}/{webroot}/rev/{node|short}\\n\n"
+"             {desc}\\n\n"
+"    strip=5"
+msgstr ""
+"    [bugzilla]\n"
+"    bzurl=http://my-project.org/bugzilla\n"
+"    user=bugmail@my-project.org\n"
+"    password=plugh\n"
+"    version=xmlrpc\n"
+"    template=Changeset {node|short} in {root|basename}.\n"
+"             {hgweb}/{webroot}/rev/{node|short}\\n\n"
+"             {desc}\\n\n"
+"    strip=5"
+
+msgid ""
+"    [web]\n"
+"    baseurl=http://my-project.org/hg"
+msgstr ""
+"    [web]\n"
+"    baseurl=http://my-project.org/hg"
+
+msgid ""
+"XMLRPC+email example configuration. This uses the Bugzilla at\n"
+"``http://my-project.org/bugzilla``, logging in as user\n"
+"``bugmail@my-project.org`` wityh password ``plugh``. It is used with a\n"
+"collection of Mercurial repositories in ``/var/local/hg/repos/``,\n"
+"with a web interface at ``http://my-project.org/hg``. Bug comments\n"
+"are sent to the Bugzilla email address\n"
+"``bugzilla@my-project.org``. ::"
+msgstr ""
+
+msgid ""
+"    [bugzilla]\n"
+"    bzurl=http://my-project.org/bugzilla\n"
+"    user=bugmail@my-project.org\n"
+"    password=plugh\n"
+"    version=xmlrpc\n"
+"    bzemail=bugzilla@my-project.org\n"
+"    template=Changeset {node|short} in {root|basename}.\n"
+"             {hgweb}/{webroot}/rev/{node|short}\\n\n"
+"             {desc}\\n\n"
+"    strip=5"
+msgstr ""
+"    [bugzilla]\n"
+"    bzurl=http://my-project.org/bugzilla\n"
+"    user=bugmail@my-project.org\n"
+"    password=plugh\n"
+"    version=xmlrpc\n"
+"    bzemail=bugzilla@my-project.org\n"
+"    template=Changeset {node|short} in {root|basename}.\n"
+"             {hgweb}/{webroot}/rev/{node|short}\\n\n"
+"             {desc}\\n\n"
+"    strip=5"
+
+msgid ""
+"    [usermap]\n"
+"    user@emaildomain.com=user.name@bugzilladomain.com"
+msgstr ""
+"    [usermap]\n"
+"    user@emaildomain.com=user.name@bugzilladomain.com"
+
+msgid ""
+"MySQL example configuration. This has a local Bugzilla 3.2 installation\n"
+"in ``/opt/bugzilla-3.2``. The MySQL database is on ``localhost``,\n"
+"the Bugzilla database name is ``bugs`` and MySQL is\n"
+"accessed with MySQL username ``bugs`` password ``XYZZY``. It is used\n"
+"with a collection of Mercurial repositories in ``/var/local/hg/repos/``,\n"
+"with a web interface at ``http://my-project.org/hg``. ::"
 msgstr ""
 
 msgid ""
@@ -478,32 +648,22 @@
 "             {desc}\\n\n"
 "    strip=5"
 
-msgid ""
-"    [web]\n"
-"    baseurl=http://dev.domain.com/hg"
-msgstr ""
-"    [web]\n"
-"    baseurl=http://dev.domain.com/hg"
-
-msgid ""
-"    [usermap]\n"
-"    user@emaildomain.com=user.name@bugzilladomain.com"
-msgstr ""
-"    [usermap]\n"
-"    user@emaildomain.com=user.name@bugzilladomain.com"
-
-msgid "Commits add a comment to the Bugzilla bug record of the form::"
+msgid "All the above add a comment to the Bugzilla bug record of the form::"
 msgstr ""
 
 msgid ""
 "    Changeset 3b16791d6642 in repository-name.\n"
-"    http://dev.domain.com/hg/repository-name/rev/3b16791d6642"
+"    http://my-project.org/hg/repository-name/rev/3b16791d6642"
 msgstr ""
 
 msgid "    Changeset commit comment. Bug 1234.\n"
 msgstr ""
 
 #, python-format
+msgid "python mysql support not available: %s"
+msgstr "python mysql-understøttelse ikke tilgængelig: %s"
+
+#, python-format
 msgid "connecting to %s:%s as %s, password %s\n"
 msgstr "forbinder til %s:%s som %s, kodeord %s\n"
 
@@ -552,6 +712,13 @@
 msgid "cannot find bugzilla user id for %s or %s"
 msgstr "kan ikke finde bugzilla bruger-id for %s eller %s"
 
+msgid "configuration 'bzemail' missing"
+msgstr "konfigurationen af 'bzemail' mangler"
+
+#, python-format
+msgid "default bugzilla user %s email not found"
+msgstr ""
+
 #, python-format
 msgid "bugzilla version %s not supported"
 msgstr "bugzilla version %s ikke understøttet"
@@ -563,16 +730,12 @@
 msgstr ""
 
 #, python-format
-msgid "python mysql support not available: %s"
-msgstr "python mysql-understøttelse ikke tilgængelig: %s"
-
-#, python-format
 msgid "hook type %s does not pass a changeset id"
 msgstr ""
 
 #, python-format
-msgid "database error: %s"
-msgstr "databasefejl: %s"
+msgid "Bugzilla error: %s"
+msgstr "Bugzilla fejl: %s"
 
 msgid "command to display child changesets"
 msgstr "kommando til at vise børne-ændringer"
@@ -736,12 +899,11 @@
 msgstr "farvelæg output for nogle kommandoer"
 
 msgid ""
-"This extension modifies the status and resolve commands to add color to "
-"their\n"
-"output to reflect file status, the qseries command to add color to reflect\n"
-"patch status (applied, unapplied, missing), and to diff-related\n"
-"commands to highlight additions, removals, diff headers, and trailing\n"
-"whitespace."
+"This extension modifies the status and resolve commands to add color\n"
+"to their output to reflect file status, the qseries command to add\n"
+"color to reflect patch status (applied, unapplied, missing), and to\n"
+"diff-related commands to highlight additions, removals, diff headers,\n"
+"and trailing whitespace."
 msgstr ""
 "Denne udvidelse ændrer status- og resolve-kommandoerne så de tilføjer\n"
 "farve til deres output for at afspejle filstatus, qseries-kommandoen\n"
@@ -1332,6 +1494,15 @@
 msgid "hg debugcvsps [OPTION]... [PATH]..."
 msgstr "hg debugcvsps [TILVALG]... [STI]..."
 
+msgid ":svnrev: String. Converted subversion revision number."
+msgstr ""
+
+msgid ":svnpath: String. Converted subversion revision project path."
+msgstr ""
+
+msgid ":svnuuid: String. Converted subversion revision repository identifier."
+msgstr ""
+
 #, python-format
 msgid "%s does not look like a Bazaar repository"
 msgstr "%s ser ikke ud som et Bazaar depot"
@@ -1664,6 +1835,9 @@
 msgid "updating tags\n"
 msgstr "opdaterer mærkater\n"
 
+msgid "updating bookmarks\n"
+msgstr "opdaterer bogmærker\n"
+
 #, python-format
 msgid "%s is not a valid start revision"
 msgstr "%s er ikke en gyldig startrevision"
@@ -1676,10 +1850,45 @@
 msgid "%s does not look like a monotone repository"
 msgstr "%s ser ikke ud som et monotone depot"
 
+msgid "bad mtn packet - no end of commandnbr"
+msgstr ""
+
+#, python-format
+msgid "bad mtn packet - bad stream type %s"
+msgstr ""
+
+msgid "bad mtn packet - no divider before size"
+msgstr ""
+
+msgid "bad mtn packet - no end of packet size"
+msgstr ""
+
+#, python-format
+msgid "bad mtn packet - bad packet size %s"
+msgstr ""
+
+#, python-format
+msgid "bad mtn packet - unable to read full packet read %s of %s"
+msgstr ""
+
+#, python-format
+msgid "mtn command '%s' returned %s"
+msgstr "mtn kommando '%s' returnerede %s"
+
 #, python-format
 msgid "copying file in renamed directory from '%s' to '%s'"
 msgstr "kopierer fil i omdøbt katalog fra '%s' til '%s'"
 
+msgid "unable to determine mtn automate interface version"
+msgstr ""
+
+#, python-format
+msgid "mtn automate stdio header unexpected: %s"
+msgstr ""
+
+msgid "failed to reach end of mtn automate stdio headers"
+msgstr ""
+
 #, python-format
 msgid "%s does not look like a P4 repository"
 msgstr "%s ser ikke ud som et P4 depot"
@@ -1935,11 +2144,13 @@
 
 msgid ""
 "The ``win32text.forbid*`` hooks provided by the win32text extension\n"
-"have been unified into a single hook named ``eol.hook``. The hook will\n"
-"lookup the expected line endings from the ``.hgeol`` file, which means\n"
-"you must migrate to a ``.hgeol`` file first before using the hook.\n"
-"Remember to enable the eol extension in the repository where you\n"
-"install the hook."
+"have been unified into a single hook named ``eol.checkheadshook``. The\n"
+"hook will lookup the expected line endings from the ``.hgeol`` file,\n"
+"which means you must migrate to a ``.hgeol`` file first before using\n"
+"the hook. ``eol.checkheadshook`` only checks heads, intermediate\n"
+"invalid revisions will be pushed. To forbid them completely, use the\n"
+"``eol.checkallhook`` hook. These hooks are best used as\n"
+"``pretxnchangegroup`` hooks."
 msgstr ""
 
 msgid ""
@@ -1950,25 +2161,24 @@
 "glob-mønstre.\n"
 
 #, python-format
-msgid "%s should not have CRLF line endings"
-msgstr "%s skulle ikke have CRLF linieskift"
-
-#, python-format
-msgid "%s should not have LF line endings"
-msgstr "%s skulle ikke have LF linieskift"
+msgid "ignoring unknown EOL style '%s' from %s\n"
+msgstr "ignorerer ukendt linieskifttype '%s' fra %s\n"
 
 #, python-format
 msgid "warning: ignoring .hgeol file due to parse error at %s: %s\n"
 msgstr ""
 
+#, python-format
+msgid "  %s in %s should not have %s line endings"
+msgstr "  %s i %s skulle ikke have %s linieskift"
+
+msgid "end-of-line check failed:\n"
+msgstr ""
+
 msgid "the eol extension is incompatible with the win32text extension\n"
 msgstr "eol-udvidelsen er inkompatibel med win32text-udvidelsen\n"
 
 #, python-format
-msgid "ignoring unknown EOL style '%s' from %s\n"
-msgstr "ignorerer ukendt linieskifttype '%s' fra %s\n"
-
-#, python-format
 msgid "inconsistent newline style in %s\n"
 msgstr "inkonsistent linieskift i %s\n"
 
@@ -2873,17 +3083,17 @@
 "available templates and filters."
 msgstr ""
 
-msgid "Three additional date template filters are provided::"
-msgstr ""
-
-msgid ""
-"    utcdate      \"2006/09/18 15:13:13\"\n"
-"    svnutcdate   \"2006-09-18 15:13:13Z\"\n"
-"    svnisodate   \"2006-09-18 08:13:13 -700 (Mon, 18 Sep 2006)\""
-msgstr ""
-"    utcdate      \"2006/09/18 15:13:13\"\n"
-"    svnutcdate   \"2006-09-18 15:13:13Z\"\n"
-"    svnisodate   \"2006-09-18 08:13:13 -700 (Mon, 18 Sep 2006)\""
+msgid "Three additional date template filters are provided:"
+msgstr ""
+
+msgid ""
+":``utcdate``:    \"2006/09/18 15:13:13\"\n"
+":``svnutcdate``: \"2006-09-18 15:13:13Z\"\n"
+":``svnisodate``: \"2006-09-18 08:13:13 -700 (Mon, 18 Sep 2006)\""
+msgstr ""
+":``utcdate``:    \"2006/09/18 15:13:13\"\n"
+":``svnutcdate``: \"2006-09-18 15:13:13Z\"\n"
+":``svnisodate``: \"2006-09-18 08:13:13 -700 (Mon, 18 Sep 2006)\""
 
 msgid ""
 "The default template mappings (view with :hg:`kwdemo -d`) can be\n"
@@ -3609,14 +3819,15 @@
 "    With -g/--git, patches imported with --rev will use the git diff\n"
 "    format. See the diffs help topic for information on why this is\n"
 "    important for preserving rename/copy information and permission\n"
-"    changes."
-msgstr ""
-"    En eksisterende ændrin kan blive sat under mq kontrol med -r/--rev\n"
+"    changes. Use :hg:`qfinish` to remove changesets from mq control."
+msgstr ""
+"    En eksisterende ændring kan blive sat under mq kontrol med -r/--rev\n"
 "    (e.g. qimport --rev tip -n patch vil sætte tip under mq kontrol).\n"
 "    Med -g/--git vil patches importeret med --rev bruge git diff\n"
 "    formatet. Se 'hg help diffs' for mere information om hvorfor dette\n"
 "    er vigtigt for at bevare omdøbnings/kopierings-information og\n"
-"    ændriner i rettigheder."
+"    ændriner i rettigheder. Brug :hg:`qfinish` for at fjerne ændringer\n"
+"    fra mq."
 
 msgid ""
 "    To import a patch from standard input, pass - as the patch file.\n"
@@ -3929,13 +4140,6 @@
 "    Når -f/--force er angivet, så vil alle lokale ændringer i de\n"
 "    rettede filer gå tabt."
 
-msgid ""
-"    Return 0 on succces.\n"
-"    "
-msgstr ""
-"    Returnerer 0 ved succes.\n"
-"    "
-
 msgid "no saved queues found, please use -n\n"
 msgstr "fandt ingen gemte køer, brug venligst -r\n"
 
@@ -4053,12 +4257,12 @@
 "    eksempel::"
 
 msgid ""
-"        qguard foo.patch -stable    (negative guard)\n"
-"        qguard bar.patch +stable    (positive guard)\n"
+"        qguard foo.patch -- -stable    (negative guard)\n"
+"        qguard bar.patch    +stable    (positive guard)\n"
 "        qselect stable"
 msgstr ""
-"        qguard foo.patch -stable    (negativt filter)\n"
-"        qguard bar.patch +stable    (positivt filter)\n"
+"        qguard foo.patch -- -stable    (negativt filter)\n"
+"        qguard bar.patch    +stable    (positivt filter)\n"
 "        qselect stable"
 
 msgid ""
@@ -4805,8 +5009,8 @@
 msgstr ""
 
 msgid ""
-"To configure other defaults, add a section like this to your hgrc\n"
-"file::"
+"To configure other defaults, add a section like this to your\n"
+"configuration file::"
 msgstr ""
 
 msgid ""
@@ -5311,6 +5515,9 @@
 "    "
 msgstr ""
 
+msgid "message can only be specified with collapse"
+msgstr ""
+
 msgid "cannot use both abort and continue"
 msgstr "abort og continue kan ikke angives samtidig"
 
@@ -5323,6 +5530,9 @@
 msgid "abort and continue do not allow specifying revisions"
 msgstr "abort og continue tillader ikke at der angives revisioner"
 
+msgid "tool option will be ignored\n"
+msgstr ""
+
 msgid "cannot specify both a revision and a base"
 msgstr "man kan ikke angive både en revision og en basis"
 
@@ -5335,9 +5545,6 @@
 msgid "nothing to rebase\n"
 msgstr ""
 
-msgid "cannot use both keepbranches and extrafn"
-msgstr "man kan ikke bruge både keepbranches og extrafn"
-
 msgid "rebasing"
 msgstr ""
 
@@ -5407,6 +5614,12 @@
 msgid "collapse the rebased changesets"
 msgstr ""
 
+msgid "use text as collapse commit message"
+msgstr "brug tekst som deponeringsbesked"
+
+msgid "read collapse commit message from file"
+msgstr "læs deponeringsbeskeden fra fil"
+
 msgid "keep original changesets"
 msgstr "behold de originale ændringer"
 
@@ -5416,6 +5629,9 @@
 msgid "force detaching of source from its original branch"
 msgstr ""
 
+msgid "specify merge tool"
+msgstr "angiv sammenføjningsværktøj"
+
 msgid "continue an interrupted rebase"
 msgstr ""
 
@@ -5536,6 +5752,17 @@
 msgid "    This command is not available when committing a merge."
 msgstr ""
 
+msgid "interactively record a new patch"
+msgstr "vælg ændringer interaktivt til deponering"
+
+msgid ""
+"    See :hg:`help qnew` & :hg:`help record` for more information and\n"
+"    usage.\n"
+"    "
+msgstr ""
+"    Se :hg:`help qnew` & :hg:`help record` for mere information.\n"
+"    "
+
 msgid "'mq' extension not loaded"
 msgstr "'mq' udvidelsen er ikke indlæst"
 
@@ -5641,7 +5868,7 @@
 msgstr "sammenkæder"
 
 #, python-format
-msgid "relinked %d files (%d bytes reclaimed)\n"
+msgid "relinked %d files (%s reclaimed)\n"
 msgstr ""
 
 msgid "[ORIGIN]"
@@ -5711,6 +5938,10 @@
 "same name.\n"
 msgstr ""
 
+#, python-format
+msgid "custom scheme %s:// conflicts with drive letter %s:\\\n"
+msgstr ""
+
 msgid "share a common history between several working directories"
 msgstr "del en fælles historie mellem flere arbejdsbiblioteker"
 
@@ -5800,6 +6031,9 @@
 msgid "commit failed"
 msgstr "deponering fejlede"
 
+msgid "filter corrupted changeset (no user or date)"
+msgstr "filtrer ødelagte ændringer (ingen bruger eller dato)"
+
 msgid ""
 "y: transplant this changeset\n"
 "n: skip this changeset\n"
@@ -5901,6 +6135,11 @@
 "    Transplanted changesets in set."
 msgstr ""
 
+msgid ""
+":transplanted: String. The node identifier of the transplanted\n"
+"    changeset if any."
+msgstr ""
+
 msgid "pull patches from REPO"
 msgstr "hiv rettelser fra DEPOT"
 
@@ -6161,6 +6400,18 @@
 msgid "bookmark '%s' contains illegal character"
 msgstr ""
 
+#, python-format
+msgid "branch %s not found"
+msgstr "gren %s blev ikke fundet"
+
+#, python-format
+msgid "updating bookmark %s\n"
+msgstr "opdaterer bogmærke %s\n"
+
+#, python-format
+msgid "not updating divergent bookmark %s\n"
+msgstr "opdaterer ikke divergerende bogmærke %s\n"
+
 msgid "searching for changed bookmarks\n"
 msgstr "leder efter ændrede bogmærker\n"
 
@@ -6699,7 +6950,8 @@
 #, python-format
 msgid ""
 "Not all ancestors of this changeset have been checked.\n"
-"To check the other ancestors, start from the common ancestor, %s.\n"
+"Use bisect --extend to continue the bisection from\n"
+"the common ancestor, %s.\n"
 msgstr ""
 
 msgid "Due to skipped revisions, the first good revision could be any of:\n"
@@ -6737,6 +6989,13 @@
 msgstr "Ændring %d:%s: %s\n"
 
 #, python-format
+msgid "Extending search to changeset %d:%s\n"
+msgstr "Udvider søgning til ændring %d:%s\n"
+
+msgid "nothing to extend"
+msgstr "kan ikke udvidde"
+
+#, python-format
 msgid "Testing changeset %d:%s (%d changesets remaining, ~%d tests)\n"
 msgstr "Tester ændring %d:%s (%d ændringer tilbage, ~%d test)\n"
 
@@ -6781,11 +7040,13 @@
 "    bookmark-udviddelsen skal være slået til.\n"
 "    "
 
-msgid "a bookmark of this name does not exist"
-msgstr "et bogmærke med dette navn findes ikke"
-
-msgid "a bookmark of the same name already exists"
-msgstr "et bogmærke med samme navn findes allerede"
+#, python-format
+msgid "bookmark '%s' does not exist"
+msgstr "mærkaten '%s' eksisterer ikke"
+
+#, python-format
+msgid "bookmark '%s' already exists (use -f to force)"
+msgstr "mærkaten '%s' eksisterer allerede (brug -f for at gennemtvinge)"
 
 msgid "new bookmark name required"
 msgstr "nyt bogmærkenavn påkrævet"
@@ -7144,6 +7405,10 @@
 msgid "can only close branch heads"
 msgstr "kan kun lukke grenhoveder"
 
+#, python-format
+msgid "nothing changed (%d missing files, see 'hg status')\n"
+msgstr ""
+
 msgid "nothing changed\n"
 msgstr "ingen ændringer\n"
 
@@ -7314,6 +7579,29 @@
 msgid "only one config item permitted"
 msgstr ""
 
+msgid "test whether node ids are known to a repo"
+msgstr ""
+
+msgid ""
+"    Every ID must be a full-length hex node id string. Returns a list of 0s "
+"and 1s\n"
+"    indicating unknown/known.\n"
+"    "
+msgstr ""
+
+msgid "lists the contents of a bundle"
+msgstr "vis indholdet af et bundt"
+
+msgid "retrieves a bundle from a repo"
+msgstr ""
+
+msgid ""
+"    Every ID must be a full-length hex node id string. Saves the bundle to "
+"the\n"
+"    given file.\n"
+"    "
+msgstr ""
+
 msgid "access the pushkey key/value protocol"
 msgstr ""
 
@@ -7412,28 +7700,6 @@
 msgid " (templates seem to have been installed incorrectly)\n"
 msgstr ""
 
-msgid "Checking patch...\n"
-msgstr ""
-
-msgid " patch call failed:\n"
-msgstr ""
-
-msgid " unexpected patch output!\n"
-msgstr ""
-
-msgid " patch test failed!\n"
-msgstr ""
-
-msgid ""
-" (Current patch tool may be incompatible with patch, or misconfigured. "
-"Please check your configuration file)\n"
-msgstr ""
-
-msgid ""
-" Internal patcher failure, please report this error to http://mercurial."
-"selenic.com/wiki/BugTracker\n"
-msgstr ""
-
 msgid "Checking commit editor...\n"
 msgstr ""
 
@@ -7742,6 +8008,10 @@
 "detaljer"
 
 #, python-format
+msgid "use \"hg help %s\" to show the full help text"
+msgstr "brug \"hg help %s\" for at se udførlig hjælp"
+
+#, python-format
 msgid "use \"hg -v help%s\" to show builtin aliases and global options"
 msgstr ""
 "brug \"hg -v help%s\" for at vise indbyggede aliaser og globale "
@@ -7840,7 +8110,14 @@
 msgstr ""
 
 msgid ""
-"    With no revision, print a summary of the current state of the\n"
+"    Print a summary identifiying the repository state at REV\n"
+"    using one or two parent hash identifiers, followed by a\n"
+"    \"+\" if there are uncommitted changes in the working directory,\n"
+"    the branch name (omitted if default) and a list of tags, bookmarks."
+msgstr ""
+
+msgid ""
+"    When REV is not given, print a summary of the current state of the\n"
 "    repository."
 msgstr ""
 
@@ -7849,14 +8126,7 @@
 "    cause lookup to operate on that repository/bundle."
 msgstr ""
 
-msgid ""
-"    This summary identifies the repository state using one or two\n"
-"    parent hash identifiers, followed by a \"+\" if there are\n"
-"    uncommitted changes in the working directory, a list of tags for\n"
-"    this revision and a branch name for non-default branches."
-msgstr ""
-
-msgid "can't query remote revision number, branch, tags, or bookmarks"
+msgid "can't query remote revision number, branch, or tags"
 msgstr ""
 
 msgid "import an ordered set of patches"
@@ -8099,7 +8369,7 @@
 msgid ""
 "    ``--tool`` can be used to specify the merge tool used for file\n"
 "    merges. It overrides the HGMERGE environment variable and your\n"
-"    configuration files."
+"    configuration files. See :hg:`help merge-tools` for options."
 msgstr ""
 
 msgid ""
@@ -8239,6 +8509,12 @@
 msgid "(run 'hg heads' to see heads, 'hg merge' to merge)\n"
 msgstr "(kør 'hg heads' for at se hoveder, 'hg merge' for at sammenføje)\n"
 
+msgid "(run 'hg heads .' to see heads, 'hg merge' to merge)\n"
+msgstr "(kør 'hg heads .' for at se hoveder, 'hg merge' for at sammenføje)\n"
+
+msgid "(run 'hg heads' to see heads)\n"
+msgstr "(kør 'hg heads' for at se hoveder)\n"
+
 msgid "(run 'hg update' to get a working copy)\n"
 msgstr "(kør 'hg update' for at få en arbejdskopi)\n"
 
@@ -8582,8 +8858,9 @@
 msgstr ""
 
 msgid ""
-"    If a file has been deleted, it is restored. If the executable mode\n"
-"    of a file was changed, it is reset."
+"    If a file has been deleted, it is restored. Files scheduled for\n"
+"    addition are just unscheduled and left as they are. If the\n"
+"    executable mode of a file was changed, it is reset."
 msgstr ""
 
 msgid ""
@@ -9333,9 +9610,6 @@
 msgid "parent to choose when backing out merge"
 msgstr ""
 
-msgid "specify merge tool"
-msgstr "angiv sammenføjningsværktøj"
-
 msgid "revision to backout"
 msgstr "revision som skal bakkes ud"
 
@@ -9354,6 +9628,9 @@
 msgid "skip testing changeset"
 msgstr "spring testen af denne ændring over"
 
+msgid "extend the bisect range"
+msgstr "udvid halveringsområdet"
+
 msgid "use command to check changeset state"
 msgstr "brug kommando for at kontrollere tilstanden af ændringen"
 
@@ -9474,6 +9751,9 @@
 msgid "[OPTION]... TEXT"
 msgstr "[TILVALG]... TEKST"
 
+msgid "show all details"
+msgstr "vis alle detaljer"
+
 msgid "[COMMAND]"
 msgstr "[KOMMANDO]"
 
@@ -9510,9 +9790,21 @@
 msgid "[PATH]"
 msgstr "[STI]"
 
+msgid "id of head node"
+msgstr ""
+
+msgid "id of common node"
+msgstr "id på fælles knude"
+
+msgid "REPO FILE [-H|-C ID]..."
+msgstr ""
+
 msgid "revlog format"
 msgstr ""
 
+msgid "REPO ID..."
+msgstr ""
+
 msgid "REPO NAMESPACE [KEY OLD NEW]"
 msgstr ""
 
@@ -9534,12 +9826,18 @@
 msgid "do not display the saved mtime"
 msgstr "vis ikke den gemte mtime"
 
+msgid "sort by saved mtime"
+msgstr "sorter efter den gemte mtime"
+
 msgid "[OPTION]..."
 msgstr "[TILVALG]..."
 
 msgid "revision to check"
 msgstr "revision som skal undersøges"
 
+msgid "REPO [OPTIONS]... [ONE [TWO]]"
+msgstr "DEPOT [TILVALG]... [EN [TO]]"
+
 msgid "[OPTION]... ([-c REV] | [-r REV1 [-r REV2]]) [FILE]..."
 msgstr "[TILVALG]... ([-c REV] | [-r REV1 [-r REV2]]) [FIL]..."
 
@@ -10014,10 +10312,6 @@
 msgstr "arbejdskatalogtilstand virker beskadiget!"
 
 #, python-format
-msgid "'\\n' and '\\r' disallowed in filenames: %r"
-msgstr "'\\n' og '\\r' må ikke forekomme i filnavne: %r"
-
-#, python-format
 msgid "directory %r already in dirstate"
 msgstr "katalog %r er allerede i dirstate"
 
@@ -10566,29 +10860,29 @@
 msgstr "- ``1165432709 0`` (Ons 6. dec. 13:18:29 2006 UTC)"
 
 msgid ""
-"This is the internal representation format for dates. unixtime is the\n"
-"number of seconds since the epoch (1970-01-01 00:00 UTC). offset is\n"
-"the offset of the local timezone, in seconds west of UTC (negative if\n"
-"the timezone is east of UTC)."
-msgstr ""
-"Dette er den interne repræsentation af datoer. unixtime er\n"
+"This is the internal representation format for dates. The first number\n"
+"is the number of seconds since the epoch (1970-01-01 00:00 UTC). The\n"
+"second is the offset of the local timezone, in seconds west of UTC\n"
+"(negative if the timezone is east of UTC)."
+msgstr ""
+"Dette er den interne repræsentation af datoer. Det første tal er\n"
 "antallet af sekunder siden begyndelsen af epoken (1970-01-01 00:00\n"
-"UTC). offset er den lokale tidszone, angivet i antal sekunder vest\n"
-"for UTC (negativ hvis tidszonen er øst for UTC)."
+"UTC). Det andet tal er den lokale tidszone, angivet i antal sekunder\n"
+"vest for UTC (negativ hvis tidszonen er øst for UTC)."
 
 msgid "The log command also accepts date ranges:"
 msgstr "Kommandoen log accepterer også datointervaller:"
 
 msgid ""
-"- ``<{datetime}`` - at or before a given date/time\n"
-"- ``>{datetime}`` - on or after a given date/time\n"
-"- ``{datetime} to {datetime}`` - a date range, inclusive\n"
-"- ``-{days}`` - within a given number of days of today\n"
-msgstr ""
-"- ``<{date}`` - på eller før den angivne dato/tidspunkt\n"
-"- ``>{date}`` - på eller efter den angivne dato/tidspunkt\n"
-"- ``{date} to {date}`` - et datointerval, inklusiv endepunkterne\n"
-"- ``-{days}`` - indenfor et angivet antal dage, fra dags dato\n"
+"- ``<DATE`` - at or before a given date/time\n"
+"- ``>DATE`` - on or after a given date/time\n"
+"- ``DATE to DATE`` - a date range, inclusive\n"
+"- ``-DAYS`` - within a given number of days of today\n"
+msgstr ""
+"- ``<DATO`` - på eller før den angivne dato/tidspunkt\n"
+"- ``>DATO`` - på eller efter den angivne dato/tidspunkt\n"
+"- ``DATO to DATO`` - et datointerval, inklusiv endepunkterne\n"
+"- ``-DAGE`` - indenfor et angivet antal dage, fra dags dato\n"
 
 msgid ""
 "Mercurial's default format for showing changes between two versions of\n"
@@ -10714,6 +11008,18 @@
 msgstr ""
 
 msgid ""
+"HGPLAINEXCEPT\n"
+"    This is a comma-separated list of features to preserve when\n"
+"    HGPLAIN is enabled. Currently the only value supported is \"i18n\",\n"
+"    which preserves internationalization in plain mode."
+msgstr ""
+
+msgid ""
+"    Setting HGPLAINEXCEPT to anything (even an empty string) will\n"
+"    enable plain mode."
+msgstr ""
+
+msgid ""
 "HGUSER\n"
 "    This is the string used as the author of a commit. If not set,\n"
 "    available values will be considered in this order:"
@@ -11367,8 +11673,8 @@
 msgstr ""
 
 msgid ""
-"This file uses the same syntax as hgrc configuration files, but only\n"
-"the following sections are recognized:"
+"This file uses the same syntax as other Mercurial configuration files,\n"
+"but only the following sections are recognized:"
 msgstr ""
 
 msgid ""
@@ -11382,7 +11688,8 @@
 
 msgid ""
 "The ``web`` section can specify all the settings described in the web\n"
-"section of the hgrc documentation."
+"section of the hgrc(5) documentation. See :hg:`help config` for\n"
+"information on where to find the manual page."
 msgstr ""
 
 msgid ""
@@ -11889,7 +12196,7 @@
 msgid "    hg log -r \"1.3::1.5 and keyword(bug) and file('hgext/*')\""
 msgstr "    hg log -r \"1.3::1.5 and keyword(bug) and file(\"hgext/*\")\""
 
-msgid "- Changesets in committed May 2008, sorted by user::"
+msgid "- Changesets committed in May 2008, sorted by user::"
 msgstr ""
 
 msgid "    hg log -r \"sort(date('May 2008'), user)\""
@@ -12134,78 +12441,7 @@
 "keywords are usually available for templating a log-like command:"
 msgstr ""
 
-msgid ":author: String. The unmodified author of the changeset."
-msgstr ""
-
-msgid ""
-":branch: String. The name of the branch on which the changeset was\n"
-"    committed."
-msgstr ""
-
-msgid ""
-":branches: List of strings. The name of the branch on which the\n"
-"    changeset was committed. Will be empty if the branch name was\n"
-"    default."
-msgstr ""
-
-msgid ":children: List of strings. The children of the changeset."
-msgstr ""
-
-msgid ":date: Date information. The date when the changeset was committed."
-msgstr ""
-
-msgid ":desc: String. The text of the changeset description."
-msgstr ""
-
-msgid ""
-":diffstat: String. Statistics of changes with the following format:\n"
-"    \"modified files: +added/-removed lines\""
-msgstr ""
-
-msgid ""
-":files: List of strings. All files modified, added, or removed by this\n"
-"    changeset."
-msgstr ""
-
-msgid ":file_adds: List of strings. Files added by this changeset."
-msgstr ""
-
-msgid ""
-":file_copies: List of strings. Files copied in this changeset with\n"
-"    their sources."
-msgstr ""
-
-msgid ""
-":file_copies_switch: List of strings. Like \"file_copies\" but displayed\n"
-"    only if the --copied switch is set."
-msgstr ""
-
-msgid ":file_mods: List of strings. Files modified by this changeset."
-msgstr ""
-
-msgid ":file_dels: List of strings. Files removed by this changeset."
-msgstr ""
-
-msgid ""
-":node: String. The changeset identification hash, as a 40 hexadecimal\n"
-"    digit string."
-msgstr ""
-
-msgid ":parents: List of strings. The parents of the changeset."
-msgstr ""
-
-msgid ":rev: Integer. The repository-local changeset revision number."
-msgstr ""
-
-msgid ":tags: List of strings. Any tags associated with the changeset."
-msgstr ""
-
-msgid ""
-":latesttag: String. Most recent global tag in the ancestors of this\n"
-"    changeset."
-msgstr ""
-
-msgid ":latesttagdistance: Integer. Longest path to the latest tag."
+msgid ".. keywordsmarker"
 msgstr ""
 
 msgid ""
@@ -12227,131 +12463,7 @@
 msgid "List of filters:"
 msgstr ""
 
-msgid ""
-":addbreaks: Any text. Add an XHTML \"<br />\" tag before the end of\n"
-"    every line except the last."
-msgstr ""
-
-msgid ""
-":age: Date. Returns a human-readable date/time difference between the\n"
-"    given date/time and the current date/time."
-msgstr ""
-
-msgid ""
-":basename: Any text. Treats the text as a path, and returns the last\n"
-"    component of the path after splitting by the path separator\n"
-"    (ignoring trailing separators). For example, \"foo/bar/baz\" becomes\n"
-"    \"baz\" and \"foo/bar//\" becomes \"bar\"."
-msgstr ""
-
-msgid ""
-":stripdir: Treat the text as path and strip a directory level, if\n"
-"    possible. For example, \"foo\" and \"foo/bar\" becomes \"foo\"."
-msgstr ""
-
-msgid ""
-":date: Date. Returns a date in a Unix date format, including the\n"
-"    timezone: \"Mon Sep 04 15:13:13 2006 0700\"."
-msgstr ""
-
-msgid ""
-":domain: Any text. Finds the first string that looks like an email\n"
-"    address, and extracts just the domain component. Example: ``User\n"
-"    <user@example.com>`` becomes ``example.com``."
-msgstr ""
-
-msgid ""
-":email: Any text. Extracts the first string that looks like an email\n"
-"    address. Example: ``User <user@example.com>`` becomes\n"
-"    ``user@example.com``."
-msgstr ""
-
-msgid ""
-":escape: Any text. Replaces the special XML/XHTML characters \"&\", \"<\"\n"
-"    and \">\" with XML entities."
-msgstr ""
-
-msgid ""
-":hex: Any text. Convert a binary Mercurial node identifier into\n"
-"    its long hexadecimal representation."
-msgstr ""
-
-msgid ":fill68: Any text. Wraps the text to fit in 68 columns."
-msgstr ""
-
-msgid ":fill76: Any text. Wraps the text to fit in 76 columns."
-msgstr ""
-
-msgid ":firstline: Any text. Returns the first line of text."
-msgstr ""
-
-msgid ":nonempty: Any text. Returns '(none)' if the string is empty."
-msgstr ""
-
-msgid ""
-":hgdate: Date. Returns the date as a pair of numbers: \"1157407993\n"
-"    25200\" (Unix timestamp, timezone offset)."
-msgstr ""
-
-msgid ""
-":isodate: Date. Returns the date in ISO 8601 format: \"2009-08-18 13:00\n"
-"    +0200\"."
-msgstr ""
-
-msgid ""
-":isodatesec: Date. Returns the date in ISO 8601 format, including\n"
-"    seconds: \"2009-08-18 13:00:13 +0200\". See also the rfc3339date\n"
-"    filter."
-msgstr ""
-
-msgid ":localdate: Date. Converts a date to local date."
-msgstr ""
-
-msgid ""
-":obfuscate: Any text. Returns the input text rendered as a sequence of\n"
-"    XML entities."
-msgstr ""
-
-msgid ":person: Any text. Returns the text before an email address."
-msgstr ""
-
-msgid ""
-":rfc822date: Date. Returns a date using the same format used in email\n"
-"    headers: \"Tue, 18 Aug 2009 13:00:13 +0200\"."
-msgstr ""
-
-msgid ""
-":rfc3339date: Date. Returns a date using the Internet date format\n"
-"    specified in RFC 3339: \"2009-08-18T13:00:13+02:00\"."
-msgstr ""
-
-msgid ""
-":short: Changeset hash. Returns the short form of a changeset hash,\n"
-"    i.e. a 12 hexadecimal digit string."
-msgstr ""
-
-msgid ":shortdate: Date. Returns a date like \"2006-09-18\"."
-msgstr ""
-
-msgid ""
-":stringify: Any type. Turns the value into text by converting values into\n"
-"    text and concatenating them."
-msgstr ""
-
-msgid ":strip: Any text. Strips all leading and trailing whitespace."
-msgstr ""
-
-msgid ""
-":tabindent: Any text. Returns the text, with every line except the\n"
-"     first starting with a tab character."
-msgstr ""
-
-msgid ""
-":urlescape: Any text. Escapes all \"special\" characters. For example,\n"
-"    \"foo bar\" becomes \"foo%20bar\"."
-msgstr ""
-
-msgid ":user: Any text. Returns the user portion of an email address.\n"
+msgid ".. filtersmarker\n"
 msgstr ""
 
 msgid "Valid URLs are of the form::"
@@ -12800,14 +12912,6 @@
 msgstr ""
 
 #, python-format
-msgid "updating bookmark %s\n"
-msgstr "opdaterer bogmærke %s\n"
-
-#, python-format
-msgid "not updating divergent bookmark %s\n"
-msgstr "opdaterer ikke divergerende bogmærke %s\n"
-
-#, python-format
 msgid "%d changesets found\n"
 msgstr "fandt %d ændringer\n"
 
@@ -12918,6 +13022,10 @@
 msgstr "ugyldig lokal adresse: %s"
 
 #, python-format
+msgid "'\\n' and '\\r' disallowed in filenames: %r"
+msgstr "'\\n' og '\\r' må ikke forekomme i filnavne: %r"
+
+#, python-format
 msgid "failed to remove %s from manifest"
 msgstr "kunne ikke fjerne %s fra manifest"
 
@@ -13004,10 +13112,6 @@
 msgid "note: possible conflict - %s was renamed multiple times to:\n"
 msgstr ""
 
-#, python-format
-msgid "branch %s not found"
-msgstr "gren %s blev ikke fundet"
-
 msgid "merging with a working directory ancestor has no effect"
 msgstr "sammenføjning med en forfader til arbejdskataloget har ingen effekt"
 
@@ -13122,10 +13226,6 @@
 msgstr ""
 
 #, python-format
-msgid "malformed patch %s %s"
-msgstr ""
-
-#, python-format
 msgid "unsupported parser state: %s"
 msgstr ""
 
@@ -13238,86 +13338,12 @@
 msgstr "ikke en funktion: %s"
 
 msgid ""
-"``id(string)``\n"
-"    Revision non-ambiguously specified by the given hex string prefix."
-msgstr ""
-
-#. i18n: "id" is a keyword
-msgid "id requires one argument"
-msgstr "id kræver et argument"
-
-#. i18n: "id" is a keyword
-msgid "id requires a string"
-msgstr "id kræver en streng"
-
-msgid ""
-"``rev(number)``\n"
-"    Revision with the given numeric identifier."
-msgstr ""
-
-#. i18n: "rev" is a keyword
-msgid "rev requires one argument"
-msgstr "rev kræver et argument"
-
-#. i18n: "rev" is a keyword
-msgid "rev requires a number"
-msgstr "rev kræver et tal"
-
-#. i18n: "rev" is a keyword
-msgid "rev expects a number"
-msgstr "rev forventer et revisionsnummer"
-
-msgid ""
-"``p1([set])``\n"
-"    First parent of changesets in set, or the working directory."
-msgstr ""
-
-msgid ""
-"``p2([set])``\n"
-"    Second parent of changesets in set, or the working directory."
-msgstr ""
-
-msgid ""
-"``parents([set])``\n"
-"    The set of all parents for all changesets in set, or the working "
-"directory."
-msgstr ""
-
-msgid ""
-"``max(set)``\n"
-"    Changeset with highest revision number in set."
-msgstr ""
-
-msgid ""
-"``min(set)``\n"
-"    Changeset with lowest revision number in set."
-msgstr ""
-
-msgid ""
-"``limit(set, n)``\n"
-"    First n members of set."
-msgstr ""
-
-#. i18n: "limit" is a keyword
-msgid "limit requires two arguments"
-msgstr "limit kræver to argumenter"
-
-#. i18n: "limit" is a keyword
-msgid "limit requires a number"
-msgstr "limit kræver et tal"
-
-#. i18n: "limit" is a keyword
-msgid "limit expects a number"
-msgstr ""
-
-msgid ""
-"``children(set)``\n"
-"    Child changesets of changesets in set."
-msgstr ""
-
-msgid ""
-"``branch(set)``\n"
-"    All changesets belonging to the branches of changesets in set."
+"``adds(pattern)``\n"
+"    Changesets that add a file matching pattern."
+msgstr ""
+
+#. i18n: "adds" is a keyword
+msgid "adds requires a pattern"
 msgstr ""
 
 msgid ""
@@ -13339,6 +13365,80 @@
 msgstr ""
 
 msgid ""
+"``author(string)``\n"
+"    Alias for ``user(string)``."
+msgstr ""
+
+#. i18n: "author" is a keyword
+msgid "author requires a string"
+msgstr ""
+
+msgid ""
+"``bisected(string)``\n"
+"    Changesets marked in the specified bisect state (good, bad, skip)."
+msgstr ""
+
+msgid "bisect requires a string"
+msgstr "bisect kræver en streng"
+
+msgid "invalid bisect state"
+msgstr "ugyldig tilstand for halvering"
+
+msgid ""
+"``bookmark([name])``\n"
+"    The named bookmark or all bookmarks."
+msgstr ""
+"``bookmark([name])``\n"
+"    Det navngivne bogmærke eller alle bogmærker."
+
+#. i18n: "bookmark" is a keyword
+msgid "bookmark takes one or no arguments"
+msgstr "bookmark tager et eller to argumenter"
+
+#. i18n: "bookmark" is a keyword
+msgid "the argument to bookmark must be a string"
+msgstr "argumentet til bookmark skal være en streng"
+
+msgid ""
+"``branch(string or set)``\n"
+"    All changesets belonging to the given branch or the branches of the "
+"given\n"
+"    changesets."
+msgstr ""
+
+msgid ""
+"``children(set)``\n"
+"    Child changesets of changesets in set."
+msgstr ""
+
+msgid ""
+"``closed()``\n"
+"    Changeset is closed."
+msgstr ""
+
+#. i18n: "closed" is a keyword
+msgid "closed takes no arguments"
+msgstr ""
+
+msgid ""
+"``contains(pattern)``\n"
+"    Revision contains pattern."
+msgstr ""
+
+#. i18n: "contains" is a keyword
+msgid "contains requires a pattern"
+msgstr ""
+
+msgid ""
+"``date(interval)``\n"
+"    Changesets within the interval, see :hg:`help dates`."
+msgstr ""
+
+#. i18n: "date" is a keyword
+msgid "date requires a string"
+msgstr ""
+
+msgid ""
 "``descendants(set)``\n"
 "    Changesets which are descendants of changesets in set."
 msgstr ""
@@ -13353,22 +13453,12 @@
 msgstr ""
 
 msgid ""
-"``date(interval)``\n"
-"    Changesets within the interval, see :hg:`help dates`."
-msgstr ""
-
-#. i18n: "date" is a keyword
-msgid "date requires a string"
-msgstr ""
-
-msgid ""
-"``keyword(string)``\n"
-"    Search commit message, user name, and names of changed files for\n"
-"    string."
-msgstr ""
-
-#. i18n: "keyword" is a keyword
-msgid "keyword requires a string"
+"``all()``\n"
+"    All changesets, the same as ``0:tip``."
+msgstr ""
+
+#. i18n: "all" is a keyword
+msgid "all takes no arguments"
 msgstr ""
 
 msgid ""
@@ -13386,20 +13476,6 @@
 msgstr "ugyldigt søgemønster: %s"
 
 msgid ""
-"``author(string)``\n"
-"    Alias for ``user(string)``."
-msgstr ""
-
-#. i18n: "author" is a keyword
-msgid "author requires a string"
-msgstr ""
-
-msgid ""
-"``user(string)``\n"
-"    User name is string."
-msgstr ""
-
-msgid ""
 "``file(pattern)``\n"
 "    Changesets affecting files matched by pattern."
 msgstr ""
@@ -13409,12 +13485,63 @@
 msgstr ""
 
 msgid ""
-"``contains(pattern)``\n"
-"    Revision contains pattern."
-msgstr ""
-
-#. i18n: "contains" is a keyword
-msgid "contains requires a pattern"
+"``head()``\n"
+"    Changeset is a named branch head."
+msgstr ""
+
+#. i18n: "head" is a keyword
+msgid "head takes no arguments"
+msgstr ""
+
+msgid ""
+"``heads(set)``\n"
+"    Members of set with no children in set."
+msgstr ""
+
+msgid ""
+"``keyword(string)``\n"
+"    Search commit message, user name, and names of changed files for\n"
+"    string."
+msgstr ""
+
+#. i18n: "keyword" is a keyword
+msgid "keyword requires a string"
+msgstr ""
+
+msgid ""
+"``limit(set, n)``\n"
+"    First n members of set."
+msgstr ""
+
+#. i18n: "limit" is a keyword
+msgid "limit requires two arguments"
+msgstr "limit kræver to argumenter"
+
+#. i18n: "limit" is a keyword
+msgid "limit requires a number"
+msgstr "limit kræver et tal"
+
+#. i18n: "limit" is a keyword
+msgid "limit expects a number"
+msgstr ""
+
+msgid ""
+"``max(set)``\n"
+"    Changeset with highest revision number in set."
+msgstr ""
+
+msgid ""
+"``merge()``\n"
+"    Changeset is a merge changeset."
+msgstr ""
+
+#. i18n: "merge" is a keyword
+msgid "merge takes no arguments"
+msgstr ""
+
+msgid ""
+"``min(set)``\n"
+"    Changeset with lowest revision number in set."
 msgstr ""
 
 msgid ""
@@ -13427,12 +13554,48 @@
 msgstr ""
 
 msgid ""
-"``adds(pattern)``\n"
-"    Changesets that add a file matching pattern."
-msgstr ""
-
-#. i18n: "adds" is a keyword
-msgid "adds requires a pattern"
+"``id(string)``\n"
+"    Revision non-ambiguously specified by the given hex string prefix."
+msgstr ""
+
+#. i18n: "id" is a keyword
+msgid "id requires one argument"
+msgstr "id kræver et argument"
+
+#. i18n: "id" is a keyword
+msgid "id requires a string"
+msgstr "id kræver en streng"
+
+msgid ""
+"``outgoing([path])``\n"
+"    Changesets not found in the specified destination repository, or the\n"
+"    default push location."
+msgstr ""
+
+#. i18n: "outgoing" is a keyword
+msgid "outgoing requires a repository path"
+msgstr ""
+
+msgid ""
+"``p1([set])``\n"
+"    First parent of changesets in set, or the working directory."
+msgstr ""
+
+msgid ""
+"``p2([set])``\n"
+"    Second parent of changesets in set, or the working directory."
+msgstr ""
+
+msgid ""
+"``parents([set])``\n"
+"    The set of all parents for all changesets in set, or the working "
+"directory."
+msgstr ""
+
+msgid ""
+"``present(set)``\n"
+"    An empty set, if any revision in set isn't found; otherwise,\n"
+"    all revisions in set."
 msgstr ""
 
 msgid ""
@@ -13445,31 +13608,21 @@
 msgstr ""
 
 msgid ""
-"``merge()``\n"
-"    Changeset is a merge changeset."
-msgstr ""
-
-#. i18n: "merge" is a keyword
-msgid "merge takes no arguments"
-msgstr ""
-
-msgid ""
-"``closed()``\n"
-"    Changeset is closed."
-msgstr ""
-
-#. i18n: "closed" is a keyword
-msgid "closed takes no arguments"
-msgstr ""
-
-msgid ""
-"``head()``\n"
-"    Changeset is a named branch head."
-msgstr ""
-
-#. i18n: "head" is a keyword
-msgid "head takes no arguments"
-msgstr ""
+"``rev(number)``\n"
+"    Revision with the given numeric identifier."
+msgstr ""
+
+#. i18n: "rev" is a keyword
+msgid "rev requires one argument"
+msgstr "rev kræver et argument"
+
+#. i18n: "rev" is a keyword
+msgid "rev requires a number"
+msgstr "rev kræver et tal"
+
+#. i18n: "rev" is a keyword
+msgid "rev expects a number"
+msgstr "rev forventer et revisionsnummer"
 
 msgid ""
 "``reverse(set)``\n"
@@ -13477,9 +13630,8 @@
 msgstr ""
 
 msgid ""
-"``present(set)``\n"
-"    An empty set, if any revision in set isn't found; otherwise,\n"
-"    all revisions in set."
+"``roots(set)``\n"
+"    Changesets with no parent changeset in set."
 msgstr ""
 
 msgid ""
@@ -13511,35 +13663,6 @@
 msgstr "ukendt sorteringsnøgle %r"
 
 msgid ""
-"``all()``\n"
-"    All changesets, the same as ``0:tip``."
-msgstr ""
-
-#. i18n: "all" is a keyword
-msgid "all takes no arguments"
-msgstr ""
-
-msgid ""
-"``heads(set)``\n"
-"    Members of set with no children in set."
-msgstr ""
-
-msgid ""
-"``roots(set)``\n"
-"    Changesets with no parent changeset in set."
-msgstr ""
-
-msgid ""
-"``outgoing([path])``\n"
-"    Changesets not found in the specified destination repository, or the\n"
-"    default push location."
-msgstr ""
-
-#. i18n: "outgoing" is a keyword
-msgid "outgoing requires a repository path"
-msgstr ""
-
-msgid ""
 "``tag(name)``\n"
 "    The specified tag by name, or all tagged revisions if no name is given."
 msgstr ""
@@ -13556,19 +13679,9 @@
 msgstr "argumentet til tag skal være en streng"
 
 msgid ""
-"``bookmark([name])``\n"
-"    The named bookmark or all bookmarks."
-msgstr ""
-"``bookmark([name])``\n"
-"    Det navngivne bogmærke eller alle bogmærker."
-
-#. i18n: "bookmark" is a keyword
-msgid "bookmark takes one or no arguments"
-msgstr "bookmark tager et eller to argumenter"
-
-#. i18n: "bookmark" is a keyword
-msgid "the argument to bookmark must be a string"
-msgstr "argumentet til bookmark skal være en streng"
+"``user(string)``\n"
+"    User name is string."
+msgstr ""
 
 msgid "can't negate that"
 msgstr ""
@@ -13716,12 +13829,8 @@
 msgstr "fjerner ikke depotet %s fordi det er ændret.\n"
 
 #, python-format
-msgid "cloning subrepo %s\n"
-msgstr "kloner underdepot %s\n"
-
-#, python-format
-msgid "pulling subrepo %s\n"
-msgstr "hiver underdepot %s\n"
+msgid "cloning subrepo %s from %s\n"
+msgstr "kloner underdepot %s fra %s\n"
 
 #, python-format
 msgid "revision %s does not exist in subrepo %s\n"
@@ -13861,6 +13970,9 @@
 msgid "edit failed"
 msgstr "redigering fejlede"
 
+msgid "file:// URLs can only refer to localhost"
+msgstr ""
+
 #, python-format
 msgid "ignoring invalid [auth] key '%s'\n"
 msgstr "ignorerer ugyldig [auth] nøgle '%s'\n"
@@ -13937,6 +14049,18 @@
 msgstr "kommandoen '%s' fejlede: %s"
 
 #, python-format
+msgid "filename contains '%s', which is reserved on Windows"
+msgstr ""
+
+#, python-format
+msgid "filename contains %r, which is invalid on Windows"
+msgstr ""
+
+#, python-format
+msgid "filename ends with '%s', which is not allowed on Windows"
+msgstr ""
+
+#, python-format
 msgid "path ends in directory separator: %s"
 msgstr ""
 
@@ -13945,8 +14069,8 @@
 msgstr "stien indeholder ugyldig komponent: %s"
 
 #, python-format
-msgid "path %r is inside repo %r"
-msgstr "stien %r er inde i repo %r"
+msgid "path %r is inside nested repo %r"
+msgstr "stien %r er inden i depotet %r"
 
 #, python-format
 msgid "path %r traverses symbolic link %r"
@@ -13979,11 +14103,24 @@
 msgid "impossible time zone offset: %d"
 msgstr "umuligt tidszone: %d"
 
+msgid "dates cannot consist entirely of whitespace"
+msgstr "datoer kan ikke bestå udelukkende af tomrum"
+
+msgid "invalid day spec, use '<DATE'"
+msgstr "ugyldig datospecifikation, brug '<DATO'"
+
+msgid "invalid day spec, use '>DATE'"
+msgstr "ugyldig datospecifikation, brug '>DATO'"
+
 #, python-format
 msgid "invalid day spec: %s"
 msgstr "ugyldig datospecifikation: %s"
 
 #, python-format
+msgid "%s must be nonnegative (see 'hg help dates')"
+msgstr ""
+
+#, python-format
 msgid "%.0f GB"
 msgstr "%.0f GB"
 
--- a/i18n/pt_BR.po	Wed Jun 01 16:32:48 2011 -0500
+++ b/i18n/pt_BR.po	Sat Jun 18 17:03:01 2011 -0500
@@ -4817,8 +4817,8 @@
 msgid "only a local queue repository may be initialized"
 msgstr "apenas um repositório de fila local pode ser inicializado"
 
-msgid "there is no Mercurial repository here (.hg not found)"
-msgstr "não há um repositório do Mercurial aqui (.hg não encontrado)"
+msgid "no repository found in %r (.hg not found)"
+msgstr "não foi encontrado um repositório em %r (.hg não encontrado)"
 
 msgid "no queue repository"
 msgstr "repositório da fila não existente"
--- a/i18n/ro.po	Wed Jun 01 16:32:48 2011 -0500
+++ b/i18n/ro.po	Sat Jun 18 17:03:01 2011 -0500
@@ -30,7 +30,7 @@
 # head          capăt
 # imply         a implica, a sugera
 # incoming      de primit
-# hook          hook, acțiune, ancoră 
+# hook          hook, acțiune, ancoră
 # merge         a fuziona (a contopi, a îmbina)
 # notation      notație
 # pattern       tipar
@@ -101,13 +101,13 @@
 #  - a   hook                 un hook
 #  - a   patch                un patch
 #
-# Daniel Dumitriu <daniel.dumitriu@gmail.com>, 2010.
+# Daniel Dumitriu <daniel.dumitriu@gmail.com>, 2010, 2011.
 msgid ""
 msgstr ""
 "Project-Id-Version: Mercurial\n"
 "Report-Msgid-Bugs-To: <mercurial-devel@selenic.com>\n"
-"POT-Creation-Date: 2010-08-25 11:46+0200\n"
-"PO-Revision-Date: 2010-08-26 16:19+0200\n"
+"POT-Creation-Date: 2011-06-08 15:03+0200\n"
+"PO-Revision-Date: 2011-06-08 17:00+0200\n"
 "Last-Translator: Daniel Dumitriu <daniel.dumitriu@gmail.com>\n"
 "Language-Team: Romanian <>\n"
 "MIME-Version: 1.0\n"
@@ -127,8 +127,16 @@
 msgid "Commands"
 msgstr "Comenzi"
 
-msgid "    options:"
-msgstr "    opțiuni:"
+msgid "Extensions"
+msgstr "Extensii"
+
+msgid ""
+"This section contains help for extensions that are distributed together with "
+"Mercurial. Help for other extensions is available in the help system."
+msgstr ""
+
+msgid "Options:"
+msgstr "Opțiuni:"
 
 #, python-format
 msgid "    aliases: %s"
@@ -190,10 +198,8 @@
 
 msgid ""
 "Branch-based Access Control\n"
-"---------------------------"
-msgstr ""
-"Controlul accesului pe bază de ramură\n"
-"-------------------------------------"
+"..........................."
+msgstr ""
 
 msgid ""
 "Use the ``acl.deny.branches`` and ``acl.allow.branches`` sections to\n"
@@ -223,7 +229,7 @@
 
 msgid ""
 "Path-based Access Control\n"
-"-------------------------"
+"........................."
 msgstr ""
 
 msgid ""
@@ -235,7 +241,7 @@
 
 msgid ""
 "Groups\n"
-"------"
+"......"
 msgstr ""
 
 msgid ""
@@ -252,7 +258,7 @@
 
 msgid ""
 "Example Configuration\n"
-"---------------------"
+"....................."
 msgstr ""
 
 msgid "::"
@@ -395,289 +401,236 @@
 msgid "acl: access denied for changeset %s"
 msgstr ""
 
-msgid "track a line of development with movable markers"
-msgstr ""
-
-msgid ""
-"Bookmarks are local movable markers to changesets. Every bookmark\n"
-"points to a changeset identified by its hash. If you commit a\n"
-"changeset that is based on a changeset that has a bookmark on it, the\n"
-"bookmark shifts to the new changeset."
-msgstr ""
-
-msgid ""
-"It is possible to use bookmark names in every revision lookup (e.g.\n"
-":hg:`merge`, :hg:`update`)."
-msgstr ""
-
-msgid ""
-"By default, when several bookmarks point to the same changeset, they\n"
-"will all move forward together. It is possible to obtain a more\n"
-"git-like experience by adding the following configuration option to\n"
-"your .hgrc::"
-msgstr ""
-
-msgid ""
-"  [bookmarks]\n"
-"  track.current = True"
-msgstr ""
-
-msgid ""
-"This will cause Mercurial to track the bookmark that you are currently\n"
-"using, and only update it. This is similar to git's approach to\n"
-"branching.\n"
-msgstr ""
-
-msgid ""
-"    Bookmarks are pointers to certain commits that move when\n"
-"    committing. Bookmarks are local. They can be renamed, copied and\n"
-"    deleted. It is possible to use bookmark names in :hg:`merge` and\n"
-"    :hg:`update` to merge and update respectively to a given bookmark."
-msgstr ""
-
-msgid ""
-"    You can use :hg:`bookmark NAME` to set a bookmark on the working\n"
-"    directory's parent revision with the given name. If you specify\n"
-"    a revision using -r REV (where REV may be an existing bookmark),\n"
-"    the bookmark is assigned to that revision.\n"
-"    "
-msgstr ""
-
-msgid "a bookmark of this name does not exist"
-msgstr ""
-
-msgid "a bookmark of the same name already exists"
-msgstr ""
-
-msgid "new bookmark name required"
-msgstr ""
-
-msgid "bookmark name required"
-msgstr ""
-
-msgid "bookmark name cannot contain newlines"
-msgstr ""
-
-msgid "bookmark names cannot consist entirely of whitespace"
-msgstr ""
-
-msgid "a bookmark cannot have the name of an existing branch"
-msgstr ""
-
-msgid "no bookmarks set\n"
-msgstr ""
-
-#, python-format
-msgid "updating bookmark %s\n"
-msgstr "se actualizează semnul de carte %s\n"
-
-#, python-format
-msgid "not updating divergent bookmark %s\n"
-msgstr "nu se actualizează semnul de carte divergent %s\n"
-
-#, python-format
-msgid "updating bookmark %s failed!\n"
-msgstr "actualizarea semnului de carte %s a eșuat!\n"
-
-#, python-format
-msgid "remote bookmark %s not found!"
-msgstr ""
-
-#, python-format
-msgid "importing bookmark %s\n"
-msgstr ""
-
-#, python-format
-msgid "exporting bookmark %s\n"
-msgstr ""
-
-#, python-format
-msgid "deleting remote bookmark %s\n"
-msgstr ""
-
-#, python-format
-msgid "bookmark %s does not exist on the local or remote repository!\n"
-msgstr ""
-
-msgid "searching for changes\n"
-msgstr "se caută modificări\n"
-
-msgid "no changes found\n"
-msgstr "nu s-au găsit modificări\n"
-
-#, python-format
-msgid "comparing with %s\n"
-msgstr "se compară cu %s\n"
-
-msgid "bookmark to import"
-msgstr ""
-
-msgid "bookmark to export"
-msgstr ""
-
-msgid "compare bookmark"
-msgstr ""
-
-msgid "force"
-msgstr ""
-
-msgid "REV"
-msgstr "REV"
-
-msgid "revision"
-msgstr "revizia"
-
-msgid "delete a given bookmark"
-msgstr ""
-
-msgid "NAME"
-msgstr "NUME"
-
-msgid "rename a given bookmark"
-msgstr ""
-
-msgid "hg bookmarks [-f] [-d] [-m NAME] [-r REV] [NAME]"
-msgstr ""
-
 msgid "hooks for integrating with the Bugzilla bug tracker"
 msgstr ""
 
 msgid ""
 "This hook extension adds comments on bugs in Bugzilla when changesets\n"
-"that refer to bugs by Bugzilla ID are seen. The hook does not change\n"
-"bug status."
-msgstr ""
-
-msgid ""
-"The hook updates the Bugzilla database directly. Only Bugzilla\n"
-"installations using MySQL are supported."
-msgstr ""
-
-msgid ""
-"The hook relies on a Bugzilla script to send bug change notification\n"
-"emails. That script changes between Bugzilla versions; the\n"
-"'processmail' script used prior to 2.18 is replaced in 2.18 and\n"
-"subsequent versions by 'config/sendbugmail.pl'. Note that these will\n"
-"be run by Mercurial as the user pushing the change; you will need to\n"
-"ensure the Bugzilla install file permissions are set appropriately."
-msgstr ""
-
-msgid ""
-"The extension is configured through three different configuration\n"
-"sections. These keys are recognized in the [bugzilla] section:"
-msgstr ""
-
-msgid ""
-"host\n"
-"  Hostname of the MySQL server holding the Bugzilla database."
-msgstr ""
-
-msgid ""
-"db\n"
-"  Name of the Bugzilla database in MySQL. Default 'bugs'."
-msgstr ""
-
-msgid ""
-"user\n"
-"  Username to use to access MySQL server. Default 'bugs'."
-msgstr ""
-
-msgid ""
-"password\n"
+"that refer to bugs by Bugzilla ID are seen. The comment is formatted using\n"
+"the Mercurial template mechanism."
+msgstr ""
+
+msgid "The hook does not change bug status."
+msgstr ""
+
+msgid "Three basic modes of access to Bugzilla are provided:"
+msgstr ""
+
+msgid ""
+"1. Access via the Bugzilla XMLRPC interface. Requires Bugzilla 3.4 or later."
+msgstr ""
+
+msgid ""
+"2. Check data via the Bugzilla XMLRPC interface and submit bug change\n"
+"   via email to Bugzilla email interface. Requires Bugzilla 3.4 or later."
+msgstr ""
+
+msgid ""
+"3. Writing directly to the Bugzilla database. Only Bugzilla installations\n"
+"   using MySQL are supported. Requires Python MySQLdb."
+msgstr ""
+
+msgid ""
+"Writing directly to the database is susceptible to schema changes, and\n"
+"relies on a Bugzilla contrib script to send out bug change\n"
+"notification emails. This script runs as the user running Mercurial,\n"
+"must be run on the host with the Bugzilla install, and requires\n"
+"permission to read Bugzilla configuration details and the necessary\n"
+"MySQL user and password to have full access rights to the Bugzilla\n"
+"database. For these reasons this access mode is now considered\n"
+"deprecated, and will not be updated for new Bugzilla versions going\n"
+"forward."
+msgstr ""
+
+msgid ""
+"Access via XMLRPC needs a Bugzilla username and password to be specified\n"
+"in the configuration. Comments are added under that username. Since the\n"
+"configuration must be readable by all Mercurial users, it is recommended\n"
+"that the rights of that user are restricted in Bugzilla to the minimum\n"
+"necessary to add comments."
+msgstr ""
+
+msgid ""
+"Access via XMLRPC/email uses XMLRPC to query Bugzilla, but sends\n"
+"email to the Bugzilla email interface to submit comments to bugs.\n"
+"The From: address in the email is set to the email address of the Mercurial\n"
+"user, so the comment appears to come from the Mercurial user. In the event\n"
+"that the Mercurial user email is not recognised by Bugzilla as a Bugzilla\n"
+"user, the email associated with the Bugzilla username used to log into\n"
+"Bugzilla is used instead as the source of the comment."
+msgstr ""
+
+msgid "Configuration items common to all access modes:"
+msgstr ""
+
+msgid ""
+"bugzilla.version\n"
+"  This access type to use. Values recognised are:"
+msgstr ""
+
+msgid ""
+"  :``xmlrpc``:       Bugzilla XMLRPC interface.\n"
+"  :``xmlrpc+email``: Bugzilla XMLRPC and email interfaces.\n"
+"  :``3.0``:          MySQL access, Bugzilla 3.0 and later.\n"
+"  :``2.18``:         MySQL access, Bugzilla 2.18 and up to but not\n"
+"                     including 3.0.\n"
+"  :``2.16``:         MySQL access, Bugzilla 2.16 and up to but not\n"
+"                     including 2.18."
+msgstr ""
+
+msgid ""
+"bugzilla.regexp\n"
+"  Regular expression to match bug IDs in changeset commit message.\n"
+"  Must contain one \"()\" group. The default expression matches ``Bug\n"
+"  1234``, ``Bug no. 1234``, ``Bug number 1234``, ``Bugs 1234,5678``,\n"
+"  ``Bug 1234 and 5678`` and variations thereof. Matching is case\n"
+"  insensitive."
+msgstr ""
+
+msgid ""
+"bugzilla.style\n"
+"  The style file to use when formatting comments."
+msgstr ""
+
+msgid ""
+"bugzilla.template\n"
+"  Template to use when formatting comments. Overrides style if\n"
+"  specified. In addition to the usual Mercurial keywords, the\n"
+"  extension specifies:"
+msgstr ""
+
+msgid ""
+"  :``{bug}``:     The Bugzilla bug ID.\n"
+"  :``{root}``:    The full pathname of the Mercurial repository.\n"
+"  :``{webroot}``: Stripped pathname of the Mercurial repository.\n"
+"  :``{hgweb}``:   Base URL for browsing Mercurial repositories."
+msgstr ""
+
+msgid ""
+"  Default ``changeset {node|short} in repo {root} refers to bug\n"
+"  {bug}.\\ndetails:\\n\\t{desc|tabindent}``"
+msgstr ""
+
+msgid ""
+"bugzilla.strip\n"
+"  The number of path separator characters to strip from the front of\n"
+"  the Mercurial repository path (``{root}`` in templates) to produce\n"
+"  ``{webroot}``. For example, a repository with ``{root}``\n"
+"  ``/var/local/my-project`` with a strip of 2 gives a value for\n"
+"  ``{webroot}`` of ``my-project``. Default 0."
+msgstr ""
+
+msgid ""
+"web.baseurl\n"
+"  Base URL for browsing Mercurial repositories. Referenced from\n"
+"  templates as ``{hgweb}``."
+msgstr ""
+
+msgid "Configuration items common to XMLRPC+email and MySQL access modes:"
+msgstr ""
+
+msgid ""
+"bugzilla.usermap\n"
+"  Path of file containing Mercurial committer email to Bugzilla user email\n"
+"  mappings. If specified, the file should contain one mapping per\n"
+"  line::"
+msgstr ""
+
+msgid "    committer = Bugzilla user"
+msgstr ""
+
+msgid "  See also the ``[usermap]`` section."
+msgstr ""
+
+msgid ""
+"The ``[usermap]`` section is used to specify mappings of Mercurial\n"
+"committer email to Bugzilla user email. See also ``bugzilla.usermap``.\n"
+"Contains entries of the form ``committer = Bugzilla user``."
+msgstr ""
+
+msgid "XMLRPC access mode configuration:"
+msgstr ""
+
+msgid ""
+"bugzilla.bzurl\n"
+"  The base URL for the Bugzilla installation.\n"
+"  Default ``http://localhost/bugzilla``."
+msgstr ""
+
+msgid ""
+"bugzilla.user\n"
+"  The username to use to log into Bugzilla via XMLRPC. Default\n"
+"  ``bugs``."
+msgstr ""
+
+msgid ""
+"bugzilla.password\n"
+"  The password for Bugzilla login."
+msgstr ""
+
+msgid ""
+"XMLRPC+email access mode uses the XMLRPC access mode configuration items,\n"
+"and also:"
+msgstr ""
+
+msgid ""
+"bugzilla.bzemail\n"
+"  The Bugzilla email address."
+msgstr ""
+
+msgid ""
+"In addition, the Mercurial email settings must be configured. See the\n"
+"documentation in hgrc(5), sections ``[email]`` and ``[smtp]``."
+msgstr ""
+
+msgid "MySQL access mode configuration:"
+msgstr ""
+
+msgid ""
+"bugzilla.host\n"
+"  Hostname of the MySQL server holding the Bugzilla database.\n"
+"  Default ``localhost``."
+msgstr ""
+
+msgid ""
+"bugzilla.db\n"
+"  Name of the Bugzilla database in MySQL. Default ``bugs``."
+msgstr ""
+
+msgid ""
+"bugzilla.user\n"
+"  Username to use to access MySQL server. Default ``bugs``."
+msgstr ""
+
+msgid ""
+"bugzilla.password\n"
 "  Password to use to access MySQL server."
 msgstr ""
 
 msgid ""
-"timeout\n"
+"bugzilla.timeout\n"
 "  Database connection timeout (seconds). Default 5."
 msgstr ""
 
 msgid ""
-"version\n"
-"  Bugzilla version. Specify '3.0' for Bugzilla versions 3.0 and later,\n"
-"  '2.18' for Bugzilla versions from 2.18 and '2.16' for versions prior\n"
-"  to 2.18."
-msgstr ""
-
-msgid ""
-"bzuser\n"
+"bugzilla.bzuser\n"
 "  Fallback Bugzilla user name to record comments with, if changeset\n"
 "  committer cannot be found as a Bugzilla user."
 msgstr ""
 
 msgid ""
-"bzdir\n"
+"bugzilla.bzdir\n"
 "   Bugzilla install directory. Used by default notify. Default\n"
-"   '/var/www/html/bugzilla'."
-msgstr ""
-
-msgid ""
-"notify\n"
+"   ``/var/www/html/bugzilla``."
+msgstr ""
+
+msgid ""
+"bugzilla.notify\n"
 "  The command to run to get Bugzilla to send bug change notification\n"
-"  emails. Substitutes from a map with 3 keys, 'bzdir', 'id' (bug id)\n"
-"  and 'user' (committer bugzilla email). Default depends on version;\n"
-"  from 2.18 it is \"cd %(bzdir)s && perl -T contrib/sendbugmail.pl\n"
-"  %(id)s %(user)s\"."
-msgstr ""
-
-msgid ""
-"regexp\n"
-"  Regular expression to match bug IDs in changeset commit message.\n"
-"  Must contain one \"()\" group. The default expression matches 'Bug\n"
-"  1234', 'Bug no. 1234', 'Bug number 1234', 'Bugs 1234,5678', 'Bug\n"
-"  1234 and 5678' and variations thereof. Matching is case insensitive."
-msgstr ""
-
-msgid ""
-"style\n"
-"  The style file to use when formatting comments."
-msgstr ""
-
-msgid ""
-"template\n"
-"  Template to use when formatting comments. Overrides style if\n"
-"  specified. In addition to the usual Mercurial keywords, the\n"
-"  extension specifies::"
-msgstr ""
-
-msgid ""
-"    {bug}       The Bugzilla bug ID.\n"
-"    {root}      The full pathname of the Mercurial repository.\n"
-"    {webroot}   Stripped pathname of the Mercurial repository.\n"
-"    {hgweb}     Base URL for browsing Mercurial repositories."
-msgstr ""
-
-msgid ""
-"  Default 'changeset {node|short} in repo {root} refers '\n"
-"          'to bug {bug}.\\ndetails:\\n\\t{desc|tabindent}'"
-msgstr ""
-
-msgid ""
-"strip\n"
-"  The number of slashes to strip from the front of {root} to produce\n"
-"  {webroot}. Default 0."
-msgstr ""
-
-msgid ""
-"usermap\n"
-"  Path of file containing Mercurial committer ID to Bugzilla user ID\n"
-"  mappings. If specified, the file should contain one mapping per\n"
-"  line, \"committer\"=\"Bugzilla user\". See also the [usermap] section."
-msgstr ""
-
-msgid ""
-"The [usermap] section is used to specify mappings of Mercurial\n"
-"committer ID to Bugzilla user ID. See also [bugzilla].usermap.\n"
-"\"committer\"=\"Bugzilla user\""
-msgstr ""
-
-msgid "Finally, the [web] section supports one entry:"
-msgstr ""
-
-msgid ""
-"baseurl\n"
-"  Base URL for browsing Mercurial repositories. Reference from\n"
-"  templates as {hgweb}."
+"  emails. Substitutes from a map with 3 keys, ``bzdir``, ``id`` (bug\n"
+"  id) and ``user`` (committer bugzilla email). Default depends on\n"
+"  version; from 2.18 it is \"cd %(bzdir)s && perl -T\n"
+"  contrib/sendbugmail.pl %(id)s %(user)s\"."
 msgstr ""
 
 msgid "Activating the extension::"
@@ -694,13 +647,69 @@
 "    incoming.bugzilla = python:hgext.bugzilla.hook"
 msgstr ""
 
-msgid "Example configuration:"
-msgstr ""
-
-msgid ""
-"This example configuration is for a collection of Mercurial\n"
-"repositories in /var/local/hg/repos/ used with a local Bugzilla 3.2\n"
-"installation in /opt/bugzilla-3.2. ::"
+msgid "Example configurations:"
+msgstr "Configurări exemplu:"
+
+msgid ""
+"XMLRPC example configuration. This uses the Bugzilla at\n"
+"``http://my-project.org/bugzilla``, logging in as user\n"
+"``bugmail@my-project.org`` with password ``plugh``. It is used with a\n"
+"collection of Mercurial repositories in ``/var/local/hg/repos/``,\n"
+"with a web interface at ``http://my-project.org/hg``. ::"
+msgstr ""
+
+msgid ""
+"    [bugzilla]\n"
+"    bzurl=http://my-project.org/bugzilla\n"
+"    user=bugmail@my-project.org\n"
+"    password=plugh\n"
+"    version=xmlrpc\n"
+"    template=Changeset {node|short} in {root|basename}.\n"
+"             {hgweb}/{webroot}/rev/{node|short}\\n\n"
+"             {desc}\\n\n"
+"    strip=5"
+msgstr ""
+
+msgid ""
+"    [web]\n"
+"    baseurl=http://my-project.org/hg"
+msgstr ""
+
+msgid ""
+"XMLRPC+email example configuration. This uses the Bugzilla at\n"
+"``http://my-project.org/bugzilla``, logging in as user\n"
+"``bugmail@my-project.org`` wityh password ``plugh``. It is used with a\n"
+"collection of Mercurial repositories in ``/var/local/hg/repos/``,\n"
+"with a web interface at ``http://my-project.org/hg``. Bug comments\n"
+"are sent to the Bugzilla email address\n"
+"``bugzilla@my-project.org``. ::"
+msgstr ""
+
+msgid ""
+"    [bugzilla]\n"
+"    bzurl=http://my-project.org/bugzilla\n"
+"    user=bugmail@my-project.org\n"
+"    password=plugh\n"
+"    version=xmlrpc\n"
+"    bzemail=bugzilla@my-project.org\n"
+"    template=Changeset {node|short} in {root|basename}.\n"
+"             {hgweb}/{webroot}/rev/{node|short}\\n\n"
+"             {desc}\\n\n"
+"    strip=5"
+msgstr ""
+
+msgid ""
+"    [usermap]\n"
+"    user@emaildomain.com=user.name@bugzilladomain.com"
+msgstr ""
+
+msgid ""
+"MySQL example configuration. This has a local Bugzilla 3.2 installation\n"
+"in ``/opt/bugzilla-3.2``. The MySQL database is on ``localhost``,\n"
+"the Bugzilla database name is ``bugs`` and MySQL is\n"
+"accessed with MySQL username ``bugs`` password ``XYZZY``. It is used\n"
+"with a collection of Mercurial repositories in ``/var/local/hg/repos/``,\n"
+"with a web interface at ``http://my-project.org/hg``. ::"
 msgstr ""
 
 msgid ""
@@ -716,28 +725,22 @@
 "    strip=5"
 msgstr ""
 
-msgid ""
-"    [web]\n"
-"    baseurl=http://dev.domain.com/hg"
-msgstr ""
-
-msgid ""
-"    [usermap]\n"
-"    user@emaildomain.com=user.name@bugzilladomain.com"
-msgstr ""
-
-msgid "Commits add a comment to the Bugzilla bug record of the form::"
+msgid "All the above add a comment to the Bugzilla bug record of the form::"
 msgstr ""
 
 msgid ""
 "    Changeset 3b16791d6642 in repository-name.\n"
-"    http://dev.domain.com/hg/repository-name/rev/3b16791d6642"
+"    http://my-project.org/hg/repository-name/rev/3b16791d6642"
 msgstr ""
 
 msgid "    Changeset commit comment. Bug 1234.\n"
 msgstr ""
 
 #, python-format
+msgid "python mysql support not available: %s"
+msgstr ""
+
+#, python-format
 msgid "connecting to %s:%s as %s, password %s\n"
 msgstr ""
 
@@ -786,6 +789,13 @@
 msgid "cannot find bugzilla user id for %s or %s"
 msgstr ""
 
+msgid "configuration 'bzemail' missing"
+msgstr "Lipsește configurarea 'bzemail'"
+
+#, python-format
+msgid "default bugzilla user %s email not found"
+msgstr "Nu s-a găsit email-ul utilizatorului bugzilla implicit %s "
+
 #, python-format
 msgid "bugzilla version %s not supported"
 msgstr ""
@@ -797,19 +807,15 @@
 msgstr ""
 
 #, python-format
-msgid "python mysql support not available: %s"
-msgstr ""
-
-#, python-format
 msgid "hook type %s does not pass a changeset id"
 msgstr ""
 
 #, python-format
-msgid "database error: %s"
-msgstr ""
+msgid "Bugzilla error: %s"
+msgstr "Eroare Bugzilla: %s"
 
 msgid "command to display child changesets"
-msgstr ""
+msgstr "comandă pentru afișarea seturilor de modificări fii"
 
 msgid "show the children of the given or working directory revision"
 msgstr "afișează copiii reviziei specificate sau a celei din directorul curent"
@@ -823,6 +829,9 @@
 "    "
 msgstr ""
 
+msgid "REV"
+msgstr "REV"
+
 msgid "show children of the specified revision"
 msgstr "afișează fiii reviziei specificate"
 
@@ -830,7 +839,7 @@
 msgstr ""
 
 msgid "command to display statistics about repository history"
-msgstr ""
+msgstr "comandă pentru afișarea statisticilor despre istoricul depozitului"
 
 #, python-format
 msgid "Revision %d is a merge, ignoring...\n"
@@ -893,6 +902,10 @@
 "    "
 msgstr ""
 
+#, python-format
+msgid "skipping malformed alias: %s\n"
+msgstr "se omite alias-ul eronat %s\n"
+
 msgid "count rate for the specified revision or range"
 msgstr ""
 
@@ -933,25 +946,25 @@
 msgstr ""
 
 msgid "colorize output from some commands"
-msgstr ""
-
-msgid ""
-"This extension modifies the status and resolve commands to add color to "
-"their\n"
-"output to reflect file status, the qseries command to add color to reflect\n"
-"patch status (applied, unapplied, missing), and to diff-related\n"
-"commands to highlight additions, removals, diff headers, and trailing\n"
-"whitespace."
+msgstr "colorează afișajul unor comenzi"
+
+msgid ""
+"This extension modifies the status and resolve commands to add color\n"
+"to their output to reflect file status, the qseries command to add\n"
+"color to reflect patch status (applied, unapplied, missing), and to\n"
+"diff-related commands to highlight additions, removals, diff headers,\n"
+"and trailing whitespace."
 msgstr ""
 
 msgid ""
 "Other effects in addition to color, like bold and underlined text, are\n"
-"also available. Effects are rendered with the ECMA-48 SGR control\n"
-"function (aka ANSI escape codes). This module also provides the\n"
-"render_text function, which can be used to add effects to any text."
-msgstr ""
-
-msgid "Default effects may be overridden from the .hgrc file::"
+"also available. By default, the terminfo database is used to find the\n"
+"terminal codes used to change color and effect.  If terminfo is not\n"
+"available, then effects are rendered with the ECMA-48 SGR control\n"
+"function (aka ANSI escape codes)."
+msgstr ""
+
+msgid "Default effects may be overridden from your configuration file::"
 msgstr ""
 
 msgid ""
@@ -1004,8 +1017,37 @@
 msgstr ""
 
 msgid ""
-"The color extension will try to detect whether to use ANSI codes or\n"
-"Win32 console APIs, unless it is made explicit::"
+"The available effects in terminfo mode are 'blink', 'bold', 'dim',\n"
+"'inverse', 'invisible', 'italic', 'standout', and 'underline'; in\n"
+"ECMA-48 mode, the options are 'bold', 'inverse', 'italic', and\n"
+"'underline'.  How each is rendered depends on the terminal emulator.\n"
+"Some may not be available for a given terminal type, and will be\n"
+"silently ignored."
+msgstr ""
+
+msgid ""
+"Because there are only eight standard colors, this module allows you\n"
+"to define color names for other color slots which might be available\n"
+"for your terminal type, assuming terminfo mode.  For instance::"
+msgstr ""
+
+msgid ""
+"  color.brightblue = 12\n"
+"  color.pink = 207\n"
+"  color.orange = 202"
+msgstr ""
+
+msgid ""
+"to set 'brightblue' to color slot 12 (useful for 16 color terminals\n"
+"that have brighter colors defined in the upper eight) and, 'pink' and\n"
+"'orange' to colors in 256-color xterm's default color cube.  These\n"
+"defined colors may then be used as any of the pre-defined eight,\n"
+"including appending '_background' to set the background to that color."
+msgstr ""
+
+msgid ""
+"The color extension will try to detect whether to use terminfo, ANSI\n"
+"codes or Win32 console APIs, unless it is made explicit; e.g.::"
 msgstr ""
 
 msgid ""
@@ -1013,24 +1055,35 @@
 "  mode = ansi"
 msgstr ""
 
-msgid "Any value other than 'ansi', 'win32', or 'auto' will disable color."
+msgid ""
+"Any value other than 'ansi', 'win32', 'terminfo', or 'auto' will\n"
+"disable color."
+msgstr ""
+
+msgid "no terminfo entry for setab/setaf: reverting to ECMA-48 color\n"
+msgstr ""
+
+#, python-format
+msgid "warning: failed to set color mode to %s\n"
 msgstr ""
 
 #, python-format
 msgid "ignoring unknown color/effect %r (configured in color.%s)\n"
 msgstr ""
 
-msgid "win32console not found, please install pywin32\n"
-msgstr ""
-
-msgid "when to colorize (always, auto, or never)"
-msgstr "când să se coloreze (întotdeauna, auto, sau niciodată)"
+#. i18n: 'always', 'auto', and 'never' are keywords and should
+#. not be translated
+msgid "when to colorize (boolean, always, auto, or never)"
+msgstr ""
+"când să se coloreze (boolean, `always`=întotdeauna, auto, sau "
+"`never`=niciodată)"
 
 msgid "TYPE"
 msgstr ""
 
 msgid "import revisions from foreign VCS repositories into Mercurial"
 msgstr ""
+"importă în Mercurial revizii din alte sisteme de control al versiunilor"
 
 msgid "convert a foreign SCM repository to a Mercurial one."
 msgstr ""
@@ -1066,9 +1119,12 @@
 
 msgid ""
 "    If no destination directory name is specified, it defaults to the\n"
-"    basename of the source with '-hg' appended. If the destination\n"
+"    basename of the source with ``-hg`` appended. If the destination\n"
 "    repository doesn't exist, it will be created."
 msgstr ""
+"    Dacă nu se specifică numele directorului destinație, acesta va fi\n"
+"    implicit numele de bază (basename) al sursei, plus sufixul ``-hg``.\n"
+"    Dacă depozitul destinație nu există, va fi creat."
 
 msgid ""
 "    By default, all sources except Mercurial will use --branchsort.\n"
@@ -1095,10 +1151,10 @@
 msgstr ""
 
 msgid ""
-"    If <REVMAP> isn't given, it will be put in a default location\n"
-"    (<dest>/.hg/shamap by default). The <REVMAP> is a simple text file\n"
-"    that maps each source commit ID to the destination ID for that\n"
-"    revision, like so::"
+"    If ``REVMAP`` isn't given, it will be put in a default location\n"
+"    (``<dest>/.hg/shamap`` by default). The ``REVMAP`` is a simple\n"
+"    text file that maps each source commit ID to the destination ID\n"
+"    for that revision, like so::"
 msgstr ""
 
 msgid "      <source ID> <destination ID>"
@@ -1106,16 +1162,21 @@
 
 msgid ""
 "    If the file doesn't exist, it's automatically created. It's\n"
-"    updated on each commit copied, so convert-repo can be interrupted\n"
+"    updated on each commit copied, so :hg:`convert` can be interrupted\n"
 "    and can be run repeatedly to copy new commits."
 msgstr ""
 
 msgid ""
-"    The [username mapping] file is a simple text file that maps each\n"
-"    source commit author to a destination commit author. It is handy\n"
-"    for source SCMs that use unix logins to identify authors (eg:\n"
-"    CVS). One line per author mapping and the line format is:\n"
-"    srcauthor=whatever string you want"
+"    The authormap is a simple text file that maps each source commit\n"
+"    author to a destination commit author. It is handy for source SCMs\n"
+"    that use unix logins to identify authors (eg: CVS). One line per\n"
+"    author mapping and the line format is::"
+msgstr ""
+
+msgid "      source author = destination author"
+msgstr ""
+
+msgid "    Empty lines and lines starting with a ``#`` are ignored."
 msgstr ""
 
 msgid ""
@@ -1134,20 +1195,20 @@
 msgstr ""
 
 msgid ""
-"    Comment lines start with '#'. A specified path matches if it\n"
+"    Comment lines start with ``#``. A specified path matches if it\n"
 "    equals the full relative name of a file or one of its parent\n"
-"    directories. The 'include' or 'exclude' directive with the longest\n"
-"    matching path applies, so line order does not matter."
-msgstr ""
-
-msgid ""
-"    The 'include' directive causes a file, or all files under a\n"
+"    directories. The ``include`` or ``exclude`` directive with the\n"
+"    longest matching path applies, so line order does not matter."
+msgstr ""
+
+msgid ""
+"    The ``include`` directive causes a file, or all files under a\n"
 "    directory, to be included in the destination repository, and the\n"
 "    exclusion of all other files and directories not explicitly\n"
-"    included. The 'exclude' directive causes files or directories to\n"
-"    be omitted. The 'rename' directive renames a file or directory if\n"
+"    included. The ``exclude`` directive causes files or directories to\n"
+"    be omitted. The ``rename`` directive renames a file or directory if\n"
 "    it is converted. To rename from a subdirectory into the root of\n"
-"    the repository, use '.' as the path to rename to."
+"    the repository, use ``.`` as the path to rename to."
 msgstr ""
 
 msgid ""
@@ -1156,7 +1217,14 @@
 "    useful if you want to e.g. give a Subversion merge two parents, or\n"
 "    graft two disconnected series of history together. Each entry\n"
 "    contains a key, followed by a space, followed by one or two\n"
-"    comma-separated values. The key is the revision ID in the source\n"
+"    comma-separated values::"
+msgstr ""
+
+msgid "      key parent1, parent2"
+msgstr ""
+
+msgid ""
+"    The key is the revision ID in the source\n"
 "    revision control system whose parents should be modified (same\n"
 "    format as a key in .hg/shamap). The values are the revision IDs\n"
 "    (in either the source or destination revision control system) that\n"
@@ -1172,78 +1240,109 @@
 "    conjunction with a splicemap, it allows for a powerful combination\n"
 "    to help fix even the most badly mismanaged repositories and turn them\n"
 "    into nicely structured Mercurial repositories. The branchmap contains\n"
-"    lines of the form \"original_branch_name new_branch_name\".\n"
-"    \"original_branch_name\" is the name of the branch in the source\n"
-"    repository, and \"new_branch_name\" is the name of the branch is the\n"
-"    destination repository. This can be used to (for instance) move code\n"
-"    in one repository from \"default\" to a named branch."
+"    lines of the form::"
+msgstr ""
+
+msgid "      original_branch_name new_branch_name"
+msgstr ""
+
+msgid ""
+"    where \"original_branch_name\" is the name of the branch in the\n"
+"    source repository, and \"new_branch_name\" is the name of the branch\n"
+"    is the destination repository. No whitespace is allowed in the\n"
+"    branch names. This can be used to (for instance) move code in one\n"
+"    repository from \"default\" to a named branch."
 msgstr ""
 
 msgid ""
 "    Mercurial Source\n"
-"    ----------------"
-msgstr ""
-
-msgid ""
-"    --config convert.hg.ignoreerrors=False    (boolean)\n"
-"        ignore integrity errors when reading. Use it to fix Mercurial\n"
-"        repositories with missing revlogs, by converting from and to\n"
-"        Mercurial.\n"
-"    --config convert.hg.saverev=False         (boolean)\n"
-"        store original revision ID in changeset (forces target IDs to\n"
-"        change)\n"
-"    --config convert.hg.startrev=0            (hg revision identifier)\n"
-"        convert start revision and its descendants"
+"    ''''''''''''''''"
+msgstr ""
+
+msgid ""
+"    The Mercurial source recognizes the following configuration\n"
+"    options, which you can set on the command line with ``--config``:"
+msgstr ""
+
+msgid ""
+"    :convert.hg.ignoreerrors: ignore integrity errors when reading.\n"
+"        Use it to fix Mercurial repositories with missing revlogs, by\n"
+"        converting from and to Mercurial. Default is False."
+msgstr ""
+
+msgid ""
+"    :convert.hg.saverev: store original revision ID in changeset\n"
+"        (forces target IDs to change). It takes and boolean argument\n"
+"        and defaults to False."
+msgstr ""
+
+msgid ""
+"    :convert.hg.startrev: convert start revision and its descendants.\n"
+"        It takes a hg revision identifier and defaults to 0."
 msgstr ""
 
 msgid ""
 "    CVS Source\n"
-"    ----------"
+"    ''''''''''"
 msgstr ""
 
 msgid ""
 "    CVS source will use a sandbox (i.e. a checked-out copy) from CVS\n"
 "    to indicate the starting point of what will be converted. Direct\n"
 "    access to the repository files is not needed, unless of course the\n"
-"    repository is :local:. The conversion uses the top level directory\n"
-"    in the sandbox to find the CVS repository, and then uses CVS rlog\n"
-"    commands to find files to convert. This means that unless a\n"
-"    filemap is given, all files under the starting directory will be\n"
+"    repository is ``:local:``. The conversion uses the top level\n"
+"    directory in the sandbox to find the CVS repository, and then uses\n"
+"    CVS rlog commands to find files to convert. This means that unless\n"
+"    a filemap is given, all files under the starting directory will be\n"
 "    converted, and that any directory reorganization in the CVS\n"
 "    sandbox is ignored."
 msgstr ""
 
-msgid "    The options shown are the defaults."
-msgstr ""
-
-msgid ""
-"    --config convert.cvsps.cache=True         (boolean)\n"
-"        Set to False to disable remote log caching, for testing and\n"
-"        debugging purposes.\n"
-"    --config convert.cvsps.fuzz=60            (integer)\n"
-"        Specify the maximum time (in seconds) that is allowed between\n"
-"        commits with identical user and log message in a single\n"
-"        changeset. When very large files were checked in as part of a\n"
-"        changeset then the default may not be long enough.\n"
-"    --config convert.cvsps.mergeto='{{mergetobranch ([-\\w]+)}}'\n"
-"        Specify a regular expression to which commit log messages are\n"
-"        matched. If a match occurs, then the conversion process will\n"
-"        insert a dummy revision merging the branch on which this log\n"
-"        message occurs to the branch indicated in the regex.\n"
-"    --config convert.cvsps.mergefrom='{{mergefrombranch ([-\\w]+)}}'\n"
-"        Specify a regular expression to which commit log messages are\n"
-"        matched. If a match occurs, then the conversion process will\n"
-"        add the most recent revision on the branch indicated in the\n"
-"        regex as the second parent of the changeset.\n"
-"    --config hook.cvslog\n"
-"        Specify a Python function to be called at the end of gathering\n"
-"        the CVS log. The function is passed a list with the log entries,\n"
-"        and can modify the entries in-place, or add or delete them.\n"
-"    --config hook.cvschangesets\n"
-"        Specify a Python function to be called after the changesets\n"
-"        are calculated from the the CVS log. The function is passed\n"
-"        a list with the changeset entries, and can modify the changesets\n"
-"        in-place, or add or delete them."
+msgid "    The following options can be used with ``--config``:"
+msgstr ""
+
+msgid ""
+"    :convert.cvsps.cache: Set to False to disable remote log caching,\n"
+"        for testing and debugging purposes. Default is True."
+msgstr ""
+
+msgid ""
+"    :convert.cvsps.fuzz: Specify the maximum time (in seconds) that is\n"
+"        allowed between commits with identical user and log message in\n"
+"        a single changeset. When very large files were checked in as\n"
+"        part of a changeset then the default may not be long enough.\n"
+"        The default is 60."
+msgstr ""
+
+msgid ""
+"    :convert.cvsps.mergeto: Specify a regular expression to which\n"
+"        commit log messages are matched. If a match occurs, then the\n"
+"        conversion process will insert a dummy revision merging the\n"
+"        branch on which this log message occurs to the branch\n"
+"        indicated in the regex. Default is ``{{mergetobranch\n"
+"        ([-\\w]+)}}``"
+msgstr ""
+
+msgid ""
+"    :convert.cvsps.mergefrom: Specify a regular expression to which\n"
+"        commit log messages are matched. If a match occurs, then the\n"
+"        conversion process will add the most recent revision on the\n"
+"        branch indicated in the regex as the second parent of the\n"
+"        changeset. Default is ``{{mergefrombranch ([-\\w]+)}}``"
+msgstr ""
+
+msgid ""
+"    :hook.cvslog: Specify a Python function to be called at the end of\n"
+"        gathering the CVS log. The function is passed a list with the\n"
+"        log entries, and can modify the entries in-place, or add or\n"
+"        delete them."
+msgstr ""
+
+msgid ""
+"    :hook.cvschangesets: Specify a Python function to be called after\n"
+"        the changesets are calculated from the the CVS log. The\n"
+"        function is passed a list with the changeset entries, and can\n"
+"        modify the changesets in-place, or add or delete them."
 msgstr ""
 
 msgid ""
@@ -1255,29 +1354,38 @@
 
 msgid ""
 "    Subversion Source\n"
-"    -----------------"
+"    '''''''''''''''''"
 msgstr ""
 
 msgid ""
 "    Subversion source detects classical trunk/branches/tags layouts.\n"
-"    By default, the supplied \"svn://repo/path/\" source URL is\n"
-"    converted as a single branch. If \"svn://repo/path/trunk\" exists it\n"
-"    replaces the default branch. If \"svn://repo/path/branches\" exists,\n"
-"    its subdirectories are listed as possible branches. If\n"
-"    \"svn://repo/path/tags\" exists, it is looked for tags referencing\n"
-"    converted branches. Default \"trunk\", \"branches\" and \"tags\" values\n"
-"    can be overridden with following options. Set them to paths\n"
+"    By default, the supplied ``svn://repo/path/`` source URL is\n"
+"    converted as a single branch. If ``svn://repo/path/trunk`` exists\n"
+"    it replaces the default branch. If ``svn://repo/path/branches``\n"
+"    exists, its subdirectories are listed as possible branches. If\n"
+"    ``svn://repo/path/tags`` exists, it is looked for tags referencing\n"
+"    converted branches. Default ``trunk``, ``branches`` and ``tags``\n"
+"    values can be overridden with following options. Set them to paths\n"
 "    relative to the source URL, or leave them blank to disable auto\n"
 "    detection."
 msgstr ""
 
-msgid ""
-"    --config convert.svn.branches=branches    (directory name)\n"
-"        specify the directory containing branches\n"
-"    --config convert.svn.tags=tags            (directory name)\n"
-"        specify the directory containing tags\n"
-"    --config convert.svn.trunk=trunk          (directory name)\n"
-"        specify the name of the trunk branch"
+msgid "    The following options can be set with ``--config``:"
+msgstr ""
+
+msgid ""
+"    :convert.svn.branches: specify the directory containing branches.\n"
+"        The default is ``branches``."
+msgstr ""
+
+msgid ""
+"    :convert.svn.tags: specify the directory containing tags. The\n"
+"        default is ``tags``."
+msgstr ""
+
+msgid ""
+"    :convert.svn.trunk: specify the name of the trunk branch. The\n"
+"        default is ``trunk``."
 msgstr ""
 
 msgid ""
@@ -1287,13 +1395,13 @@
 msgstr ""
 
 msgid ""
-"    --config convert.svn.startrev=0           (svn revision number)\n"
-"        specify start Subversion revision."
+"    :convert.svn.startrev: specify start Subversion revision number.\n"
+"        The default is 0."
 msgstr ""
 
 msgid ""
 "    Perforce Source\n"
-"    ---------------"
+"    '''''''''''''''"
 msgstr ""
 
 msgid ""
@@ -1302,34 +1410,41 @@
 "    source to a flat Mercurial repository, ignoring labels, branches\n"
 "    and integrations. Note that when a depot path is given you then\n"
 "    usually should specify a target directory, because otherwise the\n"
-"    target may be named ...-hg."
+"    target may be named ``...-hg``."
 msgstr ""
 
 msgid ""
 "    It is possible to limit the amount of source history to be\n"
-"    converted by specifying an initial Perforce revision."
-msgstr ""
-
-msgid ""
-"    --config convert.p4.startrev=0            (perforce changelist number)\n"
-"        specify initial Perforce revision."
+"    converted by specifying an initial Perforce revision:"
+msgstr ""
+
+msgid ""
+"    :convert.p4.startrev: specify initial Perforce revision (a\n"
+"        Perforce changelist number)."
 msgstr ""
 
 msgid ""
 "    Mercurial Destination\n"
-"    ---------------------"
-msgstr ""
-
-msgid ""
-"    --config convert.hg.clonebranches=False   (boolean)\n"
-"        dispatch source branches in separate clones.\n"
-"    --config convert.hg.tagsbranch=default    (branch name)\n"
-"        tag revisions branch name\n"
-"    --config convert.hg.usebranchnames=True   (boolean)\n"
-"        preserve branch names"
-msgstr ""
-
-msgid "    "
+"    '''''''''''''''''''''"
+msgstr ""
+
+msgid "    The following options are supported:"
+msgstr ""
+
+msgid ""
+"    :convert.hg.clonebranches: dispatch source branches in separate\n"
+"        clones. The default is False."
+msgstr ""
+
+msgid ""
+"    :convert.hg.tagsbranch: branch name for tag revisions, defaults to\n"
+"        ``default``."
+msgstr ""
+
+msgid ""
+"    :convert.hg.usebranchnames: preserve branch names. The default is\n"
+"        True.\n"
+"    "
 msgstr ""
 
 msgid "create changeset information from CVS"
@@ -1348,21 +1463,24 @@
 "    dates."
 msgstr ""
 
-msgid "username mapping filename"
+msgid "username mapping filename (DEPRECATED, use --authormap instead)"
+msgstr ""
+
+msgid "source repository type"
 msgstr ""
 
 msgid "destination repository type"
 msgstr ""
 
+msgid "import up to target revision REV"
+msgstr ""
+
+msgid "remap usernames using this file"
+msgstr ""
+
 msgid "remap file names using contents of file"
 msgstr ""
 
-msgid "import up to target revision REV"
-msgstr ""
-
-msgid "source repository type"
-msgstr ""
-
 msgid "splice synthesized history into place"
 msgstr ""
 
@@ -1414,6 +1532,15 @@
 msgid "hg debugcvsps [OPTION]... [PATH]..."
 msgstr ""
 
+msgid ":svnrev: String. Converted subversion revision number."
+msgstr ""
+
+msgid ":svnpath: String. Converted subversion revision project path."
+msgstr ""
+
+msgid ":svnuuid: String. Converted subversion revision repository identifier."
+msgstr ""
+
 #, python-format
 msgid "%s does not look like a Bazaar repository"
 msgstr ""
@@ -1650,6 +1777,13 @@
 msgid "Python ElementTree module is not available"
 msgstr ""
 
+#, python-format
+msgid "%s repository format is unsupported, please upgrade"
+msgstr ""
+
+msgid "failed to detect repository format!"
+msgstr ""
+
 msgid "internal calling inconsistency"
 msgstr ""
 
@@ -1736,6 +1870,9 @@
 msgid "updating tags\n"
 msgstr "se actualizează etichetele\n"
 
+msgid "updating bookmarks\n"
+msgstr "se actualizează semnele de carte\n"
+
 #, python-format
 msgid "%s is not a valid start revision"
 msgstr ""
@@ -1748,10 +1885,45 @@
 msgid "%s does not look like a monotone repository"
 msgstr ""
 
+msgid "bad mtn packet - no end of commandnbr"
+msgstr ""
+
+#, python-format
+msgid "bad mtn packet - bad stream type %s"
+msgstr ""
+
+msgid "bad mtn packet - no divider before size"
+msgstr ""
+
+msgid "bad mtn packet - no end of packet size"
+msgstr ""
+
+#, python-format
+msgid "bad mtn packet - bad packet size %s"
+msgstr ""
+
+#, python-format
+msgid "bad mtn packet - unable to read full packet read %s of %s"
+msgstr ""
+
+#, python-format
+msgid "mtn command '%s' returned %s"
+msgstr ""
+
 #, python-format
 msgid "copying file in renamed directory from '%s' to '%s'"
 msgstr ""
 
+msgid "unable to determine mtn automate interface version"
+msgstr ""
+
+#, python-format
+msgid "mtn automate stdio header unexpected: %s"
+msgstr ""
+
+msgid "failed to reach end of mtn automate stdio headers"
+msgstr ""
+
 #, python-format
 msgid "%s does not look like a P4 repository"
 msgstr ""
@@ -1774,7 +1946,7 @@
 msgid "%s does not look like a Subversion repository"
 msgstr "%s nu pare a fi un depozit Subversion"
 
-msgid "Subversion python bindings could not be loaded"
+msgid "Could not load Subversion python bindings"
 msgstr ""
 
 #, python-format
@@ -1867,27 +2039,29 @@
 
 msgid ""
 "The extension reads its configuration from a versioned ``.hgeol``\n"
-"configuration file every time you run an ``hg`` command. The\n"
+"configuration file found in the root of the working copy. The\n"
 "``.hgeol`` file use the same syntax as all other Mercurial\n"
 "configuration files. It uses two sections, ``[patterns]`` and\n"
 "``[repository]``."
 msgstr ""
 
 msgid ""
-"The ``[patterns]`` section specifies the line endings used in the\n"
-"working directory. The format is specified by a file pattern. The\n"
-"first match is used, so put more specific patterns first. The\n"
-"available line endings are ``LF``, ``CRLF``, and ``BIN``."
+"The ``[patterns]`` section specifies how line endings should be\n"
+"converted between the working copy and the repository. The format is\n"
+"specified by a file pattern. The first match is used, so put more\n"
+"specific patterns first. The available line endings are ``LF``,\n"
+"``CRLF``, and ``BIN``."
 msgstr ""
 
 msgid ""
 "Files with the declared format of ``CRLF`` or ``LF`` are always\n"
-"checked out in that format and files declared to be binary (``BIN``)\n"
-"are left unchanged. Additionally, ``native`` is an alias for the\n"
-"platform's default line ending: ``LF`` on Unix (including Mac OS X)\n"
-"and ``CRLF`` on Windows. Note that ``BIN`` (do nothing to line\n"
-"endings) is Mercurial's default behaviour; it is only needed if you\n"
-"need to override a later, more general pattern."
+"checked out and stored in the repository in that format and files\n"
+"declared to be binary (``BIN``) are left unchanged. Additionally,\n"
+"``native`` is an alias for checking out in the platform's default line\n"
+"ending: ``LF`` on Unix (including Mac OS X) and ``CRLF`` on\n"
+"Windows. Note that ``BIN`` (do nothing to line endings) is Mercurial's\n"
+"default behaviour; it is only needed if you need to override a later,\n"
+"more general pattern."
 msgstr ""
 
 msgid ""
@@ -1920,6 +2094,12 @@
 msgstr ""
 
 msgid ""
+".. note::\n"
+"   The rules will first apply when files are touched in the working\n"
+"   copy, e.g. by updating to null and back to tip to touch all files."
+msgstr ""
+
+msgid ""
 "The extension uses an optional ``[eol]`` section in your hgrc file\n"
 "(not the ``.hgeol`` file) for settings that control the overall\n"
 "behavior. There are two settings:"
@@ -1927,7 +2107,7 @@
 
 msgid ""
 "- ``eol.native`` (default ``os.linesep``) can be set to ``LF`` or\n"
-"  ``CRLF`` override the default interpretation of ``native`` for\n"
+"  ``CRLF`` to override the default interpretation of ``native`` for\n"
 "  checkout. This can be used with :hg:`archive` on Unix, say, to\n"
 "  generate an archive where files have line endings for Windows."
 msgstr ""
@@ -1941,26 +2121,47 @@
 msgstr ""
 
 msgid ""
+"The extension provides ``cleverencode:`` and ``cleverdecode:`` filters\n"
+"like the deprecated win32text extension does. This means that you can\n"
+"disable win32text and enable eol and your filters will still work. You\n"
+"only need to these filters until you have prepared a ``.hgeol`` file."
+msgstr ""
+
+msgid ""
+"The ``win32text.forbid*`` hooks provided by the win32text extension\n"
+"have been unified into a single hook named ``eol.checkheadshook``. The\n"
+"hook will lookup the expected line endings from the ``.hgeol`` file,\n"
+"which means you must migrate to a ``.hgeol`` file first before using\n"
+"the hook. ``eol.checkheadshook`` only checks heads, intermediate\n"
+"invalid revisions will be pushed. To forbid them completely, use the\n"
+"``eol.checkallhook`` hook. These hooks are best used as\n"
+"``pretxnchangegroup`` hooks."
+msgstr ""
+
+msgid ""
 "See :hg:`help patterns` for more information about the glob patterns\n"
 "used.\n"
 msgstr ""
 
 #, python-format
-msgid "%s should not have CRLF line endings"
-msgstr ""
-
-#, python-format
-msgid "%s should not have LF line endings"
-msgstr ""
-
-msgid "the eol extension is incompatible with the win32text extension"
-msgstr ""
-
-#, python-format
 msgid "ignoring unknown EOL style '%s' from %s\n"
 msgstr ""
 
 #, python-format
+msgid "warning: ignoring .hgeol file due to parse error at %s: %s\n"
+msgstr ""
+
+#, python-format
+msgid "  %s in %s should not have %s line endings"
+msgstr ""
+
+msgid "end-of-line check failed:\n"
+msgstr ""
+
+msgid "the eol extension is incompatible with the win32text extension\n"
+msgstr ""
+
+#, python-format
 msgid "inconsistent newline style in %s\n"
 msgstr ""
 
@@ -1976,7 +2177,7 @@
 msgstr ""
 
 msgid ""
-"The extdiff extension also allows to configure new diff commands, so\n"
+"The extdiff extension also allows you to configure new diff commands, so\n"
 "you do not need to type :hg:`extdiff -p kdiff3` always. ::"
 msgstr ""
 
@@ -2014,6 +2215,7 @@
 "  $parent1, $plabel1 - filename, descriptive label of first parent\n"
 "  $child,   $clabel  - filename, descriptive label of child revision\n"
 "  $parent2, $plabel2 - filename, descriptive label of second parent\n"
+"  $root              - repository root\n"
 "  $parent is an alias for $parent1."
 msgstr ""
 
@@ -2089,6 +2291,9 @@
 msgid "pass option to comparison program"
 msgstr ""
 
+msgid "revision"
+msgstr "revizia"
+
 msgid "change made by revision"
 msgstr ""
 
@@ -2114,11 +2319,15 @@
 
 msgid "pull changes from a remote repository, merge new changes if needed."
 msgstr ""
+"preia modificări dintr-un depozit la distanță, fuzionează modificările noi "
+"dacă este necesar"
 
 msgid ""
 "    This finds all changes from the repository at the specified path\n"
 "    or URL and adds them to the local repository."
 msgstr ""
+"   Găsește toate modificările din depozit la calea sau URL-ul\n"
+"   specificat și le adaugă la depozitul local."
 
 msgid ""
 "    If the pulled changes add a new branch head, the head is\n"
@@ -2134,11 +2343,15 @@
 "    order, use --switch-parent."
 msgstr ""
 
-msgid ""
-"    See :hg:`help dates` for a list of formats valid for -d/--date.\n"
-"    "
-msgstr ""
-"    Vezi :hg:`help dates` pentru o listă de formate valide cu d/--date.\n"
+msgid "    See :hg:`help dates` for a list of formats valid for -d/--date."
+msgstr ""
+"    Vezi :hg:`help dates` pentru o listă de formate valide cu d/--date."
+
+msgid ""
+"    Returns 0 on success.\n"
+"    "
+msgstr ""
+"    Returnează 0 în caz de succes.\n"
 "    "
 
 msgid ""
@@ -2218,6 +2431,9 @@
 msgid "%s Note: This key has expired (signed by: \"%s\")\n"
 msgstr ""
 
+msgid "hg sigs"
+msgstr ""
+
 msgid "list signed changesets"
 msgstr ""
 
@@ -2225,6 +2441,9 @@
 msgid "%s:%d node does not exist\n"
 msgstr ""
 
+msgid "hg sigcheck REVISION"
+msgstr ""
+
 msgid "verify all the signatures there may be for a particular revision"
 msgstr ""
 
@@ -2232,32 +2451,6 @@
 msgid "No valid signature for %s\n"
 msgstr ""
 
-msgid "add a signature for the current or given revision"
-msgstr ""
-
-msgid ""
-"    If no revision is given, the parent of the working directory is used,\n"
-"    or tip if no revision is checked out."
-msgstr ""
-
-msgid "uncommitted merge - please provide a specific revision"
-msgstr ""
-
-#, python-format
-msgid "Signing %d:%s\n"
-msgstr ""
-
-msgid "Error while signing"
-msgstr ""
-
-msgid ""
-"working copy of .hgsigs is changed (please commit .hgsigs manually or use --"
-"force)"
-msgstr ""
-
-msgid "unknown signature version"
-msgstr ""
-
 msgid "make the signature local"
 msgstr ""
 
@@ -2282,10 +2475,37 @@
 msgid "hg sign [OPTION]... [REVISION]..."
 msgstr "hg sign [OPȚIUNE]... [REVIZIE].."
 
-msgid "hg sigcheck REVISION"
-msgstr ""
-
-msgid "hg sigs"
+msgid "add a signature for the current or given revision"
+msgstr ""
+
+msgid ""
+"    If no revision is given, the parent of the working directory is used,\n"
+"    or tip if no revision is checked out."
+msgstr ""
+
+msgid ""
+"    See :hg:`help dates` for a list of formats valid for -d/--date.\n"
+"    "
+msgstr ""
+"    Vezi :hg:`help dates` pentru o listă de formate valide cu d/--date.\n"
+"    "
+
+msgid "uncommitted merge - please provide a specific revision"
+msgstr ""
+
+#, python-format
+msgid "Signing %d:%s\n"
+msgstr ""
+
+msgid "error while signing"
+msgstr ""
+
+msgid ""
+"working copy of .hgsigs is changed (please commit .hgsigs manually or use --"
+"force)"
+msgstr ""
+
+msgid "unknown signature version"
 msgstr ""
 
 msgid "command to view revision graphs from a shell"
@@ -2298,7 +2518,25 @@
 msgstr ""
 
 #, python-format
-msgid "--graph option is incompatible with --%s"
+msgid "-G/--graph option is incompatible with --%s"
+msgstr ""
+
+msgid "-G/--graph option is incompatible with --follow with file argument"
+msgstr ""
+
+msgid "NUM"
+msgstr ""
+
+msgid "limit number of changes displayed"
+msgstr "limitează numărul de modificări afișat"
+
+msgid "show patch"
+msgstr "afișează patch-ul"
+
+msgid "show the specified revision or range"
+msgstr "afișează revizia sau intervalul specificat"
+
+msgid "hg glog [OPTION]... [FILE]"
 msgstr ""
 
 msgid "show revision history alongside an ASCII revision graph"
@@ -2323,21 +2561,6 @@
 msgid "show the revision DAG"
 msgstr "afișează graful (DAG) reviziilor"
 
-msgid "NUM"
-msgstr ""
-
-msgid "limit number of changes displayed"
-msgstr "limitează numărul de modificări afișat"
-
-msgid "show patch"
-msgstr "afișează patch-ul"
-
-msgid "show the specified revision or range"
-msgstr "afișează revizia sau intervalul specificat"
-
-msgid "hg glog [OPTION]... [FILE]"
-msgstr ""
-
 msgid "hooks for integrating with the CIA.vc notification service"
 msgstr ""
 
@@ -2357,7 +2580,7 @@
 "  # Append a diffstat to the log message (optional)\n"
 "  #diffstat = False\n"
 "  # Template to use for log messages (optional)\n"
-"  #template = {desc}\\n{baseurl}/rev/{node}-- {diffstat}\n"
+"  #template = {desc}\\n{baseurl}{webroot}/rev/{node}-- {diffstat}\n"
 "  # Style to use (optional)\n"
 "  #style = foo\n"
 "  # The URL of the CIA notification service (optional)\n"
@@ -2366,7 +2589,9 @@
 "  # Make sure to set email.from if you do this.\n"
 "  #url = http://cia.vc/\n"
 "  # print message instead of sending it (optional)\n"
-"  #test = False"
+"  #test = False\n"
+"  # number of slashes to strip for url paths\n"
+"  #strip = 0"
 msgstr ""
 
 msgid ""
@@ -2413,7 +2638,7 @@
 msgid ""
 "The :hg:`view` command will launch the hgk Tcl script. For this command\n"
 "to work, hgk must be in your search path. Alternately, you can specify\n"
-"the path to hgk in your .hgrc file::"
+"the path to hgk in your configuration file::"
 msgstr ""
 
 msgid ""
@@ -2461,7 +2686,7 @@
 msgstr ""
 
 msgid "start interactive history viewer"
-msgstr ""
+msgstr "pornește vizualizatorul interactiv al istoricului"
 
 msgid "hg view [-l LIMIT] [REVRANGE]"
 msgstr ""
@@ -2742,6 +2967,11 @@
 msgstr ""
 
 msgid ""
+"Keywords expand to the changeset data pertaining to the latest change\n"
+"relative to the working directory parent of each file."
+msgstr ""
+
+msgid ""
 "Configuration is done in the [keyword], [keywordset] and [keywordmaps]\n"
 "sections of hgrc files."
 msgstr ""
@@ -2763,8 +2993,9 @@
 msgstr ""
 
 msgid ""
-"NOTE: the more specific you are in your filename patterns the less you\n"
-"lose speed in huge repositories."
+".. note::\n"
+"   The more specific you are in your filename patterns the less you\n"
+"   lose speed in huge repositories."
 msgstr ""
 
 msgid ""
@@ -2773,25 +3004,24 @@
 "available templates and filters."
 msgstr ""
 
-msgid "Three additional date template filters are provided::"
-msgstr ""
-
-msgid ""
-"    utcdate      \"2006/09/18 15:13:13\"\n"
-"    svnutcdate   \"2006-09-18 15:13:13Z\"\n"
-"    svnisodate   \"2006-09-18 08:13:13 -700 (Mon, 18 Sep 2006)\""
+msgid "Three additional date template filters are provided:"
+msgstr ""
+
+msgid ""
+":``utcdate``:    \"2006/09/18 15:13:13\"\n"
+":``svnutcdate``: \"2006-09-18 15:13:13Z\"\n"
+":``svnisodate``: \"2006-09-18 08:13:13 -700 (Mon, 18 Sep 2006)\""
 msgstr ""
 
 msgid ""
 "The default template mappings (view with :hg:`kwdemo -d`) can be\n"
 "replaced with customized keywords and templates. Again, run\n"
-":hg:`kwdemo` to control the results of your config changes."
-msgstr ""
-
-msgid ""
-"Before changing/disabling active keywords, run :hg:`kwshrink` to avoid\n"
-"the risk of inadvertently storing expanded keywords in the change\n"
-"history."
+":hg:`kwdemo` to control the results of your configuration changes."
+msgstr ""
+
+msgid ""
+"Before changing/disabling active keywords, you must run :hg:`kwshrink`\n"
+"to avoid storing expanded keywords in the change history."
 msgstr ""
 
 msgid ""
@@ -2819,6 +3049,16 @@
 msgid "no [keyword] patterns configured"
 msgstr ""
 
+#, fuzzy
+msgid "show default keyword template maps"
+msgstr "afișează corespondențele șabloanelor implicite de cuvinte cheie"
+
+msgid "read maps from rcfile"
+msgstr ""
+
+msgid "hg kwdemo [-d] [-f RCFILE] [TEMPLATEMAP]..."
+msgstr ""
+
 msgid "print [keywordmaps] configuration and an expansion example"
 msgstr ""
 
@@ -2852,12 +3092,20 @@
 msgid "\textending current template maps\n"
 msgstr ""
 
-msgid "\toverriding default template maps\n"
+msgid "\toverriding default svn keywordset\n"
+msgstr ""
+
+msgid "\toverriding default cvs keywordset\n"
 msgstr ""
 
 msgid ""
 "\n"
-"\tconfiguration using default keyword template maps\n"
+"\tconfiguration using default svn keywordset\n"
+msgstr ""
+
+msgid ""
+"\n"
+"\tconfiguration using default cvs keywordset\n"
 msgstr ""
 
 msgid "\tdisabling current template maps\n"
@@ -2882,6 +3130,9 @@
 "\tkeywords expanded\n"
 msgstr ""
 
+msgid "hg kwexpand [OPTION]... [FILE]..."
+msgstr ""
+
 msgid "expand keywords in the working directory"
 msgstr ""
 
@@ -2893,6 +3144,18 @@
 "    "
 msgstr ""
 
+msgid "show keyword status flags of all files"
+msgstr ""
+
+msgid "show files excluded from expansion"
+msgstr "afișează fișierele excluse de la expandare"
+
+msgid "only show unknown (not tracked) files"
+msgstr "afișează doar fișierele necunoscute (neurmărite)"
+
+msgid "hg kwfiles [OPTION]... [FILE]..."
+msgstr ""
+
 msgid "show files configured for keyword expansion"
 msgstr "afișează fișierele configurate pentru expandarea cuvintelor cheie"
 
@@ -2925,12 +3188,13 @@
 "    "
 msgstr ""
 
+msgid "hg kwshrink [OPTION]... [FILE]..."
+msgstr ""
+
 msgid "revert expanded keywords in the working directory"
 msgstr ""
 
-msgid ""
-"    Run before changing/disabling active keywords or if you experience\n"
-"    problems with :hg:`import` or :hg:`merge`."
+msgid "    Must be run before changing/disabling active keywords."
 msgstr ""
 
 msgid ""
@@ -2938,34 +3202,6 @@
 "    "
 msgstr ""
 
-#, fuzzy
-msgid "show default keyword template maps"
-msgstr "afișează corespondențele șabloanelor implicite de cuvinte cheie"
-
-msgid "read maps from rcfile"
-msgstr ""
-
-msgid "hg kwdemo [-d] [-f RCFILE] [TEMPLATEMAP]..."
-msgstr ""
-
-msgid "hg kwexpand [OPTION]... [FILE]..."
-msgstr ""
-
-msgid "show keyword status flags of all files"
-msgstr ""
-
-msgid "show files excluded from expansion"
-msgstr "afișează fișierele excluse de la expandare"
-
-msgid "only show unknown (not tracked) files"
-msgstr "afișează doar fișierele necunoscute (neurmărite)"
-
-msgid "hg kwfiles [OPTION]... [FILE]..."
-msgstr ""
-
-msgid "hg kwshrink [OPTION]... [FILE]..."
-msgstr ""
-
 msgid "manage a stack of patches"
 msgstr ""
 
@@ -3022,6 +3258,13 @@
 "create other, independent patch queues with the :hg:`qqueue` command.\n"
 msgstr ""
 
+msgid "print first line of patch header"
+msgstr ""
+
+#, python-format
+msgid "malformated mq status line: %s\n"
+msgstr "linie de stare mq eronată: %s\n"
+
 #, python-format
 msgid "mq.git option can be auto/keep/yes/no got %s"
 msgstr ""
@@ -3058,12 +3301,12 @@
 msgstr ""
 
 #, python-format
-msgid "allowing %s - guarded by %r\n"
-msgstr ""
-
-#, python-format
-msgid "skipping %s - guarded by %r\n"
-msgstr "se omite %s - gardat de către %r\n"
+msgid "allowing %s - guarded by %s\n"
+msgstr "se permite %s - gardat de către %s\n"
+
+#, python-format
+msgid "skipping %s - guarded by %s\n"
+msgstr "se omite %s - gardat de către %s\n"
 
 #, python-format
 msgid "skipping %s - no matching guards\n"
@@ -3115,6 +3358,9 @@
 msgid "patch %s is empty\n"
 msgstr ""
 
+msgid "repository commit failed"
+msgstr "depozitarea a eșuat"
+
 msgid "patch failed, rejects left in working dir\n"
 msgstr ""
 
@@ -3122,6 +3368,14 @@
 msgstr ""
 
 #, python-format
+msgid "revision %s refers to unknown patches: %s\n"
+msgstr "revizia %s face referință la patch-uri necunoscute: %s\n"
+
+#, python-format
+msgid "unknown patches: %s\n"
+msgstr "patch-uri necunoscute: %s\n"
+
+#, python-format
 msgid "revision %d is not managed"
 msgstr ""
 
@@ -3150,6 +3404,10 @@
 msgid "working directory revision is not qtip"
 msgstr ""
 
+#, python-format
+msgid "uncommitted changes in subrepository %s"
+msgstr "modificări nedepozitate în subdepozitul %s"
+
 msgid "local changes found, refresh first"
 msgstr ""
 
@@ -3161,6 +3419,18 @@
 msgstr ""
 
 #, python-format
+msgid "patch name cannot begin with \"%s\""
+msgstr ""
+
+#, python-format
+msgid "\"%s\" cannot be used in the name of a patch"
+msgstr ""
+
+#, python-format
+msgid "\"%s\" already exists as a directory"
+msgstr ""
+
+#, python-format
 msgid "patch \"%s\" already exists"
 msgstr ""
 
@@ -3168,6 +3438,10 @@
 msgstr ""
 
 #, python-format
+msgid "cannot write patch \"%s\": %s"
+msgstr ""
+
+#, python-format
 msgid "error unlinking %s\n"
 msgstr ""
 
@@ -3186,15 +3460,15 @@
 msgstr ""
 
 #, python-format
+msgid "qpush: %s is already at the top\n"
+msgstr ""
+
+#, python-format
 msgid "cannot push to a previous patch: %s"
 msgstr ""
 
 #, python-format
-msgid "qpush: %s is already at the top\n"
-msgstr ""
-
-#, python-format
-msgid "guarded by %r"
+msgid "guarded by %s"
 msgstr ""
 
 msgid "no matching guards"
@@ -3210,6 +3484,16 @@
 msgid "patch series already fully applied\n"
 msgstr ""
 
+msgid "cannot use --exact and --move together"
+msgstr ""
+
+msgid "cannot push --exact with applied patches"
+msgstr "nu se poate executa push --exact cu patch-uri aplicate"
+
+#, python-format
+msgid "%s does not have a parent recorded"
+msgstr ""
+
 msgid "please specify the patch to move"
 msgstr ""
 
@@ -3288,9 +3572,8 @@
 msgid "saved queue repository parents: %s %s\n"
 msgstr ""
 
-#, fuzzy
-msgid "queue directory updating\n"
-msgstr "actualizarea directorului se introduce în coadă\n"
+msgid "updating queue directory\n"
+msgstr "se actualizează directorul coadă\n"
 
 msgid "Unable to load queue repository\n"
 msgstr ""
@@ -3363,6 +3646,15 @@
 msgid "adding %s to series file\n"
 msgstr ""
 
+msgid "keep patch file"
+msgstr "păstrează fișierul patch"
+
+msgid "stop managing a revision (DEPRECATED)"
+msgstr ""
+
+msgid "hg qdelete [-k] [PATCH]..."
+msgstr ""
+
 msgid "remove patches from queue"
 msgstr ""
 
@@ -3377,18 +3669,59 @@
 "    use the :hg:`qfinish` command."
 msgstr ""
 
+msgid "show only the last patch"
+msgstr "afișează doar ultimul patch"
+
+msgid "hg qapplied [-1] [-s] [PATCH]"
+msgstr ""
+
 msgid "print the patches already applied"
 msgstr ""
 
+msgid "    Returns 0 on success."
+msgstr ""
+"    Returnează 0 în caz de succes.\n"
+"    "
+
 msgid "only one patch applied\n"
 msgstr ""
 
+msgid "show only the first patch"
+msgstr "afișează doar primul patch"
+
+msgid "hg qunapplied [-1] [-s] [PATCH]"
+msgstr ""
+
 msgid "print the patches not yet applied"
 msgstr ""
 
 msgid "all patches applied\n"
 msgstr ""
 
+msgid "import file in patch directory"
+msgstr ""
+
+msgid "NAME"
+msgstr "NUME"
+
+msgid "name of patch file"
+msgstr ""
+
+msgid "overwrite existing files"
+msgstr ""
+
+msgid "place existing revisions under mq control"
+msgstr ""
+
+msgid "use git extended diff format"
+msgstr "folosește formatul diff extins al lui git"
+
+msgid "qpush after importing"
+msgstr ""
+
+msgid "hg qimport [-e] [-n NAME] [-f] [-g] [-P] [-r REV]... FILE..."
+msgstr ""
+
 msgid "import a patch"
 msgstr ""
 
@@ -3419,7 +3752,7 @@
 "    With -g/--git, patches imported with --rev will use the git diff\n"
 "    format. See the diffs help topic for information on why this is\n"
 "    important for preserving rename/copy information and permission\n"
-"    changes."
+"    changes. Use :hg:`qfinish` to remove changesets from mq control."
 msgstr ""
 
 msgid ""
@@ -3431,9 +3764,20 @@
 msgid "    To import an existing patch while renaming it::"
 msgstr ""
 
-msgid ""
-"      hg qimport -e existing-patch -n new-name\n"
-"    "
+msgid "      hg qimport -e existing-patch -n new-name"
+msgstr ""
+
+msgid ""
+"    Returns 0 if import succeeded.\n"
+"    "
+msgstr ""
+"    Returnează 0 dacă importarea a avut loc cu succes.\n"
+"    "
+
+msgid "create queue repository"
+msgstr ""
+
+msgid "hg qinit [-c]"
 msgstr ""
 
 msgid "init a new queue repository (DEPRECATED)"
@@ -3452,6 +3796,24 @@
 "    commands. With -c, use :hg:`init --mq` instead."
 msgstr ""
 
+msgid "use pull protocol to copy metadata"
+msgstr "folosește protocolul 'pull' pentru a copia metadatele"
+
+msgid "do not update the new working directories"
+msgstr ""
+
+msgid "use uncompressed transfer (fast over LAN)"
+msgstr "folosește transfer necomprimat (rapid în LAN)"
+
+msgid "REPO"
+msgstr ""
+
+msgid "location of source patch repository"
+msgstr ""
+
+msgid "hg qclone [OPTION]... SOURCE [DEST]"
+msgstr ""
+
 msgid "clone main and patch repository at same time"
 msgstr ""
 
@@ -3470,9 +3832,15 @@
 
 msgid ""
 "    The patch directory must be a nested Mercurial repository, as\n"
-"    would be created by :hg:`init --mq`.\n"
-"    "
-msgstr ""
+"    would be created by :hg:`init --mq`."
+msgstr ""
+
+msgid ""
+"    Return 0 on success.\n"
+"    "
+msgstr ""
+"    Returnează 0 în caz de succes.\n"
+"    "
 
 msgid "versioned patch repository not found (see init --mq)"
 msgstr ""
@@ -3489,26 +3857,65 @@
 msgid "updating destination repository\n"
 msgstr "se actualizează depozitul destinație\n"
 
+msgid "hg qcommit [OPTION]... [FILE]..."
+msgstr ""
+
 msgid "commit changes in the queue repository (DEPRECATED)"
 msgstr ""
 
 msgid "    This command is deprecated; use :hg:`commit --mq` instead."
 msgstr ""
 
+msgid "print patches not in series"
+msgstr ""
+
+msgid "hg qseries [-ms]"
+msgstr ""
+
 msgid "print the entire series file"
 msgstr ""
 
+msgid "hg qtop [-s]"
+msgstr ""
+
 msgid "print the name of the current patch"
 msgstr ""
 
+msgid "hg qnext [-s]"
+msgstr ""
+
 msgid "print the name of the next patch"
 msgstr ""
 
+msgid "hg qprev [-s]"
+msgstr ""
+
 msgid "print the name of the previous patch"
 msgstr ""
 
+msgid "import uncommitted changes (DEPRECATED)"
+msgstr ""
+
+msgid "add \"From: <current user>\" to patch"
+msgstr ""
+
+msgid "USER"
+msgstr ""
+
+msgid "add \"From: <USER>\" to patch"
+msgstr ""
+
+msgid "add \"Date: <current date>\" to patch"
+msgstr ""
+
+msgid "add \"Date: <DATE>\" to patch"
+msgstr ""
+
+msgid "hg qnew [-e] [-m TEXT] [-l FILE] PATCH [FILE]..."
+msgstr ""
+
 msgid "create a new patch"
-msgstr ""
+msgstr "creează un nou patch"
 
 msgid ""
 "    qnew creates a new patch on top of the currently-applied patch (if\n"
@@ -3535,12 +3942,36 @@
 "    Use the -g/--git option to keep the patch in the git extended diff\n"
 "    format. Read the diffs help topic for more information on why this\n"
 "    is important for preserving permission changes and copy/rename\n"
-"    information.\n"
-"    "
+"    information."
+msgstr ""
+
+msgid ""
+"    Returns 0 on successful creation of a new patch.\n"
+"    "
+msgstr ""
+"    Returnează 0 dacă patch-ul a fost creat cu succes.\n"
+"    "
+
+msgid "refresh only files already in the patch and specified files"
+msgstr ""
+
+msgid "add/update author field in patch with current user"
+msgstr ""
+
+msgid "add/update author field in patch with given user"
+msgstr ""
+
+msgid "add/update date field in patch with current date"
+msgstr ""
+
+msgid "add/update date field in patch with given date"
+msgstr ""
+
+msgid "hg qrefresh [-I] [-X] [-e] [-m TEXT] [-l FILE] [-s] [FILE]..."
 msgstr ""
 
 msgid "update the current patch"
-msgstr ""
+msgstr "actualizează patch-ul curent"
 
 msgid ""
 "    If any file patterns are provided, the refreshed patch will\n"
@@ -3565,15 +3996,17 @@
 "    hg add/remove/copy/rename work as usual, though you might want to\n"
 "    use git-style patches (-g/--git or [diff] git=1) to track copies\n"
 "    and renames. See the diffs help topic for more information on the\n"
-"    git diff format.\n"
-"    "
+"    git diff format."
 msgstr ""
 
 msgid "option \"-e\" incompatible with \"-m\" or \"-l\""
 msgstr ""
 
+msgid "hg qdiff [OPTION]... [FILE]..."
+msgstr ""
+
 msgid "diff of the current patch and subsequent modifications"
-msgstr ""
+msgstr "diff pentru patch-ul curent și modificările ulterioare"
 
 msgid ""
 "    Shows a diff which includes the current patch as well as any\n"
@@ -3586,8 +4019,16 @@
 "    Use :hg:`diff` if you only want to see the changes made since the\n"
 "    last qrefresh, or :hg:`export qtip` if you want to see changes\n"
 "    made by the current patch without including changes made since the\n"
-"    qrefresh.\n"
-"    "
+"    qrefresh."
+msgstr ""
+
+msgid "edit patch header"
+msgstr ""
+
+msgid "keep folded patch files"
+msgstr ""
+
+msgid "hg qfold [-e] [-k] [-m TEXT] [-l FILE] PATCH..."
 msgstr ""
 
 msgid "fold the named patches into the current patch"
@@ -3604,30 +4045,42 @@
 
 msgid ""
 "    The header for each folded patch will be concatenated with the\n"
-"    current patch header, separated by a line of '* * *'."
+"    current patch header, separated by a line of ``* * *``."
 msgstr ""
 
 msgid "qfold requires at least one patch name"
 msgstr ""
 
-msgid "No patches applied"
-msgstr ""
-
-#, python-format
-msgid "Skipping already folded patch %s"
-msgstr "Se omite patch-ul deja pliat %s"
+#, python-format
+msgid "Skipping already folded patch %s\n"
+msgstr "Se omite patch-ul deja pliat %s\n"
 
 #, python-format
 msgid "qfold cannot fold already applied patch %s"
 msgstr ""
 
 #, python-format
-msgid "Error folding patch %s"
+msgid "error folding patch %s"
+msgstr ""
+
+msgid "overwrite any local changes"
+msgstr ""
+
+msgid "hg qgoto [OPTION]... PATCH"
 msgstr ""
 
 msgid "push or pop patches until named patch is at top of stack"
 msgstr ""
 
+msgid "list all patches and guards"
+msgstr ""
+
+msgid "drop all guards"
+msgstr ""
+
+msgid "hg qguard [-l] [-n] [PATCH] [-- [+GUARD]... [-GUARD]...]"
+msgstr ""
+
 msgid "set or print guards for a patch"
 msgstr ""
 
@@ -3642,16 +4095,18 @@
 
 msgid ""
 "    With no arguments, print the currently active guards.\n"
-"    With arguments, set guards for the named patch.\n"
-"    NOTE: Specifying negative guards now requires '--'."
+"    With arguments, set guards for the named patch."
+msgstr ""
+
+msgid ""
+"    .. note::\n"
+"       Specifying negative guards now requires '--'."
 msgstr ""
 
 msgid "    To set guards on another patch::"
 msgstr ""
 
-msgid ""
-"      hg qguard other.patch -- +2.6.17 -stable\n"
-"    "
+msgid "      hg qguard other.patch -- +2.6.17 -stable"
 msgstr ""
 
 msgid "cannot mix -l/--list with options or arguments"
@@ -3664,16 +4119,42 @@
 msgid "no patch named %s"
 msgstr ""
 
+msgid "hg qheader [PATCH]"
+msgstr ""
+
 msgid "print the header of the topmost or specified patch"
 msgstr ""
 
+msgid "apply on top of local changes"
+msgstr ""
+
+msgid "apply the target patch to its recorded parent"
+msgstr ""
+
+msgid "list patch name in commit text"
+msgstr ""
+
+msgid "apply all patches"
+msgstr ""
+
+msgid "merge from another queue (DEPRECATED)"
+msgstr ""
+
+msgid "merge queue name (DEPRECATED)"
+msgstr ""
+
+msgid "reorder patch series and apply only the patch"
+msgstr ""
+
+msgid "hg qpush [-f] [-l] [-a] [--move] [PATCH | INDEX]"
+msgstr ""
+
 msgid "push the next patch onto the stack"
-msgstr ""
+msgstr "pune patch-ul următor pe stivă"
 
 msgid ""
 "    When -f/--force is applied, all local changes in patched files\n"
-"    will be lost.\n"
-"    "
+"    will be lost."
 msgstr ""
 
 msgid "no saved queues found, please use -n\n"
@@ -3683,20 +4164,34 @@
 msgid "merging with queue at: %s\n"
 msgstr ""
 
+msgid "pop all patches"
+msgstr ""
+
+msgid "queue name to pop (DEPRECATED)"
+msgstr ""
+
+msgid "forget any local changes to patched files"
+msgstr "uită orice modificare locală adusă fișierelor peticite"
+
+msgid "hg qpop [-a] [-f] [PATCH | INDEX]"
+msgstr ""
+
 msgid "pop the current patch off the stack"
-msgstr ""
+msgstr "scoate patch-ul curent de pe stivă"
 
 msgid ""
 "    By default, pops off the top of the patch stack. If given a patch\n"
 "    name, keeps popping off patches until the named patch is at the\n"
-"    top of the stack.\n"
-"    "
+"    top of the stack."
 msgstr ""
 
 #, python-format
 msgid "using patch queue: %s\n"
 msgstr ""
 
+msgid "hg qrename PATCH1 [PATCH2]"
+msgstr ""
+
 msgid "rename a patch"
 msgstr ""
 
@@ -3705,18 +4200,34 @@
 "    With two arguments, renames PATCH1 to PATCH2."
 msgstr ""
 
-#, python-format
-msgid "%s already exists"
-msgstr ""
-
-#, python-format
-msgid "A patch named %s already exists in the series file"
+msgid "delete save entry"
+msgstr ""
+
+msgid "update queue working directory"
+msgstr ""
+
+msgid "hg qrestore [-d] [-u] REV"
 msgstr ""
 
 msgid "restore the queue state saved by a revision (DEPRECATED)"
 msgstr ""
 
-msgid "    This command is deprecated, use rebase --mq instead."
+msgid "    This command is deprecated, use :hg:`rebase` instead."
+msgstr ""
+
+msgid "copy patch directory"
+msgstr ""
+
+msgid "copy directory name"
+msgstr ""
+
+msgid "clear queue status file"
+msgstr ""
+
+msgid "force copy"
+msgstr ""
+
+msgid "hg qsave [-m TEXT] [-l FILE] [-c] [-n NAME] [-e] [-f]"
 msgstr ""
 
 msgid "save current queue state (DEPRECATED)"
@@ -3734,13 +4245,36 @@
 msgid "copy %s to %s\n"
 msgstr ""
 
+msgid "force removal of changesets, discard uncommitted changes (no backup)"
+msgstr ""
+"forțează înlăturarea seturilor de modificări, renunță la modificările "
+"nedepozitate (fără copie de siguranță)"
+
+msgid ""
+"bundle only changesets with local revision number greater than REV which are "
+"not descendants of REV (DEPRECATED)"
+msgstr ""
+
+msgid "no backups"
+msgstr ""
+
+msgid "no backups (DEPRECATED)"
+msgstr ""
+
+msgid "do not modify working copy during strip"
+msgstr ""
+
+msgid "hg strip [-k] [-f] [-n] REV..."
+msgstr "hg strip [-k] [-f] [-n] REV..."
+
 msgid "strip changesets and all their descendants from the repository"
 msgstr ""
 
 msgid ""
 "    The strip command removes the specified changesets and all their\n"
-"    descendants. If the working directory has uncommitted changes,\n"
-"    the operation is aborted unless the --force flag is supplied."
+"    descendants. If the working directory has uncommitted changes, the\n"
+"    operation is aborted unless the --force flag is supplied, in which\n"
+"    case changes will be discarded."
 msgstr ""
 
 msgid ""
@@ -3760,9 +4294,26 @@
 msgstr ""
 
 msgid ""
-"    Use the --nobackup option to discard the backup bundle once the\n"
-"    operation completes.\n"
-"    "
+"    Use the --no-backup option to discard the backup bundle once the\n"
+"    operation completes."
+msgstr ""
+
+msgid "empty revision set"
+msgstr "setul de revizii este vid"
+
+msgid "disable all guards"
+msgstr ""
+
+msgid "list all guards in series file"
+msgstr ""
+
+msgid "pop to before first guarded applied patch"
+msgstr ""
+
+msgid "pop, then reapply patches"
+msgstr ""
+
+msgid "hg qselect [OPTION]... [GUARD]..."
 msgstr ""
 
 msgid "set or print guarded patches to push"
@@ -3777,8 +4328,8 @@
 msgstr ""
 
 msgid ""
-"        qguard foo.patch -stable    (negative guard)\n"
-"        qguard bar.patch +stable    (positive guard)\n"
+"        qguard foo.patch -- -stable    (negative guard)\n"
+"        qguard bar.patch    +stable    (positive guard)\n"
 "        qselect stable"
 msgstr ""
 
@@ -3841,6 +4392,12 @@
 msgid "reapplying unguarded patches\n"
 msgstr ""
 
+msgid "finish all applied changesets"
+msgstr ""
+
+msgid "hg qfinish [-a] [REV]..."
+msgstr ""
+
 msgid "move applied patches into repository history"
 msgstr ""
 
@@ -3860,13 +4417,30 @@
 msgid ""
 "    This can be especially useful if your changes have been applied to\n"
 "    an upstream repository, or if you are about to push your changes\n"
-"    to upstream.\n"
-"    "
+"    to upstream."
 msgstr ""
 
 msgid "no revisions specified"
 msgstr ""
 
+msgid "list all available queues"
+msgstr ""
+
+msgid "create new queue"
+msgstr ""
+
+msgid "rename active queue"
+msgstr ""
+
+msgid "delete reference to queue"
+msgstr ""
+
+msgid "delete queue, and remove patch dir"
+msgstr ""
+
+msgid "[OPTION] [QUEUE]"
+msgstr "[OPȚIUNE] [COADĂ]"
+
 msgid "manage multiple patch queues"
 msgstr ""
 
@@ -3893,8 +4467,7 @@
 msgid ""
 "    To delete an existing queue, use --delete. You cannot delete the "
 "currently\n"
-"    active queue.\n"
-"    "
+"    active queue."
 msgstr ""
 
 msgid "patches applied - cannot set new queue active"
@@ -3920,7 +4493,7 @@
 msgid "can't rename \"%s\" to its current name"
 msgstr ""
 
-#, fuzzy, python-format
+#, python-format
 msgid "non-queue directory \"%s\" already exists"
 msgstr "depozitul %s neaflat în coadă există deja"
 
@@ -3947,7 +4520,7 @@
 msgid "only a local queue repository may be initialized"
 msgstr ""
 
-msgid "There is no Mercurial repository here (.hg not found)"
+msgid "there is no Mercurial repository here (.hg not found)"
 msgstr ""
 
 msgid "no queue repository"
@@ -3964,280 +4537,17 @@
 msgid "mq:     (empty queue)\n"
 msgstr ""
 
+msgid ""
+"``mq()``\n"
+"    Changesets managed by MQ."
+msgstr ""
+
+msgid "mq takes no arguments"
+msgstr ""
+
 msgid "operate on patch repository"
 msgstr "operează pe depozitul de patch-uri"
 
-msgid "print first line of patch header"
-msgstr ""
-
-msgid "show only the last patch"
-msgstr "afișează doar ultimul patch"
-
-msgid "hg qapplied [-1] [-s] [PATCH]"
-msgstr ""
-
-msgid "use pull protocol to copy metadata"
-msgstr "folosește protocolul 'pull' pentru a copia metadatele"
-
-msgid "do not update the new working directories"
-msgstr ""
-
-msgid "use uncompressed transfer (fast over LAN)"
-msgstr "folosește transfer necomprimat (rapid în LAN)"
-
-msgid "REPO"
-msgstr ""
-
-msgid "location of source patch repository"
-msgstr ""
-
-msgid "hg qclone [OPTION]... SOURCE [DEST]"
-msgstr ""
-
-msgid "hg qcommit [OPTION]... [FILE]..."
-msgstr ""
-
-msgid "hg qdiff [OPTION]... [FILE]..."
-msgstr ""
-
-msgid "keep patch file"
-msgstr "păstrează fișierul patch"
-
-msgid "stop managing a revision (DEPRECATED)"
-msgstr ""
-
-msgid "hg qdelete [-k] [-r REV]... [PATCH]..."
-msgstr ""
-
-msgid "edit patch header"
-msgstr ""
-
-msgid "keep folded patch files"
-msgstr ""
-
-msgid "hg qfold [-e] [-k] [-m TEXT] [-l FILE] PATCH..."
-msgstr ""
-
-msgid "overwrite any local changes"
-msgstr ""
-
-msgid "hg qgoto [OPTION]... PATCH"
-msgstr ""
-
-msgid "list all patches and guards"
-msgstr ""
-
-msgid "drop all guards"
-msgstr ""
-
-msgid "hg qguard [-l] [-n] [PATCH] [-- [+GUARD]... [-GUARD]...]"
-msgstr ""
-
-msgid "hg qheader [PATCH]"
-msgstr ""
-
-msgid "import file in patch directory"
-msgstr ""
-
-msgid "name of patch file"
-msgstr ""
-
-msgid "overwrite existing files"
-msgstr ""
-
-msgid "place existing revisions under mq control"
-msgstr ""
-
-msgid "use git extended diff format"
-msgstr "folosește formatul diff extins al lui git"
-
-msgid "qpush after importing"
-msgstr ""
-
-msgid "hg qimport [-e] [-n NAME] [-f] [-g] [-P] [-r REV]... FILE..."
-msgstr ""
-
-msgid "create queue repository"
-msgstr ""
-
-msgid "hg qinit [-c]"
-msgstr ""
-
-msgid "import uncommitted changes (DEPRECATED)"
-msgstr ""
-
-msgid "add \"From: <current user>\" to patch"
-msgstr ""
-
-msgid "USER"
-msgstr ""
-
-msgid "add \"From: <USER>\" to patch"
-msgstr ""
-
-msgid "add \"Date: <current date>\" to patch"
-msgstr ""
-
-msgid "add \"Date: <DATE>\" to patch"
-msgstr ""
-
-msgid "hg qnew [-e] [-m TEXT] [-l FILE] PATCH [FILE]..."
-msgstr ""
-
-msgid "hg qnext [-s]"
-msgstr ""
-
-msgid "hg qprev [-s]"
-msgstr ""
-
-msgid "pop all patches"
-msgstr ""
-
-msgid "queue name to pop (DEPRECATED)"
-msgstr ""
-
-msgid "forget any local changes to patched files"
-msgstr ""
-
-msgid "hg qpop [-a] [-n NAME] [-f] [PATCH | INDEX]"
-msgstr ""
-
-msgid "apply if the patch has rejects"
-msgstr ""
-
-msgid "list patch name in commit text"
-msgstr ""
-
-msgid "apply all patches"
-msgstr ""
-
-msgid "merge from another queue (DEPRECATED)"
-msgstr ""
-
-msgid "merge queue name (DEPRECATED)"
-msgstr ""
-
-msgid "reorder patch series and apply only the patch"
-msgstr ""
-
-msgid "hg qpush [-f] [-l] [-a] [-m] [-n NAME] [--move] [PATCH | INDEX]"
-msgstr ""
-
-msgid "refresh only files already in the patch and specified files"
-msgstr ""
-
-msgid "add/update author field in patch with current user"
-msgstr ""
-
-msgid "add/update author field in patch with given user"
-msgstr ""
-
-msgid "add/update date field in patch with current date"
-msgstr ""
-
-msgid "add/update date field in patch with given date"
-msgstr ""
-
-msgid "hg qrefresh [-I] [-X] [-e] [-m TEXT] [-l FILE] [-s] [FILE]..."
-msgstr ""
-
-msgid "hg qrename PATCH1 [PATCH2]"
-msgstr ""
-
-msgid "delete save entry"
-msgstr ""
-
-msgid "update queue working directory"
-msgstr ""
-
-msgid "hg qrestore [-d] [-u] REV"
-msgstr ""
-
-msgid "copy patch directory"
-msgstr ""
-
-msgid "copy directory name"
-msgstr ""
-
-msgid "clear queue status file"
-msgstr ""
-
-msgid "force copy"
-msgstr ""
-
-msgid "hg qsave [-m TEXT] [-l FILE] [-c] [-n NAME] [-e] [-f]"
-msgstr ""
-
-msgid "disable all guards"
-msgstr ""
-
-msgid "list all guards in series file"
-msgstr ""
-
-msgid "pop to before first guarded applied patch"
-msgstr ""
-
-msgid "pop, then reapply patches"
-msgstr ""
-
-msgid "hg qselect [OPTION]... [GUARD]..."
-msgstr ""
-
-msgid "print patches not in series"
-msgstr ""
-
-msgid "hg qseries [-ms]"
-msgstr ""
-
-msgid ""
-"force removal of changesets even if the working directory has uncommitted "
-"changes"
-msgstr ""
-
-msgid ""
-"bundle only changesets with local revision number greater than REV which are "
-"not descendants of REV (DEPRECATED)"
-msgstr ""
-
-msgid "no backups"
-msgstr ""
-
-msgid "hg strip [-f] [-n] REV..."
-msgstr ""
-
-msgid "hg qtop [-s]"
-msgstr ""
-
-msgid "show only the first patch"
-msgstr "afișează doar primul patch"
-
-msgid "hg qunapplied [-1] [-s] [PATCH]"
-msgstr ""
-
-msgid "finish all applied changesets"
-msgstr ""
-
-msgid "hg qfinish [-a] [REV]..."
-msgstr ""
-
-msgid "list all available queues"
-msgstr ""
-
-msgid "create new queue"
-msgstr ""
-
-msgid "rename active queue"
-msgstr ""
-
-msgid "delete reference to queue"
-msgstr ""
-
-msgid "delete queue, and remove patch dir"
-msgstr ""
-
-msgid "[OPTION] [QUEUE]"
-msgstr "[OPȚIUNE] [COADĂ]"
-
 msgid "hooks for sending email notifications at commit/push time"
 msgstr ""
 
@@ -4324,6 +4634,9 @@
 "If you like, you can put notify config file in repository that users\n"
 "can push changes to, they can manage their own subscriptions.\n"
 msgstr ""
+"Dacă doriți, puteți pune un fișier de configurare pentru `notify` în\n"
+"depozitul spre care utilizatorii pot trimite modificări, ei își pot\n"
+"gestiona propriile abonări.\n"
 
 #, python-format
 msgid "%s: %d new changesets"
@@ -4357,7 +4670,7 @@
 
 msgid ""
 "  [pager]\n"
-"  pager = LESS='FSRX' less"
+"  pager = less -FRSX"
 msgstr ""
 
 msgid ""
@@ -4405,34 +4718,19 @@
 
 msgid ""
 "To ignore global commands like :hg:`version` or :hg:`help`, you have\n"
-"to specify them in the global .hgrc\n"
-msgstr ""
-
-msgid "interpret suffixes to refer to ancestor revisions"
-msgstr ""
-
-msgid ""
-"This extension allows you to use git-style suffixes to refer to the\n"
-"ancestors of a specific revision."
-msgstr ""
-
-msgid "For example, if you can refer to a revision as \"foo\", then::"
-msgstr ""
-
-msgid ""
-"  foo^N = Nth parent of foo\n"
-"  foo^0 = foo\n"
-"  foo^1 = first parent of foo\n"
-"  foo^2 = second parent of foo\n"
-"  foo^  = foo^1"
-msgstr ""
-
-msgid ""
-"  foo~N = Nth first grandparent of foo\n"
-"  foo~0 = foo\n"
-"  foo~1 = foo^1 = foo^ = first parent of foo\n"
-"  foo~2 = foo^1^1 = foo^^ = first parent of first parent of foo\n"
-msgstr ""
+"to specify them in your user configuration file."
+msgstr ""
+
+msgid ""
+"The --pager=... option can also be used to control when the pager is\n"
+"used. Use a boolean value like yes, no, on, off, or use auto for\n"
+"normal behavior.\n"
+msgstr ""
+
+msgid "when to paginate (boolean, always, auto, or never)"
+msgstr ""
+"când să se pagineze (boolean, `always`=întotdeauna, auto, sau "
+"`never`=niciodată)"
 
 msgid "command to send changesets as (a series of) patch emails"
 msgstr ""
@@ -4461,14 +4759,8 @@
 msgstr ""
 
 msgid ""
-"With the -d/--diffstat option, you will be prompted for each changeset\n"
-"with a diffstat summary and the changeset summary, so you can be sure\n"
-"you are sending the right changes."
-msgstr ""
-
-msgid ""
-"To configure other defaults, add a section like this to your hgrc\n"
-"file::"
+"To configure other defaults, add a section like this to your\n"
+"configuration file::"
 msgstr ""
 
 msgid ""
@@ -4491,39 +4783,6 @@
 msgstr ""
 
 msgid ""
-"To avoid sending patches prematurely, it is a good idea to first run\n"
-"the :hg:`email` command with the \"-n\" option (test only). You will be\n"
-"prompted for an email recipient address, a subject and an introductory\n"
-"message describing the patches of your patchbomb. Then when all is\n"
-"done, patchbomb messages are displayed. If the PAGER environment\n"
-"variable is set, your pager will be fired up once for each patchbomb\n"
-"message, so you can verify everything is alright."
-msgstr ""
-
-msgid ""
-"The -m/--mbox option is also very useful. Instead of previewing each\n"
-"patchbomb message in a pager or sending the messages directly, it will\n"
-"create a UNIX mailbox file with the patch emails. This mailbox file\n"
-"can be previewed with any mail user agent which supports UNIX mbox\n"
-"files, e.g. with mutt::"
-msgstr ""
-
-msgid "  % mutt -R -f mbox"
-msgstr ""
-
-msgid ""
-"When you are previewing the patchbomb messages, you can use ``formail``\n"
-"(a utility that is commonly installed as part of the procmail\n"
-"package), to send each message out::"
-msgstr ""
-
-msgid "  % formail -s sendmail -bm -t < mbox"
-msgstr ""
-
-msgid "That should be all. Now your patchbomb is on its way out."
-msgstr ""
-
-msgid ""
 "You can also either configure the method option in the email section\n"
 "to be a sendmail compatible mailer or fill out the [smtp] section so\n"
 "that the patchbomb extension can automatically send patchbombs\n"
@@ -4538,111 +4797,6 @@
 msgid "Please enter a valid value.\n"
 msgstr ""
 
-msgid "does the diffstat above look okay?"
-msgstr ""
-
-msgid "diffstat rejected"
-msgstr ""
-
-msgid "send changesets by email"
-msgstr ""
-
-msgid ""
-"    By default, diffs are sent in the format generated by\n"
-"    :hg:`export`, one per message. The series starts with a \"[PATCH 0\n"
-"    of N]\" introduction, which describes the series as a whole."
-msgstr ""
-
-msgid ""
-"    Each patch email has a Subject line of \"[PATCH M of N] ...\", using\n"
-"    the first line of the changeset description as the subject text.\n"
-"    The message contains two or three parts. First, the changeset\n"
-"    description. Next, (optionally) if the diffstat program is\n"
-"    installed and -d/--diffstat is used, the result of running\n"
-"    diffstat on the patch. Finally, the patch itself, as generated by\n"
-"    :hg:`export`."
-msgstr ""
-
-msgid ""
-"    By default the patch is included as text in the email body for\n"
-"    easy reviewing. Using the -a/--attach option will instead create\n"
-"    an attachment for the patch. With -i/--inline an inline attachment\n"
-"    will be created."
-msgstr ""
-
-msgid ""
-"    With -o/--outgoing, emails will be generated for patches not found\n"
-"    in the destination repository (or only those which are ancestors\n"
-"    of the specified revisions if any are provided)"
-msgstr ""
-
-msgid ""
-"    With -b/--bundle, changesets are selected as for --outgoing, but a\n"
-"    single email containing a binary Mercurial bundle as an attachment\n"
-"    will be sent."
-msgstr ""
-
-msgid ""
-"      hg email -r 3000          # send patch 3000 only\n"
-"      hg email -r 3000 -r 3001  # send patches 3000 and 3001\n"
-"      hg email -r 3000:3005     # send patches 3000 through 3005\n"
-"      hg email 3000             # send patch 3000 (deprecated)"
-msgstr ""
-
-msgid ""
-"      hg email -o               # send all patches not in default\n"
-"      hg email -o DEST          # send all patches not in DEST\n"
-"      hg email -o -r 3000       # send all ancestors of 3000 not in default\n"
-"      hg email -o -r 3000 DEST  # send all ancestors of 3000 not in DEST"
-msgstr ""
-
-msgid ""
-"      hg email -b               # send bundle of all patches not in default\n"
-"      hg email -b DEST          # send bundle of all patches not in DEST\n"
-"      hg email -b -r 3000       # bundle of all ancestors of 3000 not in "
-"default\n"
-"      hg email -b -r 3000 DEST  # bundle of all ancestors of 3000 not in DEST"
-msgstr ""
-
-msgid ""
-"    Before using this command, you will need to enable email in your\n"
-"    hgrc. See the [email] section in hgrc(5) for details.\n"
-"    "
-msgstr ""
-
-msgid "specify at least one changeset with -r or -o"
-msgstr ""
-
-msgid "--outgoing mode always on with --bundle; do not re-specify --outgoing"
-msgstr ""
-
-msgid "too many destinations"
-msgstr ""
-
-msgid "use only one form to specify the revision"
-msgstr ""
-
-msgid ""
-"\n"
-"Write the introductory message for the patch series."
-msgstr ""
-
-#, python-format
-msgid "This patch series consists of %d patches."
-msgstr ""
-
-msgid "Final summary:\n"
-msgstr ""
-
-msgid "Displaying "
-msgstr ""
-
-msgid "Writing "
-msgstr ""
-
-msgid "Sending "
-msgstr ""
-
 msgid "send patches as attachments"
 msgstr ""
 
@@ -4655,6 +4809,9 @@
 msgid "email addresses of copy recipients"
 msgstr ""
 
+msgid "ask for confirmation before sending"
+msgstr ""
+
 msgid "add diffstat output to messages"
 msgstr ""
 
@@ -4705,6 +4862,8 @@
 
 msgid "run even when remote repository is unrelated (with -b/--bundle)"
 msgstr ""
+"execută chiar când depozitul la distanță este neînrudit\n"
+"(cu -b/--bundle)"
 
 msgid "a base changeset to specify instead of a destination (with -b/--bundle)"
 msgstr ""
@@ -4715,6 +4874,174 @@
 msgid "hg email [OPTION]... [DEST]..."
 msgstr ""
 
+msgid "send changesets by email"
+msgstr ""
+
+msgid ""
+"    By default, diffs are sent in the format generated by\n"
+"    :hg:`export`, one per message. The series starts with a \"[PATCH 0\n"
+"    of N]\" introduction, which describes the series as a whole."
+msgstr ""
+
+msgid ""
+"    Each patch email has a Subject line of \"[PATCH M of N] ...\", using\n"
+"    the first line of the changeset description as the subject text.\n"
+"    The message contains two or three parts. First, the changeset\n"
+"    description."
+msgstr ""
+
+msgid ""
+"    With the -d/--diffstat option, if the diffstat program is\n"
+"    installed, the result of running diffstat on the patch is inserted."
+msgstr ""
+
+msgid "    Finally, the patch itself, as generated by :hg:`export`."
+msgstr ""
+
+msgid ""
+"    With the -d/--diffstat or -c/--confirm options, you will be presented\n"
+"    with a final summary of all messages and asked for confirmation before\n"
+"    the messages are sent."
+msgstr ""
+
+msgid ""
+"    By default the patch is included as text in the email body for\n"
+"    easy reviewing. Using the -a/--attach option will instead create\n"
+"    an attachment for the patch. With -i/--inline an inline attachment\n"
+"    will be created."
+msgstr ""
+
+msgid ""
+"    With -o/--outgoing, emails will be generated for patches not found\n"
+"    in the destination repository (or only those which are ancestors\n"
+"    of the specified revisions if any are provided)"
+msgstr ""
+
+msgid ""
+"    With -b/--bundle, changesets are selected as for --outgoing, but a\n"
+"    single email containing a binary Mercurial bundle as an attachment\n"
+"    will be sent."
+msgstr ""
+
+msgid ""
+"    With -m/--mbox, instead of previewing each patchbomb message in a\n"
+"    pager or sending the messages directly, it will create a UNIX\n"
+"    mailbox file with the patch emails. This mailbox file can be\n"
+"    previewed with any mail user agent which supports UNIX mbox\n"
+"    files."
+msgstr ""
+
+msgid ""
+"    With -n/--test, all steps will run, but mail will not be sent.\n"
+"    You will be prompted for an email recipient address, a subject and\n"
+"    an introductory message describing the patches of your patchbomb.\n"
+"    Then when all is done, patchbomb messages are displayed. If the\n"
+"    PAGER environment variable is set, your pager will be fired up once\n"
+"    for each patchbomb message, so you can verify everything is alright."
+msgstr ""
+
+msgid ""
+"    In case email sending fails, you will find a backup of your series\n"
+"    introductory message in ``.hg/last-email.txt``."
+msgstr ""
+
+msgid ""
+"      hg email -r 3000          # send patch 3000 only\n"
+"      hg email -r 3000 -r 3001  # send patches 3000 and 3001\n"
+"      hg email -r 3000:3005     # send patches 3000 through 3005\n"
+"      hg email 3000             # send patch 3000 (deprecated)"
+msgstr ""
+
+msgid ""
+"      hg email -o               # send all patches not in default\n"
+"      hg email -o DEST          # send all patches not in DEST\n"
+"      hg email -o -r 3000       # send all ancestors of 3000 not in default\n"
+"      hg email -o -r 3000 DEST  # send all ancestors of 3000 not in DEST"
+msgstr ""
+
+msgid ""
+"      hg email -b               # send bundle of all patches not in default\n"
+"      hg email -b DEST          # send bundle of all patches not in DEST\n"
+"      hg email -b -r 3000       # bundle of all ancestors of 3000 not in "
+"default\n"
+"      hg email -b -r 3000 DEST  # bundle of all ancestors of 3000 not in DEST"
+msgstr ""
+
+msgid ""
+"      hg email -o -m mbox &&    # generate an mbox file...\n"
+"        mutt -R -f mbox         # ... and view it with mutt\n"
+"      hg email -o -m mbox &&    # generate an mbox file ...\n"
+"        formail -s sendmail \\   # ... and use formail to send from the "
+"mbox\n"
+"          -bm -t < mbox         # ... using sendmail"
+msgstr ""
+
+msgid ""
+"    Before using this command, you will need to enable email in your\n"
+"    hgrc. See the [email] section in hgrc(5) for details.\n"
+"    "
+msgstr ""
+
+#, python-format
+msgid "comparing with %s\n"
+msgstr "se compară cu %s\n"
+
+msgid "no changes found\n"
+msgstr "nu s-au găsit modificări\n"
+
+msgid "specify at least one changeset with -r or -o"
+msgstr ""
+
+msgid "--outgoing mode always on with --bundle; do not re-specify --outgoing"
+msgstr ""
+
+msgid "too many destinations"
+msgstr ""
+
+msgid "use only one form to specify the revision"
+msgstr ""
+
+msgid ""
+"\n"
+"Write the introductory message for the patch series."
+msgstr ""
+
+#, python-format
+msgid "This patch series consists of %d patches."
+msgstr ""
+
+msgid ""
+"\n"
+"Final summary:"
+msgstr ""
+
+msgid "are you sure you want to send (yn)?"
+msgstr ""
+
+msgid "&No"
+msgstr ""
+
+msgid "&Yes"
+msgstr ""
+
+msgid "patchbomb canceled"
+msgstr ""
+
+msgid "Displaying "
+msgstr ""
+
+msgid "Writing "
+msgstr ""
+
+msgid "writing"
+msgstr ""
+
+msgid "Sending "
+msgstr ""
+
+msgid "sending"
+msgstr ""
+
 msgid "show progress bars for some actions"
 msgstr "afișează bare de progres pentru anumite acțiuni"
 
@@ -4732,7 +5059,7 @@
 "  [progress]\n"
 "  delay = 3 # number of seconds (float) before showing the progress bar\n"
 "  refresh = 0.1 # time in seconds between refreshes of the progress bar\n"
-"  format = topic bar number # format of the progress bar\n"
+"  format = topic bar number estimate # format of the progress bar\n"
 "  width = <none> # if set, the maximum width of the progress information\n"
 "                 # (that is, min(width, term width) will be used)\n"
 "  clear-complete = True # clear the progress bar after it's done\n"
@@ -4742,15 +5069,65 @@
 msgstr ""
 
 msgid ""
-"Valid entries for the format field are topic, bar, number, unit, and\n"
-"item. item defaults to the last 20 characters of the item, but this\n"
-"can be changed by adding either ``-<num>`` which would take the last\n"
-"num characters, or ``+<num>`` for the first num characters.\n"
+"Valid entries for the format field are topic, bar, number, unit,\n"
+"estimate, speed, and item. item defaults to the last 20 characters of\n"
+"the item, but this can be changed by adding either ``-<num>`` which\n"
+"would take the last num characters, or ``+<num>`` for the first num\n"
+"characters.\n"
+msgstr ""
+
+#. i18n: format XX seconds as "XXs"
+#, python-format
+msgid "%02ds"
+msgstr ""
+
+#. i18n: format X minutes and YY seconds as "XmYYs"
+#, python-format
+msgid "%dm%02ds"
+msgstr ""
+
+#. i18n: format X hours and YY minutes as "XhYYm"
+#, python-format
+msgid "%dh%02dm"
+msgstr ""
+
+#. i18n: format X days and YY hours as "XdYYh"
+#, python-format
+msgid "%dd%02dh"
+msgstr ""
+
+#. i18n: format X weeks and YY days as "XwYYd"
+#, python-format
+msgid "%dw%02dd"
+msgstr ""
+
+#. i18n: format X years and YY weeks as "XyYYw"
+#, python-format
+msgid "%dy%02dw"
+msgstr ""
+
+#, python-format
+msgid "%d %s/sec"
 msgstr ""
 
 msgid "command to delete untracked files from the working directory"
 msgstr ""
 
+msgid "abort if an error occurs"
+msgstr ""
+
+msgid "purge ignored files too"
+msgstr ""
+
+msgid "print filenames instead of deleting them"
+msgstr ""
+
+msgid "end filenames with NUL, for use with xargs (implies -p/--print)"
+msgstr ""
+
+msgid "hg purge [OPTION]... [DIR]..."
+msgstr ""
+
 msgid "removes files not tracked by Mercurial"
 msgstr ""
 
@@ -4806,21 +5183,6 @@
 msgid "Removing directory %s\n"
 msgstr ""
 
-msgid "abort if an error occurs"
-msgstr ""
-
-msgid "purge ignored files too"
-msgstr ""
-
-msgid "print filenames instead of deleting them"
-msgstr ""
-
-msgid "end filenames with NUL, for use with xargs (implies -p/--print)"
-msgstr ""
-
-msgid "hg purge [OPTION]... [DIR]..."
-msgstr ""
-
 msgid "command to move sets of revisions to a different ancestor"
 msgstr ""
 
@@ -4834,6 +5196,51 @@
 "http://mercurial.selenic.com/wiki/RebaseExtension\n"
 msgstr ""
 
+msgid "rebase from the specified changeset"
+msgstr ""
+
+msgid ""
+"rebase from the base of the specified changeset (up to greatest common "
+"ancestor of base and dest)"
+msgstr ""
+
+msgid "rebase onto the specified changeset"
+msgstr "repoziționează la setul de modificări specificat"
+
+msgid "collapse the rebased changesets"
+msgstr "restrânge seturile de modificări repoziționate"
+
+msgid "use text as collapse commit message"
+msgstr "folosește textul drept mesaj de depozitare pentru colapsare"
+
+msgid "read collapse commit message from file"
+msgstr "citește mesajul pentru depozitare la colapsare din fișier"
+
+msgid "keep original changesets"
+msgstr ""
+
+msgid "keep original branch names"
+msgstr ""
+
+msgid "force detaching of source from its original branch"
+msgstr ""
+
+msgid "specify merge tool"
+msgstr "specifică instrumentul pentru fuziune"
+
+msgid "continue an interrupted rebase"
+msgstr "continuă o repoziționare întreruptă"
+
+msgid "abort an interrupted rebase"
+msgstr "abandonează o repoziționare întreruptă"
+
+msgid ""
+"hg rebase [-s REV | -b REV] [-d REV] [options]\n"
+"hg rebase {-a|-c}"
+msgstr ""
+"hg rebase [-s REV | -b REV] [-d REV] [opțiuni]\n"
+"hg rebase {-a|-c}"
+
 msgid "move changeset (and descendants) to a different branch"
 msgstr ""
 
@@ -4899,6 +5306,9 @@
 "    "
 msgstr ""
 
+msgid "message can only be specified with collapse"
+msgstr ""
+
 msgid "cannot use both abort and continue"
 msgstr "abort și continue nu se pot folosi împreună"
 
@@ -4911,6 +5321,9 @@
 msgid "abort and continue do not allow specifying revisions"
 msgstr ""
 
+msgid "tool option will be ignored\n"
+msgstr ""
+
 msgid "cannot specify both a revision and a base"
 msgstr ""
 
@@ -4923,16 +5336,13 @@
 msgid "nothing to rebase\n"
 msgstr ""
 
-msgid "cannot use both keepbranches and extrafn"
-msgstr ""
-
 msgid "rebasing"
 msgstr ""
 
-msgid " changesets"
-msgstr "seturi de modificări"
-
-msgid "fix unresolved conflicts with hg resolve then run hg rebase --continue"
+msgid "changesets"
+msgstr ""
+
+msgid "unresolved conflicts (see hg resolve, then hg rebase --continue)"
 msgstr ""
 
 #, python-format
@@ -4965,7 +5375,7 @@
 msgid "warning: new changesets detected on target branch, can't abort\n"
 msgstr ""
 "avertisment: au fost detectate seturi de modificări noi în ramura\n"
-", destinație, nu se poate abandona\n"
+"destinație,r nu se poate abandona\n"
 
 msgid "rebase aborted\n"
 msgstr ""
@@ -4979,44 +5389,14 @@
 msgid "source is descendant of destination"
 msgstr ""
 
+msgid "--tool can only be used with --rebase"
+msgstr ""
+
 msgid "rebase working directory to branch head"
-msgstr ""
-
-msgid "rebase from the specified changeset"
-msgstr ""
-
-msgid ""
-"rebase from the base of the specified changeset (up to greatest common "
-"ancestor of base and dest)"
-msgstr ""
-
-msgid "rebase onto the specified changeset"
-msgstr "dislocă către setul de modificări specificat"
-
-msgid "collapse the rebased changesets"
-msgstr "restrânge seturile de modificări repoziționate"
-
-msgid "keep original changesets"
-msgstr ""
-
-msgid "keep original branch names"
-msgstr ""
-
-msgid "force detaching of source from its original branch"
-msgstr ""
-
-msgid "continue an interrupted rebase"
-msgstr "continuă o repoziționare întreruptă"
-
-msgid "abort an interrupted rebase"
-msgstr "abandonează o repoziționare întreruptă"
-
-msgid ""
-"hg rebase [-s REV | -b REV] [-d REV] [options]\n"
-"hg rebase {-a|-c}"
-msgstr ""
-"hg rebase [-s REV | -b REV] [-d REV] [opțiuni]\n"
-"hg rebase {-a|-c}"
+msgstr "repoziționează directorul de lucru la capătul de ramură"
+
+msgid "specify merge tool for rebase"
+msgstr "specifică instrumentul pentru fuziune pentru rebase"
 
 msgid "commands to interactively select changes for commit/qrefresh"
 msgstr ""
@@ -5076,6 +5456,9 @@
 msgid "record change %d/%d to %r?"
 msgstr ""
 
+msgid "hg record [OPTION]... [FILE]..."
+msgstr "hg record [OPȚIUNE]... [FIȘIER]..."
+
 msgid "interactively select changes to commit"
 msgstr ""
 
@@ -5084,10 +5467,6 @@
 "    will be candidates for recording."
 msgstr ""
 
-msgid "    See :hg:`help dates` for a list of formats valid for -d/--date."
-msgstr ""
-"    Vezi :hg:`help dates` pentru o listă de formate valide cu d/--date."
-
 msgid ""
 "    You will be prompted for whether to record changes to each\n"
 "    modified file, and for files with multiple changes, for each\n"
@@ -5124,27 +5503,34 @@
 msgid "    This command is not available when committing a merge."
 msgstr ""
 
+msgid "interactively record a new patch"
+msgstr "înregistrează interactiv un nou patch"
+
+msgid ""
+"    See :hg:`help qnew` & :hg:`help record` for more information and\n"
+"    usage.\n"
+"    "
+msgstr ""
+
 msgid "'mq' extension not loaded"
 msgstr ""
 
-msgid "running non-interactively, use commit instead"
-msgstr ""
-
-msgid "cannot partially commit a merge (use hg commit instead)"
+#, python-format
+msgid "running non-interactively, use %s instead"
+msgstr ""
+
+msgid "cannot partially commit a merge (use \"hg commit\" instead)"
 msgstr ""
 
 msgid "no changes to record\n"
 msgstr ""
 
-msgid "patch failed to apply"
-msgstr ""
-
-msgid "hg record [OPTION]... [FILE]..."
-msgstr "hg record [OPȚIUNE]... [FIȘIER]..."
-
 msgid "hg qrecord [OPTION]... PATCH [FILE]..."
 msgstr ""
 
+msgid "interactively select changes to refresh"
+msgstr ""
+
 msgid "recreates hardlinks between repository clones"
 msgstr ""
 
@@ -5189,10 +5575,16 @@
 msgid "hardlinks are not supported on this system"
 msgstr ""
 
+msgid "must specify local origin repository"
+msgstr "trebuie să specifice depozitul de origine local"
+
 #, python-format
 msgid "relinking %s to %s\n"
 msgstr ""
 
+msgid "there is nothing to relink\n"
+msgstr ""
+
 #, python-format
 msgid "tip has %d files, estimated total number of files: %s\n"
 msgstr ""
@@ -5214,9 +5606,6 @@
 msgid "not linkable: %s\n"
 msgstr ""
 
-msgid " files"
-msgstr ""
-
 msgid "pruning"
 msgstr ""
 
@@ -5228,7 +5617,7 @@
 msgstr ""
 
 #, python-format
-msgid "relinked %d files (%d bytes reclaimed)\n"
+msgid "relinked %d files (%s reclaimed)\n"
 msgstr ""
 
 msgid "[ORIGIN]"
@@ -5288,6 +5677,10 @@
 "same name.\n"
 msgstr ""
 
+#, python-format
+msgid "custom scheme %s:// conflicts with drive letter %s:\\\n"
+msgstr ""
+
 msgid "share a common history between several working directories"
 msgstr ""
 
@@ -5300,15 +5693,16 @@
 msgstr ""
 
 msgid ""
-"    NOTE: using rollback or extensions that destroy/modify history\n"
-"    (mq, rebase, etc.) can cause considerable confusion with shared\n"
-"    clones. In particular, if two shared clones are both updated to\n"
-"    the same changeset, and one of them destroys that changeset with\n"
-"    rollback, the other clone will suddenly stop working: all\n"
-"    operations will fail with \"abort: working directory has unknown\n"
-"    parent\". The only known workaround is to use debugsetparents on\n"
-"    the broken clone to reset it to a changeset that still exists\n"
-"    (e.g. tip).\n"
+"    .. note::\n"
+"       using rollback or extensions that destroy/modify history (mq,\n"
+"       rebase, etc.) can cause considerable confusion with shared\n"
+"       clones. In particular, if two shared clones are both updated to\n"
+"       the same changeset, and one of them destroys that changeset\n"
+"       with rollback, the other clone will suddenly stop working: all\n"
+"       operations will fail with \"abort: working directory has unknown\n"
+"       parent\". The only known workaround is to use debugsetparents on\n"
+"       the broken clone to reset it to a changeset that still exists\n"
+"       (e.g. tip).\n"
 "    "
 msgstr ""
 
@@ -5359,7 +5753,7 @@
 msgid "%s: empty changeset"
 msgstr ""
 
-msgid "Fix up the merge and run hg transplant --continue"
+msgid "fix up the merge and run hg transplant --continue"
 msgstr ""
 
 #, python-format
@@ -5376,6 +5770,9 @@
 msgid "commit failed"
 msgstr ""
 
+msgid "filter corrupted changeset (no user or date)"
+msgstr ""
+
 msgid ""
 "y: transplant this changeset\n"
 "n: skip this changeset\n"
@@ -5399,13 +5796,50 @@
 msgid "no such option\n"
 msgstr "opțiune inexistentă\n"
 
+msgid "pull patches from REPO"
+msgstr ""
+
+msgid "BRANCH"
+msgstr "RAMURĂ"
+
+msgid "pull patches from branch BRANCH"
+msgstr ""
+
+msgid "pull all changesets up to BRANCH"
+msgstr ""
+
+msgid "skip over REV"
+msgstr "omite REV"
+
+msgid "merge at REV"
+msgstr ""
+
+msgid "append transplant info to log message"
+msgstr ""
+
+msgid "continue last transplant session after repair"
+msgstr ""
+
+msgid "filter changesets through command"
+msgstr ""
+
+msgid "hg transplant [-s REPO] [-b BRANCH [-a]] [-p REV] [-m REV] [REV]..."
+msgstr "hg transplant [-s DEPOZIT] [-b RAMURĂ [-a]] [-p REV] [-m REV] [REV]..."
+
 msgid "transplant changesets from another branch"
 msgstr ""
 
 msgid ""
 "    Selected changesets will be applied on top of the current working\n"
-"    directory with the log of the original changeset. If --log is\n"
-"    specified, log messages will have a comment appended of the form::"
+"    directory with the log of the original changeset. The changesets\n"
+"    are copied and will thus appear twice in the history. Use the\n"
+"    rebase extension instead if you want to move a whole branch of\n"
+"    unpublished changesets."
+msgstr ""
+
+msgid ""
+"    If --log is specified, log messages will have a comment appended\n"
+"    of the form::"
 msgstr ""
 
 msgid "      (transplanted from CHANGESETHASH)"
@@ -5427,9 +5861,9 @@
 msgstr ""
 
 msgid ""
-"    :hg:`transplant --branch REVISION --all` will rebase the selected\n"
-"    branch (up to the named revision) onto your current working\n"
-"    directory."
+"    :hg:`transplant --branch REVISION --all` will transplant the\n"
+"    selected branch (up to the named revision) onto your current\n"
+"    working directory."
 msgstr ""
 
 msgid ""
@@ -5472,35 +5906,15 @@
 msgid "outstanding local changes"
 msgstr "modificări locale în suspensie"
 
-msgid "pull patches from REPO"
-msgstr ""
-
-msgid "BRANCH"
-msgstr "RAMURĂ"
-
-msgid "pull patches from branch BRANCH"
-msgstr ""
-
-msgid "pull all changesets up to BRANCH"
-msgstr ""
-
-msgid "skip over REV"
-msgstr "omite REV"
-
-msgid "merge at REV"
-msgstr ""
-
-msgid "append transplant info to log message"
-msgstr ""
-
-msgid "continue last transplant session after repair"
-msgstr ""
-
-msgid "filter changesets through command"
-msgstr ""
-
-msgid "hg transplant [-s REPO] [-b BRANCH [-a]] [-p REV] [-m REV] [REV]..."
-msgstr "hg transplant [-s DEPOZIT] [-b RAMURĂ [-a]] [-p REV] [-m REV] [REV]..."
+msgid ""
+"``transplanted([set])``\n"
+"    Transplanted changesets in set, or all transplanted changesets."
+msgstr ""
+
+msgid ""
+":transplanted: String. The node identifier of the transplanted\n"
+"    changeset if any."
+msgstr ""
 
 msgid "allow the use of MBCS paths with problematic encodings"
 msgstr ""
@@ -5535,11 +5949,13 @@
 msgid "Note that there are some limitations on using this extension:"
 msgstr ""
 
-msgid "- You should use single encoding in one repository."
-msgstr ""
-
-msgid ""
-"\n"
+msgid ""
+"- You should use single encoding in one repository.\n"
+"- If the repository path ends with 0x5c, .hg/hgrc cannot be read.\n"
+"- win32mbcs is not compatible with fixutf8 extension."
+msgstr ""
+
+msgid ""
 "By default, win32mbcs uses encoding.encoding decided by Mercurial.\n"
 "You can specify the encoding by config option::"
 msgstr ""
@@ -5655,6 +6071,11 @@
 "** = %sdecode:\n"
 msgstr ""
 
+msgid ""
+"win32text is deprecated: http://mercurial.selenic.com/wiki/"
+"Win32TextExtension\n"
+msgstr ""
+
 msgid "discover and advertise repositories on the local network"
 msgstr ""
 
@@ -5694,8 +6115,30 @@
 msgid "unknown archive type '%s'"
 msgstr ""
 
-msgid "invalid changegroup"
-msgstr ""
+msgid "archiving"
+msgstr ""
+
+#, python-format
+msgid "bookmark '%s' contains illegal character"
+msgstr ""
+
+#, python-format
+msgid "branch %s not found"
+msgstr ""
+
+#, python-format
+msgid "updating bookmark %s\n"
+msgstr "se actualizează semnul de carte %s\n"
+
+#, python-format
+msgid "not updating divergent bookmark %s\n"
+msgstr "nu se actualizează semnul de carte divergent %s\n"
+
+msgid "searching for changed bookmarks\n"
+msgstr "se caută semne de carte modificate\n"
+
+msgid "no changed bookmarks found\n"
+msgstr "nu s-au găsit semne de carte modificate\n"
 
 msgid "unknown parent"
 msgstr ""
@@ -5704,23 +6147,23 @@
 msgid "integrity check failed on %s:%d"
 msgstr ""
 
-#, python-format
-msgid "%s: not a Mercurial bundle file"
-msgstr ""
-
-#, python-format
-msgid "%s: unknown bundle version"
-msgstr ""
-
-#, python-format
-msgid "%s: unknown bundle compression type"
-msgstr ""
-
 msgid "cannot create new bundle repository"
 msgstr ""
 
 #, python-format
-msgid "premature EOF reading chunk (got %d bytes, expected %d)"
+msgid "stream ended unexpectedly (got %d bytes, expected %d)"
+msgstr ""
+
+#, python-format
+msgid "invalid chunk length %d"
+msgstr ""
+
+#, python-format
+msgid "%s: not a Mercurial bundle"
+msgstr ""
+
+#, python-format
+msgid "%s: unknown bundle version %s"
 msgstr ""
 
 msgid "empty username"
@@ -5747,24 +6190,25 @@
 msgid "limit must be positive"
 msgstr ""
 
-msgid "too many revisions specified"
-msgstr ""
-
 #, python-format
 msgid "invalid format spec '%%%s' in output filename"
 msgstr ""
 
-#, python-format
-msgid "adding %s\n"
-msgstr "se adaugă %s\n"
-
-#, python-format
-msgid "removing %s\n"
-msgstr ""
-
-#, python-format
-msgid "recording removal of %s as rename to %s (%d%% similar)\n"
-msgstr ""
+msgid "cannot specify --changelog and --manifest at the same time"
+msgstr ""
+
+msgid "cannot specify filename with --changelog or --manifest"
+msgstr ""
+
+msgid "cannot specify --changelog or --manifest without a repository"
+msgstr ""
+
+msgid "invalid arguments"
+msgstr ""
+
+#, python-format
+msgid "revlog '%s' not found"
+msgstr "revlog-ul '%s' nu a fost găsit"
 
 #, python-format
 msgid "%s: not copying - file is not managed\n"
@@ -5806,10 +6250,6 @@
 msgid "copying %s to %s\n"
 msgstr ""
 
-#, python-format
-msgid "%s has not been committed yet, so no copy data will be stored for %s.\n"
-msgstr ""
-
 msgid "no source or destination specified"
 msgstr ""
 
@@ -5841,6 +6281,10 @@
 msgstr "ramură:              %s\n"
 
 #, python-format
+msgid "bookmark:    %s\n"
+msgstr "semn de carte:    %s\n"
+
+#, python-format
 msgid "tag:         %s\n"
 msgstr "etichetă:            %s\n"
 
@@ -5906,6 +6350,14 @@
 msgid "can only follow copies/renames for explicit filenames"
 msgstr ""
 
+#, python-format
+msgid "adding %s\n"
+msgstr "se adaugă %s\n"
+
+#, python-format
+msgid "skipping missing subrepository: %s\n"
+msgstr ""
+
 msgid "HG: Enter commit message.  Lines beginning with 'HG:' are removed."
 msgstr ""
 
@@ -5945,6 +6397,150 @@
 msgid "empty commit message"
 msgstr ""
 
+msgid "repository root directory or name of overlay bundle file"
+msgstr ""
+
+msgid "DIR"
+msgstr "DIR"
+
+msgid "change working directory"
+msgstr "schimbă directorul de lucru "
+
+msgid "do not prompt, assume 'yes' for any required answers"
+msgstr "nu întreba, presupune 'da' pentru orice răspuns solicitat"
+
+msgid "suppress output"
+msgstr "suprimă afișarea"
+
+msgid "enable additional output"
+msgstr "activează afișarea informațiilor suplimentare"
+
+msgid "set/override config option (use 'section.name=value')"
+msgstr ""
+"setează/suprascrie opțiunea de configurare (folosiți 'secțiune.nume=valoare')"
+
+msgid "CONFIG"
+msgstr ""
+
+msgid "enable debugging output"
+msgstr "activează afișarea informațiilor pentru depanare"
+
+msgid "start debugger"
+msgstr "pornește depanatorul (debugger)"
+
+msgid "set the charset encoding"
+msgstr "setează codificarea pentru setul de caractere"
+
+msgid "ENCODE"
+msgstr ""
+
+msgid "MODE"
+msgstr ""
+
+msgid "set the charset encoding mode"
+msgstr "setează modul de codificare pentru setul de caractere"
+
+msgid "always print a traceback on exception"
+msgstr "în caz de excepție, afișează întotdeauna un traceback"
+
+msgid "time how long the command takes"
+msgstr "durata de execuție a comenzii"
+
+msgid "print command execution profile"
+msgstr "afișează profilul executării comenzii"
+
+msgid "output version information and exit"
+msgstr "afișează informații despre versiune și ieși"
+
+msgid "display help and exit"
+msgstr "afișează ajutorul și ieși"
+
+msgid "do not perform actions, just print output"
+msgstr "acțiunea nu se execută, doar se afișează mesajele"
+
+msgid "specify ssh command to use"
+msgstr "specifică comanda ssh care va fi folosită"
+
+msgid "specify hg command to run on the remote side"
+msgstr "specifică comanda hg care va fi executată pe mașina la distanță"
+
+msgid "do not verify server certificate (ignoring web.cacerts config)"
+msgstr ""
+"nu verifica certificatul serverului (ignorând configurarea web.cacerts)"
+
+msgid "PATTERN"
+msgstr "TIPAR"
+
+msgid "include names matching the given patterns"
+msgstr "include numele care se potrivesc cu tiparele specificate"
+
+msgid "exclude names matching the given patterns"
+msgstr "exclude numele care se potrivesc cu tiparele specificate"
+
+msgid "use text as commit message"
+msgstr "folosește textul drept mesaj de depozitare"
+
+msgid "read commit message from file"
+msgstr "citește mesajul pentru depozitare din fișier"
+
+msgid "record the specified date as commit date"
+msgstr "înregistrează data specificată drept dată a depozitării"
+
+msgid "record the specified user as committer"
+msgstr ""
+"înregistrează utilizatorul specificat ca fiind cel care a făcut depozitarea"
+
+msgid "STYLE"
+msgstr "STIL"
+
+msgid "display using template map file"
+msgstr "afișează folosind fișierul cu harta de șabloane"
+
+msgid "display with template"
+msgstr "afișează cu șablon"
+
+msgid "do not show merges"
+msgstr "nu afișa fuziunile"
+
+msgid "output diffstat-style summary of changes"
+msgstr "afișează sumarul modificărilor în stil diffstat"
+
+msgid "treat all files as text"
+msgstr "tratează toate fișierele ca text"
+
+msgid "omit dates from diff headers"
+msgstr "omite datele din antetele diff"
+
+msgid "show which function each change is in"
+msgstr "afișează funcția în care se află fiecare modificare"
+
+msgid "produce a diff that undoes the changes"
+msgstr ""
+
+msgid "ignore white space when comparing lines"
+msgstr "ignoră spațiul alb la compararea liniilor"
+
+msgid "ignore changes in the amount of white space"
+msgstr "ignoră modificările cantității de spațiu alb"
+
+msgid "ignore changes whose lines are all blank"
+msgstr "ignoră modificările ale căror linii sunt toate vide"
+
+msgid "number of lines of context to show"
+msgstr "numărul liniilor de context care vor fi afișate"
+
+msgid "SIMILARITY"
+msgstr "ASEMĂNARE"
+
+msgid "guess renamed files by similarity (0<=s<=100)"
+msgstr "ghicește fișierele redenumite după asemănare (0<=s<=100)"
+
+msgid "recurse into subrepositories"
+msgstr "operează recursiv în subdepozite"
+
+msgid "[OPTION]... [FILE]..."
+msgstr "[OPȚIUNE]... [FIȘIER]..."
+
 msgid "add the specified files on the next commit"
 msgstr "adaugă fișierele specificate la următoarea depozitare ('commit')"
 
@@ -6004,7 +6600,7 @@
 
 msgid ""
 "    New files are ignored if they match any of the patterns in\n"
-"    .hgignore. As with add, these changes take effect at the next\n"
+"    ``.hgignore``. As with add, these changes take effect at the next\n"
 "    commit."
 msgstr ""
 
@@ -6024,10 +6620,42 @@
 msgid "similarity must be between 0 and 100"
 msgstr ""
 
+msgid "annotate the specified revision"
+msgstr "adnotează revizia specificată"
+
+msgid "follow copies/renames and list the filename (DEPRECATED)"
+msgstr ""
+"urmărește copierile/redenumirile și afișează numele\n"
+"fișierului (ÎNVECHIT)"
+
+msgid "don't follow copies and renames"
+msgstr "nu urmări copierile și redenumirile"
+
+msgid "list the author (long with -v)"
+msgstr "afișează autorul (lung cu -v)"
+
+msgid "list the filename"
+msgstr "afișează numele fișierului"
+
+msgid "list the date (short with -q)"
+msgstr "afișează data (scurt cu -q)"
+
+msgid "list the revision number (default)"
+msgstr "afișează numele reviziei (implicit)"
+
+msgid "list the changeset"
+msgstr "afișează setul de modificări"
+
+msgid "show line number at the first appearance"
+msgstr "afișează numărul liniei la prima apariție"
+
+msgid "[-r REV] [-f] [-a] [-u] [-d] [-n] [-c] [-l] FILE..."
+msgstr "[-r REV] [-f] [-a] [-u] [-d] [-n] [-c] [-l] FIȘIER..."
+
 msgid "show changeset information by line for each file"
 msgstr ""
-"afișează informațiile despre setul de modificări line cu linie\n "
-"pentru fiecare fișier"
+"afișează informațiile despre setul de modificări line cu linie\n"
+" pentru fiecare fișier"
 
 msgid ""
 "    List changes in files, showing the revision id responsible for\n"
@@ -6046,13 +6674,6 @@
 "    nor desirable."
 msgstr ""
 
-msgid ""
-"    Returns 0 on success.\n"
-"    "
-msgstr ""
-"    Returnează 0 în caz de succes.\n"
-"    "
-
 msgid "at least one filename or pattern is required"
 msgstr ""
 
@@ -6063,6 +6684,24 @@
 msgid "%s: binary file\n"
 msgstr ""
 
+msgid "do not pass files through decoders"
+msgstr ""
+
+msgid "directory prefix for files in archive"
+msgstr ""
+
+msgid "PREFIX"
+msgstr "PREFIX"
+
+msgid "revision to distribute"
+msgstr ""
+
+msgid "type of distribution to create"
+msgstr ""
+
+msgid "[OPTION]... DEST"
+msgstr "[OPȚIUNE]... DEST"
+
 msgid "create an unversioned archive of a repository revision"
 msgstr ""
 
@@ -6109,25 +6748,44 @@
 msgid "cannot archive plain files to stdout"
 msgstr ""
 
+msgid "merge with old dirstate parent after backout"
+msgstr ""
+
+msgid "parent to choose when backing out merge"
+msgstr ""
+
+msgid "revision to backout"
+msgstr ""
+
+msgid "[OPTION]... [-r] REV"
+msgstr "[OPȚIUNE]... [-r] REV"
+
 msgid "reverse effect of earlier changeset"
 msgstr ""
 
 msgid ""
-"    Commit the backed out changes as a new changeset. The new\n"
-"    changeset is a child of the backed out changeset."
-msgstr ""
-
-msgid ""
-"    If you backout a changeset other than the tip, a new head is\n"
-"    created. This head will be the new tip and you should merge this\n"
-"    backout changeset with another head."
-msgstr ""
-
-msgid ""
-"    The --merge option remembers the parent of the working directory\n"
-"    before starting the backout, then merges the new head with that\n"
-"    changeset afterwards. This saves you from doing the merge by hand.\n"
-"    The result of this merge is not committed, as with a normal merge."
+"    Prepare a new changeset with the effect of REV undone in the\n"
+"    current working directory."
+msgstr ""
+
+msgid ""
+"    If REV is the parent of the working directory, then this new changeset\n"
+"    is committed automatically. Otherwise, hg needs to merge the\n"
+"    changes and the merged result is left uncommitted."
+msgstr ""
+
+msgid ""
+"    By default, the pending changeset will have one parent,\n"
+"    maintaining a linear history. With --merge, the pending changeset\n"
+"    will instead have two parents: the old parent of the working\n"
+"    directory and a new child of REV that simply undoes REV."
+msgstr ""
+
+msgid ""
+"    Before version 1.7, the behavior without --merge was equivalent to\n"
+"    specifying --merge followed by :hg:`update --clean .` to cancel\n"
+"    the merge and leave the child of REV as a head to be merged\n"
+"    separately."
 msgstr ""
 
 msgid "please specify just one revision"
@@ -6160,11 +6818,29 @@
 msgid "merging with changeset %s\n"
 msgstr ""
 
-msgid "the backout changeset is a new head - do not forget to merge\n"
-msgstr ""
-
-msgid "(use \"backout --merge\" if you want to auto-merge)\n"
-msgstr ""
+msgid "reset bisect state"
+msgstr ""
+
+msgid "mark changeset good"
+msgstr "marchează setul de modificări drept bun"
+
+msgid "mark changeset bad"
+msgstr "marchează setul de modificări drept rău"
+
+msgid "skip testing changeset"
+msgstr "omite testarea setului de modificări"
+
+msgid "extend the bisect range"
+msgstr ""
+
+msgid "use command to check changeset state"
+msgstr ""
+
+msgid "do not update to target"
+msgstr "nu actualiza la destinație"
+
+msgid "[-gbsr] [-U] [-c CMD] [REV]"
+msgstr "[-gbsr] [-U] [-c CMD] [REV]"
 
 msgid "subdivision search of changesets"
 msgstr ""
@@ -6206,6 +6882,13 @@
 msgid "The first bad revision is:\n"
 msgstr ""
 
+#, python-format
+msgid ""
+"Not all ancestors of this changeset have been checked.\n"
+"Use bisect --extend to continue the bisection from\n"
+"the common ancestor, %s.\n"
+msgstr ""
+
 msgid "Due to skipped revisions, the first good revision could be any of:\n"
 msgstr ""
 "Datorită reviziilor omise, prima revizie bună ar putea fi oricare\n"
@@ -6241,9 +6924,92 @@
 msgstr ""
 
 #, python-format
+msgid "Extending search to changeset %d:%s\n"
+msgstr "Se extinde căutarea la setul de modificări %d:%s\n"
+
+msgid "nothing to extend"
+msgstr ""
+
+#, python-format
 msgid "Testing changeset %d:%s (%d changesets remaining, ~%d tests)\n"
 msgstr ""
 
+msgid "force"
+msgstr ""
+
+msgid "delete a given bookmark"
+msgstr ""
+
+msgid "rename a given bookmark"
+msgstr ""
+
+msgid "do not mark a new bookmark active"
+msgstr ""
+
+msgid "hg bookmarks [-f] [-d] [-i] [-m NAME] [-r REV] [NAME]"
+msgstr "hg bookmarks [-f] [-d] [-i] [-m NUME] [-r REV] [NUME]"
+
+msgid "track a line of development with movable markers"
+msgstr "urmărește cu marcatori mobili o linie de dezvoltare "
+
+msgid ""
+"    Bookmarks are pointers to certain commits that move when\n"
+"    committing. Bookmarks are local. They can be renamed, copied and\n"
+"    deleted. It is possible to use bookmark names in :hg:`merge` and\n"
+"    :hg:`update` to merge and update respectively to a given bookmark."
+msgstr ""
+
+msgid ""
+"    You can use :hg:`bookmark NAME` to set a bookmark on the working\n"
+"    directory's parent revision with the given name. If you specify\n"
+"    a revision using -r REV (where REV may be an existing bookmark),\n"
+"    the bookmark is assigned to that revision."
+msgstr ""
+
+msgid ""
+"    Bookmarks can be pushed and pulled between repositories (see :hg:`help\n"
+"    push` and :hg:`help pull`). This requires both the local and remote\n"
+"    repositories to support bookmarks. For versions prior to 1.8, this "
+"means\n"
+"    the bookmarks extension must be enabled.\n"
+"    "
+msgstr ""
+
+#, python-format
+msgid "bookmark '%s' does not exist"
+msgstr "semnul de carte '%s' nu există"
+
+#, python-format
+msgid "bookmark '%s' already exists (use -f to force)"
+msgstr ""
+
+msgid "new bookmark name required"
+msgstr ""
+
+msgid "bookmark name required"
+msgstr ""
+
+msgid "bookmark name cannot contain newlines"
+msgstr ""
+
+msgid "bookmark names cannot consist entirely of whitespace"
+msgstr ""
+
+msgid "a bookmark cannot have the name of an existing branch"
+msgstr ""
+
+msgid "no bookmarks set\n"
+msgstr ""
+
+msgid "set branch name even if it shadows an existing branch"
+msgstr ""
+
+msgid "reset branch name to parent branch name"
+msgstr ""
+
+msgid "[-fC] [NAME]"
+msgstr "[-fC] [NAME]"
+
 msgid "set or show the current branch name"
 msgstr "setează sau afișează numele ramurii curente"
 
@@ -6275,14 +7041,26 @@
 msgid "reset working directory to branch %s\n"
 msgstr ""
 
-msgid ""
-"a branch of the same name already exists (use 'hg update' to switch to it)"
+msgid "a branch of the same name already exists"
+msgstr ""
+
+#. i18n: "it" refers to an existing branch
+msgid "use 'hg update' to switch to it"
 msgstr ""
 
 #, python-format
 msgid "marked working directory as branch %s\n"
 msgstr ""
 
+msgid "show only branches that have unmerged heads"
+msgstr "afișează doar ramurile care au capete nefuzionate"
+
+msgid "show normal and closed branches"
+msgstr "afișează ramurile normale și închise"
+
+msgid "[-ac]"
+msgstr ""
+
 msgid "list repository named branches"
 msgstr ""
 
@@ -6311,6 +7089,27 @@
 msgid " (inactive)"
 msgstr ""
 
+msgid "run even when the destination is unrelated"
+msgstr "execută chiar când destinația este neînrudită"
+
+msgid "a changeset intended to be added to the destination"
+msgstr ""
+
+msgid "a specific branch you would like to bundle"
+msgstr "o ramură specifică pe care ați dori să o împachetați (bundle)"
+
+msgid "a base changeset assumed to be available at the destination"
+msgstr ""
+
+msgid "bundle all changesets in the repository"
+msgstr ""
+
+msgid "bundle compression type to use"
+msgstr ""
+
+msgid "[-f] [-t TYPE] [-a] [-r REV]... [--base REV]... FILE [DEST]"
+msgstr ""
+
 msgid "create a changegroup file"
 msgstr ""
 
@@ -6357,6 +7156,18 @@
 msgid "unknown bundle type specified with --type"
 msgstr ""
 
+msgid "print output to file with formatted name"
+msgstr ""
+
+msgid "print the given revision"
+msgstr ""
+
+msgid "apply any matching decode filter"
+msgstr ""
+
+msgid "[OPTION]... FILE..."
+msgstr "[OPȚIUNE]... FIȘIER"
+
 msgid "output the current or given revision of files"
 msgstr ""
 
@@ -6378,6 +7189,21 @@
 "    :``%p``: root-relative path name of file being printed"
 msgstr ""
 
+msgid "the clone will include an empty working copy (only a repository)"
+msgstr "clona va include o copie de lucru vidă (doar un depozit)"
+
+msgid "revision, tag or branch to check out"
+msgstr "revizia, eticheta sau ramura care va fi actualizată"
+
+msgid "include the specified changeset"
+msgstr "include setul de modificări specificat"
+
+msgid "clone only the specified branch"
+msgstr "clonează doar ramura specificată"
+
+msgid "[OPTION]... SOURCE [DEST]"
+msgstr "[OPȚIUNE]... SURSĂ [DEST]"
+
 msgid "make a copy of an existing repository"
 msgstr "realizează o copie a unui depozit existent"
 
@@ -6393,10 +7219,10 @@
 
 msgid ""
 "    The location of the source is added to the new repository's\n"
-"    .hg/hgrc file, as the default to be used for future pulls."
-msgstr ""
-"    Amplasarea sursei este adăugată în fișierul .hg/hgrc al noului\n"
-"    depozit, ca amplasarea implicită pentru viitoarele comenzi 'pull'."
+"    ``.hg/hgrc`` file, as the default to be used for future pulls."
+msgstr ""
+"    Amplasarea sursei este adăugată în fișierul ``.hg/hgrc`` al noului\n"
+"    depozit, ca amplasare implicită pentru viitoarele comenzi 'pull'."
 
 msgid "    See :hg:`help urls` for valid source format details."
 msgstr ""
@@ -6404,13 +7230,13 @@
 
 msgid ""
 "    It is possible to specify an ``ssh://`` URL as the destination, but no\n"
-"    .hg/hgrc and working directory will be created on the remote side.\n"
+"    ``.hg/hgrc`` and working directory will be created on the remote side.\n"
 "    Please see :hg:`help urls` for important details about ``ssh://`` URLs."
 msgstr ""
-"    Ca destinație se poate specifica un URL ``ssh://``, dar nu va fi creat.\n"
+"    Ca destinație se poate specifica un URL ``ssh://``, dar nu va fi creat\n"
 "    niciun fișier .hg/hgrc pe mașina la distanță.\n"
-"    Vezi :hg:`help urls` pentru detalii importante despre URL-urile ``ssh://"
-"``."
+"    Vezi :hg:`help urls` pentru detalii importante despre URL-urile\n"
+"    ``ssh://``."
 
 msgid ""
 "    A set of changesets (tags, or branch names) to pull may be specified\n"
@@ -6478,7 +7304,7 @@
 "    sigur. Operația nu este atomică (rămâne în sarcina dvs. să vă asigurați\n"
 "    că DEP nu este modificat în timpul operației) și trebuie să vă\n"
 "    asigurați că editorul dvs. desface link-urile hard (Emacs si cele mai\n"
-"    multe unelte din kernelul Linux o vor face ). De asemenea, acest mod\n"
+"    multe unelte din kernelul Linux o vor face). De asemenea, acest mod\n"
 "    nu este compatibil cu anumite extensii care își plasează metadatele\n"
 "    în directorul .hg, precum mq."
 
@@ -6518,12 +7344,19 @@
 msgid "cannot specify both --noupdate and --updaterev"
 msgstr ""
 
+msgid "mark new/missing files as added/removed before committing"
+msgstr ""
+"marchează fișierele noi/lipsă ca adăugate/eliminate înainte de depozitare"
+
+msgid "mark a branch as closed, hiding it from the branch list"
+msgstr "marchează o ramură ca închisă, ascunzând-o din lista ramurilor"
+
 msgid "commit the specified files or all outstanding changes"
 msgstr "depozitează fișierele specificate sau toate modificările în suspensie"
 
 msgid ""
 "    Commit changes to the given files into the repository. Unlike a\n"
-"    centralized RCS, this operation is a local operation. See\n"
+"    centralized SCM, this operation is a local operation. See\n"
 "    :hg:`push` for a way to actively distribute your changes."
 msgstr ""
 "    Depozitează modificările fișierelor date în depozit. Spre deosebire\n"
@@ -6566,6 +7399,10 @@
 msgid "can only close branch heads"
 msgstr ""
 
+#, python-format
+msgid "nothing changed (%d missing files, see 'hg status')\n"
+msgstr ""
+
 msgid "nothing changed\n"
 msgstr ""
 
@@ -6580,6 +7417,15 @@
 msgid "committed changeset %d:%s\n"
 msgstr ""
 
+msgid "record a copy that has already occurred"
+msgstr ""
+
+msgid "forcibly copy over an existing managed file"
+msgstr ""
+
+msgid "[OPTION]... [SOURCE]... DEST"
+msgstr "[OPȚIUNE]... [SURSĂ]... DEST"
+
 msgid "mark files as copied for the next commit"
 msgstr ""
 
@@ -6607,13 +7453,33 @@
 "    Returnează 0 în caz de succes, 1 dacă au apărut erori.\n"
 "    "
 
+msgid "[INDEX] REV1 REV2"
+msgstr ""
+
 msgid "find the ancestor revision of two revisions in a given index"
 msgstr ""
 
 msgid "either two or three arguments required"
 msgstr ""
 
-msgid "builds a repo with a given dag from scratch in the current empty repo"
+msgid "add single file mergeable changes"
+msgstr ""
+
+msgid "add single file all revs overwrite"
+msgstr ""
+
+msgid "add new file at each rev"
+msgstr ""
+
+msgid "[OPTION]... [TEXT]"
+msgstr "[OPȚIUNE]... TEXT"
+
+msgid "builds a repo with a given DAG from scratch in the current empty repo"
+msgstr ""
+
+msgid ""
+"    The description of the DAG is read from stdin if not given on the\n"
+"    command line."
 msgstr ""
 
 msgid "    Elements:"
@@ -6631,8 +7497,6 @@
 "     - \"/p2\" is a merge of the preceding node and p2\n"
 "     - \":tag\" defines a local tag for the preceding node\n"
 "     - \"@branch\" sets the named branch for subsequent nodes\n"
-"     - \"!command\" runs the command using your shell\n"
-"     - \"!!my command\\n\" is like \"!\", but to the end of the line\n"
 "     - \"#...\\n\" is a comment up to the end of the line"
 msgstr ""
 
@@ -6652,36 +7516,25 @@
 
 msgid ""
 "    All string valued-elements are either strictly alphanumeric, or must\n"
-"    be enclosed in double quotes (\"...\"), with \"\\\" as escape character."
-msgstr ""
-
-msgid ""
-"    Note that the --overwritten-file and --appended-file options imply the\n"
-"    use of \"HGMERGE=internal:local\" during DAG buildup.\n"
-"    "
-msgstr ""
-
-msgid "need at least one of -m, -a, -o, -n"
+"    be enclosed in double quotes (\"...\"), with \"\\\" as escape "
+"character.\n"
+"    "
+msgstr ""
+
+msgid "reading DAG from stdin\n"
 msgstr ""
 
 msgid "repository is not empty"
 msgstr ""
 
-#, python-format
-msgid "%s command %s"
-msgstr ""
-
-msgid "list all available commands and options"
-msgstr "afișează toate comenzile și opțiunile disponibile"
-
-msgid "returns the completion list associated with the given command"
-msgstr ""
-
-msgid "show information detected about current filesystem"
-msgstr "afișează informațiile detectate despre sistemul de fișiere curent"
-
-msgid "rebuild the dirstate as it would look like for the given revision"
-msgstr ""
+msgid "building"
+msgstr "se generează"
+
+msgid "show all details"
+msgstr "afișează toate detaliile"
+
+msgid "lists the contents of a bundle"
+msgstr "afișează conținutul unui fișier bundle"
 
 msgid "validate the correctness of the current dirstate"
 msgstr ""
@@ -6705,63 +7558,35 @@
 msgid ".hg/dirstate inconsistent with current parent's manifest"
 msgstr ""
 
-msgid "show combined config settings from all hgrc files"
-msgstr "afișează setările de configurare combinate din toate fișierele hgrc"
-
-msgid "    With no arguments, print names and values of all config items."
-msgstr ""
-
-msgid ""
-"    With one argument of the form section.name, print just the value\n"
-"    of that config item."
-msgstr ""
-
-msgid ""
-"    With multiple arguments, print names and values of all config\n"
-"    items with matching section names."
-msgstr ""
-
-msgid ""
-"    With --debug, the source (filename and line number) is printed\n"
-"    for each config item."
-msgstr ""
-
-#, python-format
-msgid "read config from: %s\n"
-msgstr ""
-
-msgid "only one config item permitted"
-msgstr ""
-
-msgid "access the pushkey key/value protocol"
-msgstr ""
-
-msgid "    With two args, list the keys in the given namespace."
-msgstr ""
-
-msgid ""
-"    With five args, set a key to new if it currently is set to old.\n"
-"    Reports success or failure.\n"
-"    "
-msgstr ""
-
-msgid "parse and apply a revision specification"
-msgstr ""
-
-msgid "manually set the parents of the current working directory"
-msgstr ""
-
-msgid ""
-"    This is useful for writing repository conversion tools, but should\n"
-"    be used with care."
-msgstr ""
-
-msgid "show the contents of the current dirstate"
-msgstr "afișează conținutul dirstate-ului curent"
-
-#, python-format
-msgid "copy: %s -> %s\n"
-msgstr ""
+msgid "[COMMAND]"
+msgstr ""
+
+msgid "list all available commands and options"
+msgstr "afișează toate comenzile și opțiunile disponibile"
+
+msgid "show the command options"
+msgstr "afișează opțiunile comenzii"
+
+msgid "[-o] CMD"
+msgstr ""
+
+msgid "returns the completion list associated with the given command"
+msgstr ""
+
+msgid "use tags as labels"
+msgstr ""
+
+msgid "annotate with branch names"
+msgstr ""
+
+msgid "use dots for runs"
+msgstr ""
+
+msgid "separate elements by spaces"
+msgstr ""
+
+msgid "[OPTION]... [FILE [REV]...]"
+msgstr "[OPȚIUNE]... [FIȘIER [REV]...]"
 
 msgid "format the changelog or an index DAG as a concise textual description"
 msgstr ""
@@ -6779,6 +7604,15 @@
 msgid "need repo for changelog dag"
 msgstr ""
 
+msgid "open changelog"
+msgstr "deschide changelog-ul"
+
+msgid "open manifest"
+msgstr "deschide manifestul"
+
+msgid "-c|-m|FILE REV"
+msgstr ""
+
 msgid "dump the contents of a data file revision"
 msgstr ""
 
@@ -6786,14 +7620,76 @@
 msgid "invalid revision identifier %s"
 msgstr ""
 
+msgid "try extended date formats"
+msgstr ""
+
+msgid "[-e] DATE [RANGE]"
+msgstr ""
+
 msgid "parse and display a date"
 msgstr ""
 
+msgid "use old-style discovery"
+msgstr ""
+
+msgid "use old-style discovery with non-heads included"
+msgstr ""
+
+msgid "[-l REV] [-r REV] [-b BRANCH]... [OTHER]"
+msgstr ""
+
+msgid "runs the changeset discovery protocol in isolation"
+msgstr ""
+
+msgid "parse and apply a fileset specification"
+msgstr ""
+
+msgid "[PATH]"
+msgstr ""
+
+msgid "show information detected about current filesystem"
+msgstr "afișează informațiile detectate despre sistemul de fișiere curent"
+
+msgid "id of head node"
+msgstr ""
+
+msgid "id of common node"
+msgstr "id-ul nodului comun"
+
+msgid "REPO FILE [-H|-C ID]..."
+msgstr ""
+
+msgid "retrieves a bundle from a repo"
+msgstr ""
+
+msgid ""
+"    Every ID must be a full-length hex node id string. Saves the bundle to "
+"the\n"
+"    given file.\n"
+"    "
+msgstr ""
+
+msgid "display the combined ignore pattern"
+msgstr ""
+
+msgid "no ignore patterns found"
+msgstr ""
+
+msgid "revlog format"
+msgstr ""
+
+msgid "[-f FORMAT] -c|-m|FILE"
+msgstr ""
+
 msgid "dump the contents of an index file"
-msgstr ""
+msgstr "afișează conținutul unui fișier index"
+
+#, python-format
+msgid "unknown format %d"
+msgstr "format necunoscut %d"
 
 msgid "dump an index DAG as a graphviz dot file"
-msgstr ""
+msgstr "afișează un DAG index sub forma unui fișier dot graphviz"
 
 msgid "test Mercurial installation"
 msgstr ""
@@ -6821,35 +7717,13 @@
 msgid " (templates seem to have been installed incorrectly)\n"
 msgstr ""
 
-msgid "Checking patch...\n"
-msgstr "Se verifică patch-ul\n"
-
-msgid " patch call failed:\n"
-msgstr ""
-
-msgid " unexpected patch output!\n"
-msgstr ""
-
-msgid " patch test failed!\n"
-msgstr ""
-
-msgid ""
-" (Current patch tool may be incompatible with patch, or misconfigured. "
-"Please check your .hgrc file)\n"
-msgstr ""
-
-msgid ""
-" Internal patcher failure, please report this error to http://mercurial."
-"selenic.com/bts/\n"
-msgstr ""
-
 msgid "Checking commit editor...\n"
 msgstr "Se verifică editorul pentru commit...\n"
 
 msgid " No commit editor set and can't find vi in PATH\n"
 msgstr ""
 
-msgid " (specify a commit editor in your .hgrc file)\n"
+msgid " (specify a commit editor in your configuration file)\n"
 msgstr ""
 
 #, python-format
@@ -6859,7 +7733,7 @@
 msgid "Checking username...\n"
 msgstr "Se verifică numele de utilizator...\n"
 
-msgid " (specify a username in your .hgrc file)\n"
+msgid " (specify a username in your configuration file)\n"
 msgstr ""
 
 msgid "No problems detected\n"
@@ -6869,8 +7743,51 @@
 msgid "%s problems detected, please check your install!\n"
 msgstr ""
 
+msgid "REPO ID..."
+msgstr ""
+
+msgid "test whether node ids are known to a repo"
+msgstr ""
+
+msgid ""
+"    Every ID must be a full-length hex node id string. Returns a list of 0s "
+"and 1s\n"
+"    indicating unknown/known.\n"
+"    "
+msgstr ""
+
+msgid "REPO NAMESPACE [KEY OLD NEW]"
+msgstr ""
+
+msgid "access the pushkey key/value protocol"
+msgstr ""
+
+msgid "    With two args, list the keys in the given namespace."
+msgstr ""
+
+msgid ""
+"    With five args, set a key to new if it currently is set to old.\n"
+"    Reports success or failure.\n"
+"    "
+msgstr ""
+
+msgid "revision to rebuild to"
+msgstr ""
+
+msgid "[-r REV] [REV]"
+msgstr ""
+
+msgid "rebuild the dirstate as it would look like for the given revision"
+msgstr ""
+
+msgid "revision to debug"
+msgstr ""
+
+msgid "[-r REV] FILE"
+msgstr ""
+
 msgid "dump rename information"
-msgstr ""
+msgstr "afișează informații despre redenumiri"
 
 #, python-format
 msgid "%s renamed from %s:%s\n"
@@ -6880,11 +7797,59 @@
 msgid "%s not renamed\n"
 msgstr ""
 
+msgid "dump index data"
+msgstr ""
+
+msgid "-c|-m|FILE"
+msgstr ""
+
+msgid "show data and statistics about a revlog"
+msgstr ""
+
+msgid "parse and apply a revision specification"
+msgstr ""
+
+msgid "REV1 [REV2]"
+msgstr ""
+
+msgid "manually set the parents of the current working directory"
+msgstr ""
+
+msgid ""
+"    This is useful for writing repository conversion tools, but should\n"
+"    be used with care."
+msgstr ""
+
+msgid "do not display the saved mtime"
+msgstr ""
+
+msgid "sort by saved mtime"
+msgstr ""
+
+msgid "[OPTION]..."
+msgstr "[OPȚIUNE]..."
+
+msgid "show the contents of the current dirstate"
+msgstr "afișează conținutul dirstate-ului curent"
+
+#, python-format
+msgid "copy: %s -> %s\n"
+msgstr ""
+
+msgid "revision to check"
+msgstr ""
+
 msgid "show how files match on given patterns"
 msgstr "afișează modul în care fișierele se potrivesc cu tiparele specificate"
 
+msgid "REPO [OPTIONS]... [ONE [TWO]]"
+msgstr "DEPOZIT [OPȚIUNI]... [UNU [DOI]]"
+
+msgid "[OPTION]... ([-c REV] | [-r REV1 [-r REV2]]) [FILE]..."
+msgstr "[OPȚIUNE]... ([-c REV] | [-r REV1 [-r REV2]]) [FIȘIER]..."
+
 msgid "diff repository (or selected files)"
-msgstr ""
+msgstr "afișează diferențele (diff) în depozit (sau fișierele selectate)"
 
 msgid "    Show differences between revisions for the specified files."
 msgstr ""
@@ -6893,10 +7858,15 @@
 msgstr ""
 
 msgid ""
-"    NOTE: diff may generate unexpected results for merges, as it will\n"
-"    default to comparing against the working directory's first parent\n"
-"    changeset if no revisions are specified."
-msgstr ""
+"    .. note::\n"
+"       diff may generate unexpected results for merges, as it will\n"
+"       default to comparing against the working directory's first\n"
+"       parent changeset if no revisions are specified."
+msgstr ""
+"    Notă:\n"
+"      `diff` poate genera afișaj diff neașteptat pentru seturi\n"
+"      de modificări de fuziune, deoarece va compara setul de modificări de\n"
+"      fuziune doar cu primul părinte, dacă nu se specifică nicio revizie."
 
 msgid ""
 "    Alternatively you can specify -c/--change with a revision to see\n"
@@ -6914,8 +7884,19 @@
 "    format. For more information, read :hg:`help diffs`."
 msgstr ""
 
+msgid "diff against the second parent"
+msgstr ""
+
+msgid "revisions to export"
+msgstr ""
+
+msgid "[OPTION]... [-o OUTFILESPEC] REV..."
+msgstr "[OPȚIUNE]... [-o SPECFIȘIEȘIRE] REV..."
+
 msgid "dump the header and diffs for one or more changesets"
 msgstr ""
+"afișează antetul și diferențele pentru unul sau mai multe seturi de "
+"modificări"
 
 msgid "    Print the changeset header and diffs for one or more revisions."
 msgstr ""
@@ -6927,10 +7908,15 @@
 msgstr ""
 
 msgid ""
-"    NOTE: export may generate unexpected diff output for merge\n"
-"    changesets, as it will compare the merge changeset against its\n"
-"    first parent only."
-msgstr ""
+"    .. note::\n"
+"       export may generate unexpected diff output for merge\n"
+"       changesets, as it will compare the merge changeset against its\n"
+"       first parent only."
+msgstr ""
+"    Notă:\n"
+"      `export` poate genera afișaj diff neașteptat pentru seturi\n"
+"      de modificări de fuziune, deoarece va compara setul de modificări de\n"
+"      fuziune doar cu primul părinte."
 
 msgid ""
 "    Output may be to a file, in which case the name of the file is\n"
@@ -6974,21 +7960,27 @@
 msgstr ""
 
 msgid "forget the specified files on the next commit"
-msgstr ""
+msgstr "uită fișierele specificate la următoarea depozitare"
 
 msgid ""
 "    Mark the specified files so they will no longer be tracked\n"
 "    after the next commit."
 msgstr ""
+"    Marchează fișierele specificate astfel încât nu vor mai fi\n"
+"    urmărite după următoarea depozitare."
 
 msgid ""
 "    This only removes files from the current branch, not from the\n"
 "    entire project history, and it does not delete them from the\n"
 "    working directory."
 msgstr ""
+"    Aceasta înlătură fișierele doar din ramura curentă, nu din întregul\n"
+"    istoric al proiectului, și nu le șterge din directorul de lucru."
 
 msgid "    To undo a forget before the next commit, see :hg:`add`."
 msgstr ""
+"    Pentru a anula efectul lui `forget` înainte de următoarea\n"
+"    depozitare, vezi :hg:`add`."
 
 msgid "no files specified"
 msgstr ""
@@ -6997,6 +7989,36 @@
 msgid "not removing %s: file is already untracked\n"
 msgstr ""
 
+#, python-format
+msgid "removing %s\n"
+msgstr ""
+
+msgid "end fields with NUL"
+msgstr ""
+
+msgid "print all revisions that match"
+msgstr ""
+
+msgid "follow changeset history, or file history across copies and renames"
+msgstr ""
+"urmărește istoricul seturilor de modificări sau al fișierelor, ținând cont "
+"de copieri și redenumiri"
+
+msgid "ignore case when matching"
+msgstr "ignoră minuscule/majuscule la potrivire"
+
+msgid "print only filenames and revisions that match"
+msgstr "afișează doar numele de fișiere și reviziile care se potrivesc"
+
+msgid "print matching line numbers"
+msgstr "afișează numerele liniilor care se potrivesc"
+
+msgid "only search files changed within revision range"
+msgstr "caută doar fișierele modificate în intervalul de revizii"
+
+msgid "[OPTION]... PATTERN [FILE]..."
+msgstr "[OPȚIUNE]... TIPAR [FIȘIER]..."
+
 msgid "search for a pattern in specified files and revisions"
 msgstr ""
 
@@ -7029,6 +8051,24 @@
 msgid "grep: invalid match pattern: %s\n"
 msgstr ""
 
+msgid "STARTREV"
+msgstr ""
+
+msgid "show only heads which are descendants of STARTREV"
+msgstr "afișează doar capetele care sunt descendenți ai REVSTART"
+
+msgid "show topological heads only"
+msgstr "afișează doar capetele topologice"
+
+msgid "show active branchheads only (DEPRECATED)"
+msgstr "afișează doar capetele de ramură active [ÎNVECHIT]"
+
+msgid "show normal and closed branch heads"
+msgstr " afișează capetele de ramură normale și închise"
+
+msgid "[-ac] [-r STARTREV] [REV]..."
+msgstr "[-ac] [-r REV] [REVSTART]..."
+
 msgid "show current repository heads or show branch heads"
 msgstr "afișează capetele curente ale depozitului sau capetele de ramură"
 
@@ -7078,6 +8118,15 @@
 msgid " (started at %s)"
 msgstr ""
 
+msgid "show only help for extensions"
+msgstr "afișează doar ajutorul pentru extensii"
+
+msgid "show only help for commands"
+msgstr "afișează doar ajutorul pentru comenzi"
+
+msgid "[-ec] [TOPIC]"
+msgstr "[-ec] [SUBIECT]"
+
 msgid "show help for a given topic or a help overview"
 msgstr ""
 "afișează ajutorul pentru un anumit subiect sau un rezumat al ajutorului"
@@ -7110,10 +8159,14 @@
 "detalii"
 
 #, python-format
-msgid "use \"hg -v help%s\" to show aliases and global options"
-msgstr ""
-"folosiți \"hg -v help%s\" pentru afișarea alias-urilor și a opțiunilor "
-"globale"
+msgid "use \"hg help %s\" to show the full help text"
+msgstr "folosiți \"hg help %s\" pentru afișarea textului complet al ajutorului"
+
+#, python-format
+msgid "use \"hg -v help%s\" to show builtin aliases and global options"
+msgstr ""
+"folosiți \"hg -v help%s\" pentru afișarea alias-urilor și a opțiunilor\n"
+"globale integrate"
 
 #, python-format
 msgid "use \"hg -v help %s\" to show global options"
@@ -7160,9 +8213,23 @@
 msgid "options:\n"
 msgstr "opțiuni:\n"
 
+#, python-format
+msgid "use \"hg help -e %s\" to show help for the %s extension"
+msgstr ""
+"folosiți \"hg help -e %s\" pentru afișarea ajutorului pentru\n"
+"extensia %s"
+
 msgid "no commands defined\n"
 msgstr ""
 
+#, python-format
+msgid ""
+"\n"
+"use \"hg help -c %s\" to see help for the %s command\n"
+msgstr ""
+"\n"
+"folosiți \"hg help -c %s\" pentru a vedea ajutorul pentru comanda %s\n"
+
 msgid "no help text available"
 msgstr ""
 
@@ -7181,7 +8248,7 @@
 msgstr "Mercurial - gestionar distribuit pentru controlul codului sursă\n"
 
 msgid "basic commands:"
-msgstr ""
+msgstr "comenzi de bază:"
 
 msgid "enabled extensions:"
 msgstr "extensii activate:"
@@ -7206,11 +8273,39 @@
 "\n"
 "subiecte de ajutor suplimentare:"
 
+msgid "identify the specified revision"
+msgstr "identifică revizia specificată"
+
+msgid "show local revision number"
+msgstr "afișează numărul de revizie local"
+
+msgid "show global revision id"
+msgstr "afișează id-ul global al reviziei"
+
+msgid "show branch"
+msgstr "afișează ramura"
+
+msgid "show tags"
+msgstr "afișează etichetele"
+
+msgid "show bookmarks"
+msgstr "arată semnele de carte"
+
+msgid "[-nibtB] [-r REV] [SOURCE]"
+msgstr "[-nibtB] [-r REV] [SURSĂ]"
+
 msgid "identify the working copy or specified revision"
 msgstr ""
 
 msgid ""
-"    With no revision, print a summary of the current state of the\n"
+"    Print a summary identifying the repository state at REV using one or\n"
+"    two parent hash identifiers, followed by a \"+\" if the working\n"
+"    directory has uncommitted changes, the branch name (if not default),\n"
+"    a list of tags, and a list of bookmarks."
+msgstr ""
+
+msgid ""
+"    When REV is not given, print a summary of the current state of the\n"
 "    repository."
 msgstr ""
 
@@ -7219,12 +8314,36 @@
 "    cause lookup to operate on that repository/bundle."
 msgstr ""
 
-msgid ""
-"    This summary identifies the repository state using one or two\n"
-"    parent hash identifiers, followed by a \"+\" if there are\n"
-"    uncommitted changes in the working directory, a list of tags for\n"
-"    this revision and a branch name for non-default branches."
-msgstr ""
+msgid "can't query remote revision number, branch, or tags"
+msgstr ""
+
+msgid ""
+"directory strip option for patch. This has the same meaning as the "
+"corresponding patch option"
+msgstr ""
+
+msgid "PATH"
+msgstr "CALE"
+
+msgid "base path (DEPRECATED)"
+msgstr ""
+
+msgid "skip check for outstanding uncommitted changes"
+msgstr "omite verificarea pentru modificări nedepozitate în suspensie"
+
+msgid "don't commit, just update the working directory"
+msgstr "nu depozita, doar actualizează directorul de lucru"
+
+msgid "apply patch to the nodes from which it was generated"
+msgstr "aplică patch-ul nodurilor pentru care a fost generat"
+
+msgid "use any branch information in patch (implied by --exact)"
+msgstr ""
+"folosește orice informație despre ramură din patch\n"
+"(implicat de --exact)"
+
+msgid "[OPTION]... PATCH..."
+msgstr "[OPȚIUNE]... PATCH"
 
 msgid "import an ordered set of patches"
 msgstr ""
@@ -7293,6 +8412,29 @@
 msgid "no diffs found"
 msgstr ""
 
+msgid "run even if remote repository is unrelated"
+msgstr "execută chiar dacă depozitul la distanță este neînrudit"
+
+msgid "show newest record first"
+msgstr "afișează începând cu cea mai nouă înregistrare"
+
+msgid "file to store the bundles into"
+msgstr "fișierul în care va fi salvat bundle-ul"
+
+msgid "a remote changeset intended to be added"
+msgstr ""
+"un set de modificări la distanță care se intenționează a fi\n"
+"adăugat"
+
+msgid "compare bookmarks"
+msgstr "compară semnele de carte"
+
+msgid "a specific branch you would like to pull"
+msgstr "o ramură specifică pe care ați dori să o trimiteți"
+
+msgid "[-p] [-n] [-M] [-f] [-r REV]... [--bundle FILENAME] [SOURCE]"
+msgstr "[-p] [-n] [-M] [-f] [-r REV]... [--bundle NUMEFIȘIER] [SURSĂ]"
+
 msgid "show new changesets found in source"
 msgstr "afișează seturile de modificări noi găsite în sursă"
 
@@ -7301,11 +8443,18 @@
 "    pull location. These are the changesets that would have been pulled\n"
 "    if a pull at the time you issued this command."
 msgstr ""
+"    Afișează seturile noi de modificări găsite în calea sau URL-ul\n"
+"    specificat sau la amplasarea implicită pentru 'pull'. Acestea\n"
+"    sunt seturi care ar fi fost aduse dacă s-ar fi executat o\n"
+"    comandă 'pull' la momentul emiterii comenzii."
 
 msgid ""
 "    For remote repository, using --bundle avoids downloading the\n"
 "    changesets twice if the incoming is followed by a pull."
 msgstr ""
+"    Pentru depozitul la distantă, folosirea lui --bundle evită\n"
+"    descărcarea de două ori a setului de modificări în cazul\n"
+"    în care 'incoming' este urmat de 'pull'."
 
 msgid "    See pull for valid source format details."
 msgstr "    Vezi pull pentru detalii legate de formate valide de surse."
@@ -7317,6 +8466,15 @@
 "    Returnează 0 dacă există modificări de primit, 1 altfel.\n"
 "    "
 
+msgid "cannot combine --bundle and --subrepos"
+msgstr ""
+
+msgid "remote doesn't support bookmarks\n"
+msgstr ""
+
+msgid "[-e CMD] [--remotecmd CMD] [DEST]"
+msgstr "[-e CMD] [--remotecmd CMD] [DEST]"
+
 msgid "create a new repository in the given directory"
 msgstr "creează un nou depozit în directorul specificat"
 
@@ -7338,6 +8496,18 @@
 "    Ca destinație se poate specifica un URL ``ssh://``.\n"
 "    Vezi :hg:`help urls` pentru mai multe detalii."
 
+msgid "search the repository as it is in REV"
+msgstr "caută depozitul așa cum este el în REV"
+
+msgid "end filenames with NUL, for use with xargs"
+msgstr "termină numele de fișiere cu NUL, pentru utilizare cu xargs"
+
+msgid "print complete paths from the filesystem root"
+msgstr "afișează căi complete de la rădăcina sistemului de fișiere"
+
+msgid "[OPTION]... [PATTERN]..."
+msgstr "[OPȚIUNE]... [TIPAR]..."
+
 msgid "locate files matching specific patterns"
 msgstr ""
 
@@ -7364,6 +8534,42 @@
 "    contain whitespace as multiple filenames."
 msgstr ""
 
+msgid "only follow the first parent of merge changesets"
+msgstr "urmărește doar primul părinte al seturilor de modificări de fuziune"
+
+msgid "show revisions matching date spec"
+msgstr "afișează reviziile care se potrivesc cu data"
+
+msgid "show copied files"
+msgstr "afișează fișierele copiate"
+
+msgid "do case-insensitive search for a given text"
+msgstr "caută textul specificat fără a diferenția între minuscule și majuscule"
+
+msgid "include revisions where files were removed"
+msgstr "include reviziile în care au fost eliminate fișiere"
+
+msgid "show only merges"
+msgstr "afișează doar fuziunile"
+
+msgid "revisions committed by user"
+msgstr "reviziile depozitate de utilizatorul"
+
+msgid "show only changesets within the given named branch (DEPRECATED)"
+msgstr ""
+"afișează doar seturile de modificări din interiorul ramurii denumite\n"
+"specificate (ÎNVECHIT)"
+
+msgid "show changesets within the given named branch"
+msgstr ""
+"afișează seturile de modificări din cadrul ramurii denumite specificate"
+
+msgid "do not display revision or any of its ancestors"
+msgstr "nu afișa revizia sau oricare din strămoșii ei"
+
+msgid "[OPTION]... [FILE]"
+msgstr "[OPȚIUNE]... [FIȘIER]"
+
 msgid "show revision history of entire repository or files"
 msgstr ""
 "afișează istoricul reviziilor pentru întregul depozit sau pentru unele "
@@ -7390,16 +8596,15 @@
 "    urmărește doar primul părinte al reviziilor fuzionate."
 
 msgid ""
-"    If no revision range is specified, the default is tip:0 unless\n"
+"    If no revision range is specified, the default is ``tip:0`` unless\n"
 "    --follow is set, in which case the working directory parent is\n"
 "    used as the starting revision. You can specify a revision set for\n"
 "    log, see :hg:`help revsets` for more information."
 msgstr ""
 "    Dacă nu se specifică niciun interval de revizii, acesta este implicit\n"
-"    tip:0 (vârf:0), cu excepția cazului când --follow este setat, în "
-"această\n"
-"    situație părintele directorului de lucru este folosit ca revizie de "
-"stat.\n"
+"    tip:0 (vârf:0), cu excepția cazului când --follow este setat, în\n"
+"    această situație părintele directorului de lucru este folosit ca\n"
+"    revizie de start.\n"
 "    Puteți specifica un set de revizii pentru 'log'; pentru mai multe\n"
 "    informații, vezi :hg:`help revsets`."
 
@@ -7415,15 +8620,26 @@
 "    se afișează lista fișierelor modificate și mesajul de depozitare complet."
 
 msgid ""
-"    NOTE: log -p/--patch may generate unexpected diff output for merge\n"
-"    changesets, as it will only compare the merge changeset against\n"
-"    its first parent. Also, only files different from BOTH parents\n"
-"    will appear in files:."
-msgstr ""
-"    NOTĂ: log -p/--patch poate genera afișaj diff neașteptat pentru seturi\n"
-"    de modificări de fuziune, deoarece va compara setul de modificări de\n"
-"    fuziune doar cu primul părinte. De asemenea, doar fișierele diferite\n"
-"    față de AMBII părinți vor apărea în lista de fișiere."
+"    .. note::\n"
+"       log -p/--patch may generate unexpected diff output for merge\n"
+"       changesets, as it will only compare the merge changeset against\n"
+"       its first parent. Also, only files different from BOTH parents\n"
+"       will appear in files:."
+msgstr ""
+"    Notă:\n"
+"      `log -p/--patch` poate genera afișaj diff neașteptat pentru seturi\n"
+"      de modificări de fuziune, deoarece va compara setul de modificări de\n"
+"      fuziune doar cu primul părinte. De asemenea, doar fișierele diferite\n"
+"      față de AMBII părinți vor apărea în lista de fișiere."
+
+msgid "revision to display"
+msgstr "revizia de afișat"
+
+msgid "list files from all revisions"
+msgstr "afișează fișierele din toate reviziile"
+
+msgid "[-r REV]"
+msgstr "[-r REV]"
 
 msgid "output the current or given revision of the project manifest"
 msgstr ""
@@ -7439,6 +8655,28 @@
 "    With --debug, print file revision hashes."
 msgstr ""
 
+msgid ""
+"    If option --all is specified, the list of all files from all revisions\n"
+"    is printed. This includes deleted and renamed files."
+msgstr ""
+
+msgid "can't specify a revision with --all"
+msgstr ""
+
+msgid "force a merge with outstanding changes"
+msgstr "forțează o fuziune cu modificări în suspensie"
+
+msgid "revision to merge"
+msgstr "revizia de fuzionat"
+
+msgid "review revisions to merge (no merge is performed)"
+msgstr ""
+"treci în revistă reviziile de fuzionat (nu se execută\n"
+"nicio fuziune)"
+
+msgid "[-P] [-f] [[-r] REV]"
+msgstr "[-P] [-f] [[-r] REV]"
+
 msgid "merge working directory with another revision"
 msgstr "fuzionează directorul de lucru cu o altă revizie"
 
@@ -7462,6 +8700,16 @@
 "    doi părinți."
 
 msgid ""
+"    ``--tool`` can be used to specify the merge tool used for file\n"
+"    merges. It overrides the HGMERGE environment variable and your\n"
+"    configuration files. See :hg:`help merge-tools` for options."
+msgstr ""
+"    ``--tool`` poate fi folosit pentru a specifica instrumentul\n"
+"    pentru fuziune folosit la fuziunile de fișiere. Acesta\n"
+"    prevalează asupra variabilei de mediu HGMERGE și a fișierelor\n"
+"    dvs. de configurare. Pentru opțiuni vezi :hg:`help merge-tools`."
+
+msgid ""
 "    If no revision is specified, the working directory's parent is a\n"
 "    head revision, and the current branch contains exactly one other\n"
 "    head, the other head is merged with by default. Otherwise, an\n"
@@ -7473,6 +8721,11 @@
 "    capăt. Altfel, o revizie explicită cu care să aibă loc fuziunea\n"
 "    trebuie specificată."
 
+msgid "    :hg:`resolve` must be used to resolve unresolved files."
+msgstr ""
+"    :hg:`resolve` trebuie folosit pentru a rezolva fișierele\n"
+"    nerezolvate."
+
 msgid ""
 "    To undo an uncommitted merge, use :hg:`update --clean .` which\n"
 "    will check out a clean copy of the original merge parent, losing\n"
@@ -7490,15 +8743,17 @@
 "    "
 
 #, python-format
-msgid ""
-"branch '%s' has %d heads - please merge with an explicit rev\n"
-"(run 'hg heads .' to see heads)"
-msgstr ""
-
-#, python-format
-msgid ""
-"branch '%s' has one head - please merge with an explicit rev\n"
-"(run 'hg heads' to see all heads)"
+msgid "branch '%s' has %d heads - please merge with an explicit rev"
+msgstr ""
+
+msgid "run 'hg heads .' to see heads"
+msgstr ""
+
+#, python-format
+msgid "branch '%s' has one head - please merge with an explicit rev"
+msgstr ""
+
+msgid "run 'hg heads' to see all heads"
 msgstr ""
 
 msgid "there is nothing to merge"
@@ -7508,10 +8763,20 @@
 msgid "%s - use \"hg update\" instead"
 msgstr ""
 
-msgid ""
-"working dir not at a head rev - use \"hg update\" or merge with an explicit "
-"rev"
-msgstr ""
+msgid "working directory not at a head revision"
+msgstr "directorul de lucru nu se află la o revizie capăt"
+
+msgid "use 'hg update' or merge with an explicit revision"
+msgstr ""
+
+msgid "a changeset intended to be included in the destination"
+msgstr "un set de modificări care se dorește a fi inclus în destinație"
+
+msgid "a specific branch you would like to push"
+msgstr "o ramură specifică pe care ați dori să o preluați"
+
+msgid "[-M] [-p] [-n] [-f] [-r REV]... [DEST]"
+msgstr "[-M] [-p] [-n] [-f] [-r REV]... [DEST]"
 
 msgid "show changesets not found in the destination"
 msgstr "afișează seturile de modificări negăsite în destinație"
@@ -7521,9 +8786,16 @@
 "    or the default push location. These are the changesets that would\n"
 "    be pushed if a push was requested."
 msgstr ""
+"    Afișează seturile de modificări care nu se regăsesc în depozitul\n"
+"    destinație specificat sau în calea pentru 'push' implicită\n"
+"    'default'. Acestea sunt seturile de modificări care ar fi\n"
+"    difuzate dacă s-ar executa o comandă 'push' la momentul\n"
+"    emiterii comenzii."
 
 msgid "    See pull for details of valid destination formats."
 msgstr ""
+"    Vezi 'pull' pentru detalii legate de formatele valide pentru\n"
+"    destinații."
 
 msgid ""
 "    Returns 0 if there are outgoing changes, 1 otherwise.\n"
@@ -7532,6 +8804,12 @@
 "    Returnează 0 dacă există modificări de trimis, 1 altfel.\n"
 "    "
 
+msgid "show parents of the specified revision"
+msgstr "afișează părinții reviziei specificate"
+
+msgid "[-r REV] [FILE]"
+msgstr "[-r REV] [FIȘIER]"
+
 msgid "show the parents of the working directory or revision"
 msgstr "afișează părinții directorului de lucru sau al reviziei"
 
@@ -7550,6 +8828,9 @@
 msgid "'%s' not found in manifest!"
 msgstr "'%s' nu a fost găsit în manifest!"
 
+msgid "[NAME]"
+msgstr "[NUME]"
+
 msgid "show aliases for remote repositories"
 msgstr "afișează alias-urile pentru depozitele la distanță"
 
@@ -7559,8 +8840,13 @@
 msgstr ""
 
 msgid ""
-"    Path names are defined in the [paths] section of\n"
-"    ``/etc/mercurial/hgrc`` and ``$HOME/.hgrc``. If run inside a\n"
+"    Option -q/--quiet suppresses all output when searching for NAME\n"
+"    and shows only the path names when listing all definitions."
+msgstr ""
+
+msgid ""
+"    Path names are defined in the [paths] section of your\n"
+"    configuration file and in ``/etc/mercurial/hgrc``. If run inside a\n"
 "    repository, ``.hg/hgrc`` is used, too."
 msgstr ""
 
@@ -7583,20 +8869,44 @@
 msgid "not found!\n"
 msgstr ""
 
-msgid "not updating, since new heads added\n"
-msgstr "nu se actualizează deoarece au fost adăugate noi capete\n"
+#, python-format
+msgid "not updating: %s\n"
+msgstr "nu se actualizează: %s\n"
 
 msgid "(run 'hg heads' to see heads, 'hg merge' to merge)\n"
 msgstr ""
 
+msgid "(run 'hg heads .' to see heads, 'hg merge' to merge)\n"
+msgstr ""
+
+msgid "(run 'hg heads' to see heads)\n"
+msgstr ""
+
 msgid "(run 'hg update' to get a working copy)\n"
 msgstr ""
 
+msgid "update to new branch head if changesets were pulled"
+msgstr ""
+"actualizează la noul capăt de ramură, dacă au fost preluate\n"
+"seturi de modificări"
+
+msgid "run even when remote repository is unrelated"
+msgstr "execută chiar când depozitul la distanță este neînrudit"
+
+msgid "BOOKMARK"
+msgstr ""
+
+msgid "bookmark to pull"
+msgstr "semnul de carte de importat"
+
+msgid "[-u] [-f] [-r REV]... [-e CMD] [--remotecmd CMD] [SOURCE]"
+msgstr "[-u] [-f] [-r REV]... [-e CMD] [--remotecmd CMD] [SURSĂ]"
+
 msgid "pull changes from the specified source"
-msgstr ""
+msgstr "preia modificări de la sursa specificată"
 
 msgid "    Pull changes from a remote repository to a local one."
-msgstr ""
+msgstr "    Preia modificări dintr-un depozit la distanță într-unul local."
 
 msgid ""
 "    This finds all changes from the repository at the specified path\n"
@@ -7604,6 +8914,10 @@
 "    -R is specified). By default, this does not update the copy of the\n"
 "    project in the working directory."
 msgstr ""
+"    Găsește toate modificările din depozit la calea sau URL-ul\n"
+"    specificat și le adaugă la un depozit local (cel curent, dacă nu\n"
+"    se specifică -R). Implicit, copia proiectului din directorul\n"
+"    curent nu este actualizată."
 
 msgid ""
 "    Use :hg:`incoming` if you want to see what would have been added\n"
@@ -7611,11 +8925,18 @@
 "    to add those changes to the repository, you should use :hg:`pull\n"
 "    -r X` where ``X`` is the last changeset listed by :hg:`incoming`."
 msgstr ""
+"    Folosiți :hg:`incoming` dacă doriți să vedeți ce ar fi adăugat un\n"
+"    `pull` la momentul la care ați emis această comandă. Dacă după\n"
+"    aceasta decideți să adăugați aceste modificări în depozit,\n"
+"    folosiți :hg:`pull -r X`, unde ``X`` este ultimul set de\n"
+"    modificări afișat de :hg:`incoming`."
 
 msgid ""
 "    If SOURCE is omitted, the 'default' path will be used.\n"
 "    See :hg:`help urls` for more information."
 msgstr ""
+"    Dacă SURSA este omisă, va fi folosită calea implicită 'default'.\n"
+"    Pentru mai multe informații, vezi :hg:`help urls`."
 
 msgid ""
 "    Returns 0 on success, 1 if an update had unresolved files.\n"
@@ -7625,18 +8946,47 @@
 "    fișiere nerezolvate.\n"
 "    "
 
+#, python-format
+msgid "remote bookmark %s not found!"
+msgstr ""
+
+msgid ""
+"other repository doesn't support revision lookup, so a rev cannot be "
+"specified."
+msgstr ""
+
+#, python-format
+msgid "importing bookmark %s\n"
+msgstr ""
+
+msgid "force push"
+msgstr "forțează `push`"
+
+msgid "bookmark to push"
+msgstr "semnul de carte de exportat"
+
+msgid "allow pushing a new branch"
+msgstr "permite trimiterea unei ramuri noi"
+
+msgid "[-f] [-r REV]... [-e CMD] [--remotecmd CMD] [DEST]"
+msgstr "[-f] [-r REV]... [-e CMD] [--remotecmd CMD] [DEST]"
+
 msgid "push changes to the specified destination"
-msgstr ""
+msgstr "trimite modificări către destinația specificată"
 
 msgid ""
 "    Push changesets from the local repository to the specified\n"
 "    destination."
 msgstr ""
+"    Trimite seturi de modificări din depozitul local către\n"
+"    destinația specificată."
 
 msgid ""
 "    This operation is symmetrical to pull: it is identical to a pull\n"
 "    in the destination repository from the current one."
 msgstr ""
+"    Această operație este simetrică cu `pull`: este identică cu un\n"
+"    `pull` din directorul curent, aplicat în directorul destinație."
 
 msgid ""
 "    By default, push will not allow creation of new heads at the\n"
@@ -7644,40 +8994,72 @@
 "    to use. In this situation, it is recommended to pull and merge\n"
 "    before pushing."
 msgstr ""
+"    Implicit, `push` nu va permite crearea de capete noi la\n"
+"    destinație, deoarece capetele multiple ar crea neclarități\n"
+"    privind capătul care trebuie folosit. În această situație\n"
+"    este recomandat să executați `pull` și `merge` înainte de\n"
+"    `push`."
 
 msgid ""
 "    Use --new-branch if you want to allow push to create a new named\n"
 "    branch that is not present at the destination. This allows you to\n"
 "    only create a new branch without forcing other changes."
 msgstr ""
+"    Folosiți --new-branch dacă doriți să permiteți lui `push` să\n"
+"    creeze o nouă ramură cu nume care nu este prezentă la\n"
+"    destinație. Aceasta vă permite să creați doar o ramură nouă,\n"
+"    fără a forța alte modificări."
 
 msgid ""
 "    Use -f/--force to override the default behavior and push all\n"
 "    changesets on all branches."
 msgstr ""
+"    Folosiți -f/--force pentru a înlocui comportamentul implicit\n"
+"    și a trimite toate modificările din toate ramurile."
 
 msgid ""
 "    If -r/--rev is used, the specified revision and all its ancestors\n"
 "    will be pushed to the remote repository."
 msgstr ""
+"    Dacă se folosește -r/--rev, revizia specificată și toți\n"
+"    strămoșii ei vor fi trimiși către depozitul la distanță."
 
 msgid ""
 "    Please see :hg:`help urls` for important details about ``ssh://``\n"
 "    URLs. If DESTINATION is omitted, a default path will be used."
 msgstr ""
+"    Vezi :hg:`help urls` pentru detalii importante despre URL-urile\n"
+"    ``ssh://``. Dacă DESTINAȚIA este omisă, se va folosi o cale\n"
+"    implicită."
 
 msgid ""
 "    Returns 0 if push was successful, 1 if nothing to push.\n"
 "    "
 msgstr ""
-"    Returnează 0 dacă 'push' s-a încheiat cu succes, 1 dacă nu există\n"
-"    nimic pentru 'push'.\n"
+"    Returnează 0 dacă trimiterea s-a încheiat cu succes, 1 dacă nu există\n"
+"    nimic de trimis.\n"
 "    "
 
 #, python-format
 msgid "pushing to %s\n"
 msgstr ""
 
+#, python-format
+msgid "exporting bookmark %s\n"
+msgstr ""
+
+#, python-format
+msgid "deleting remote bookmark %s\n"
+msgstr ""
+
+#, python-format
+msgid "bookmark %s does not exist on the local or remote repository!\n"
+msgstr ""
+
+#, python-format
+msgid "updating bookmark %s failed!\n"
+msgstr "actualizarea semnului de carte %s a eșuat!\n"
+
 msgid "roll back an interrupted transaction"
 msgstr ""
 
@@ -7698,6 +9080,12 @@
 "    sau verificarea eșuează.\n"
 "    "
 
+msgid "record delete for missing files"
+msgstr "înregistrează ștergere pentru fișierele lipsă"
+
+msgid "remove (and delete) file even if added or modified"
+msgstr "înlătură (și șterge) fișierul chiar dacă este adăugat sau modificat"
+
 msgid "remove the specified files on the next commit"
 msgstr "înlătură fișierele specificate la următoarea depozitare"
 
@@ -7745,6 +9133,11 @@
 "      -Af     Î  Î  Î  Î"
 
 msgid ""
+"    Note that remove never deletes files in Added [A] state from the\n"
+"    working directory, not even if option --force is specified."
+msgstr ""
+
+msgid ""
 "    This command schedules the files to be removed at the next commit.\n"
 "    To undo a remove before that, see :hg:`revert`."
 msgstr ""
@@ -7764,17 +9157,23 @@
 msgstr ""
 
 #, python-format
-msgid "not removing %s: file %s (use -f to force removal)\n"
-msgstr ""
-
-msgid "still exists"
-msgstr ""
-
-msgid "is modified"
-msgstr ""
-
-msgid "has been marked for add"
-msgstr ""
+msgid "not removing %s: file still exists (use -f to force removal)\n"
+msgstr ""
+
+#, python-format
+msgid "not removing %s: file is modified (use -f to force removal)\n"
+msgstr ""
+
+#, python-format
+msgid ""
+"not removing %s: file has been marked for add (use -f to force removal)\n"
+msgstr ""
+
+msgid "record a rename that has already occurred"
+msgstr "înregistrează o redenumire care a avut deja loc"
+
+msgid "[OPTION]... SOURCE... DEST"
+msgstr "[OPȚIUNE]... SURSĂ... DEST"
 
 msgid "rename files; equivalent of copy + remove"
 msgstr ""
@@ -7790,26 +9189,44 @@
 "    before that, see :hg:`revert`."
 msgstr ""
 
+msgid "select all unresolved files"
+msgstr "selectează toate fișierele nerezolvate"
+
+msgid "list state of files needing merge"
+msgstr "afișează starea fișierelor care au nevoie de fuziune"
+
+msgid "mark files as resolved"
+msgstr "marchează fișierul drept rezolvat"
+
+msgid "mark files as unresolved"
+msgstr "marchează fișierul drept rezolvat"
+
+msgid "hide status prefix"
+msgstr "ascunde prefixul stării"
+
 msgid "redo merges or set/view the merge status of files"
 msgstr ""
 
 msgid ""
 "    Merges with unresolved conflicts are often the result of\n"
-"    non-interactive merging using the ``internal:merge`` hgrc setting,\n"
-"    or a command-line merge tool like ``diff3``. The resolve command\n"
-"    is used to manage the files involved in a merge, after :hg:`merge`\n"
-"    has been run, and before :hg:`commit` is run (i.e. the working\n"
-"    directory must have two parents)."
+"    non-interactive merging using the ``internal:merge`` configuration\n"
+"    setting, or a command-line merge tool like ``diff3``. The resolve\n"
+"    command is used to manage the files involved in a merge, after\n"
+"    :hg:`merge` has been run, and before :hg:`commit` is run (i.e. the\n"
+"    working directory must have two parents)."
 msgstr ""
 
 msgid "    The resolve command can be used in the following ways:"
 msgstr ""
 
 msgid ""
-"    - :hg:`resolve FILE...`: attempt to re-merge the specified files,\n"
-"      discarding any previous merge attempts. Re-merging is not\n"
+"    - :hg:`resolve [--tool TOOL] FILE...`: attempt to re-merge the "
+"specified\n"
+"      files, discarding any previous merge attempts. Re-merging is not\n"
 "      performed for files already marked as resolved. Use ``--all/-a``\n"
-"      to selects all unresolved files."
+"      to selects all unresolved files. ``--tool`` can be used to specify\n"
+"      the merge tool used for the given files. It overrides the HGMERGE\n"
+"      environment variable and your configuration files."
 msgstr ""
 
 msgid ""
@@ -7851,17 +9268,32 @@
 msgid "no files or directories specified; use --all to remerge all files"
 msgstr ""
 
+msgid "revert all changes when no arguments given"
+msgstr ""
+
+msgid "tipmost revision matching date"
+msgstr "revizia cea mai apropiată de vârf care se potrivește cu data"
+
+msgid "revert to the specified revision"
+msgstr ""
+
+msgid "do not save backup copies of files"
+msgstr "nu salva copii de siguranță ale fișierelor"
+
+msgid "[OPTION]... [-r REV] [NAME]..."
+msgstr "[OPȚIUNE]... [-r REV] [NUME]..."
+
 msgid "restore individual files or directories to an earlier state"
 msgstr ""
 
 msgid ""
-"    NOTE: This command is most likely not what you are looking for. revert\n"
-"    will partially overwrite content in the working directory without "
-"changing\n"
-"    the working directory parents. Use :hg:`update -r rev` to check out "
-"earlier\n"
-"    revisions, or :hg:`update --clean .` to undo a merge which has added\n"
-"    another parent."
+"    .. note::\n"
+"       This command is most likely not what you are looking for.\n"
+"       Revert will partially overwrite content in the working\n"
+"       directory without changing the working directory parents. Use\n"
+"       :hg:`update -r rev` to check out earlier revisions, or\n"
+"       :hg:`update --clean .` to undo a merge which has added another\n"
+"       parent."
 msgstr ""
 
 msgid ""
@@ -7889,8 +9321,9 @@
 msgstr ""
 
 msgid ""
-"    If a file has been deleted, it is restored. If the executable mode\n"
-"    of a file was changed, it is reset."
+"    If a file has been deleted, it is restored. Files scheduled for\n"
+"    addition are just unscheduled and left as they are. If the\n"
+"    executable mode of a file was changed, it is reset."
 msgstr ""
 
 msgid ""
@@ -7906,6 +9339,9 @@
 msgid "you can't specify a revision and a date"
 msgstr ""
 
+msgid "uncommitted merge - use \"hg update\", see \"hg help revert\""
+msgstr ""
+
 msgid "no files or directories specified; use --all to revert the whole repo"
 msgstr ""
 
@@ -7979,12 +9415,58 @@
 msgid "    Print the root directory of the current repository."
 msgstr ""
 
+msgid "name of access log file to write to"
+msgstr "numele fișierului jurnal de acces în care să se scrie"
+
+msgid "name of error log file to write to"
+msgstr "numele fișierului jurnal de eroare în care să se scrie"
+
+msgid "PORT"
+msgstr "PORT"
+
+msgid "port to listen on (default: 8000)"
+msgstr "portul pe care se va asculta (implicit: 8000)"
+
+msgid "address to listen on (default: all interfaces)"
+msgstr ""
+
+msgid "ADDR"
+msgstr "ADRESĂ"
+
+msgid "prefix path to serve from (default: server root)"
+msgstr ""
+
+msgid "name to show in web pages (default: working directory)"
+msgstr ""
+"numele care va fi afișat în paginile web (implicit: directorul de lucru)"
+
+msgid "name of the hgweb config file (see \"hg help hgweb\")"
+msgstr ""
+
+msgid "name of the hgweb config file (DEPRECATED)"
+msgstr ""
+
+msgid "for remote clients"
+msgstr ""
+
+msgid "web templates to use"
+msgstr ""
+
+msgid "template style to use"
+msgstr ""
+
+msgid "use IPv6 in addition to IPv4"
+msgstr ""
+
+msgid "SSL certificate file"
+msgstr ""
+
 msgid "start stand-alone webserver"
-msgstr ""
+msgstr "pornește serverul web autonom"
 
 msgid ""
 "    Start a local HTTP repository browser and pull server. You can use\n"
-"    this for ad-hoc sharing and browing of repositories. It is\n"
+"    this for ad-hoc sharing and browsing of repositories. It is\n"
 "    recommended to use a real web server to serve a repository for\n"
 "    longer periods of time."
 msgstr ""
@@ -8009,10 +9491,80 @@
 "    number it uses."
 msgstr ""
 
+msgid "There is no Mercurial repository here (.hg not found)"
+msgstr ""
+
 #, python-format
 msgid "listening at http://%s%s/%s (bound to %s:%d)\n"
 msgstr ""
 
+msgid "show untrusted configuration options"
+msgstr "afișează opțiunile de configurare 'untrusted'"
+
+msgid "[-u] [NAME]..."
+msgstr ""
+
+msgid "show combined config settings from all hgrc files"
+msgstr "afișează setările de configurare combinate din toate fișierele hgrc"
+
+msgid "    With no arguments, print names and values of all config items."
+msgstr ""
+
+msgid ""
+"    With one argument of the form section.name, print just the value\n"
+"    of that config item."
+msgstr ""
+
+msgid ""
+"    With multiple arguments, print names and values of all config\n"
+"    items with matching section names."
+msgstr ""
+
+msgid ""
+"    With --debug, the source (filename and line number) is printed\n"
+"    for each config item."
+msgstr ""
+
+#, python-format
+msgid "read config from: %s\n"
+msgstr ""
+
+msgid "only one config item permitted"
+msgstr ""
+
+msgid "show status of all files"
+msgstr "afișează starea tuturor fișierelor"
+
+msgid "show only modified files"
+msgstr "afișează doar fișierele modificate"
+
+msgid "show only added files"
+msgstr "afișează doar fișierele adăugate"
+
+msgid "show only removed files"
+msgstr "afișează doar fișierele înlăturate"
+
+msgid "show only deleted (but tracked) files"
+msgstr "afișează doar fișierele șterse (dar urmărite)"
+
+msgid "show only files without changes"
+msgstr "afișează doar fișierele fără modificări"
+
+msgid "show only unknown (not tracked) files"
+msgstr "afișează doar fișierele necunoscute (neurmărite)"
+
+msgid "show only ignored files"
+msgstr "afișează doar fișierele ignorate"
+
+msgid "show source of copied files"
+msgstr "afișează sursa fișierelor copiate"
+
+msgid "show difference from revision"
+msgstr "afișează diferențele față de revizie"
+
+msgid "list the changed files of a revision"
+msgstr "afișează fișierele modificate ale unei revizii"
+
 msgid "show changed files in the working directory"
 msgstr "afișează fișierele modificate în directorul de lucru"
 
@@ -8024,18 +9576,35 @@
 "    Unless options described with \"show only ...\" are given, the\n"
 "    options -mardu are used."
 msgstr ""
+"    Afișează starea fișierelor din depozit. Dacă sunt furnizate nume,\n"
+"    se arată doar fișierele care se potrivesc. Fișierele curate, ignorate\n"
+"    sau care nu sunt sursa unei operații de copiere/mutare nu sunt afișate,\n"
+"    cu excepția cazului când se furnizează `-c/--clean`, `-i/--ignored`,\n"
+"    `-C/--copies` sau `-A/--all`. Dacă nu se furnizează opțiunile a căror\n"
+"    descriere începe cu ``afișează doar...``, vor fi folosite opțiunile\n"
+"    -mardu."
 
 msgid ""
 "    Option -q/--quiet hides untracked (unknown and ignored) files\n"
 "    unless explicitly requested with -u/--unknown or -i/--ignored."
 msgstr ""
-
-msgid ""
-"    NOTE: status may appear to disagree with diff if permissions have\n"
-"    changed or a merge has occurred. The standard diff format does not\n"
-"    report permission changes and diff only reports changes relative\n"
-"    to one merge parent."
-msgstr ""
+"    Opțiunea `-q/--quiet` ascunde fișierele neurmărite (necunoscute\n"
+"    sau ignorate), cu excepția cazului când se solicită explicit\n"
+"    afișarea lor cu `-u/--unknown` sau `-i/--ignored`."
+
+msgid ""
+"    .. note::\n"
+"       status may appear to disagree with diff if permissions have\n"
+"       changed or a merge has occurred. The standard diff format does\n"
+"       not report permission changes and diff only reports changes\n"
+"       relative to one merge parent."
+msgstr ""
+"    Notă:\n"
+"       `status` poate apărea în dezacord cu `diff` dacă s-au\n"
+"       modificat permisiuni sau a avut loc o fuziune. Formatul\n"
+"       diff standard nu raportează modificările permisiunilor,\n"
+"       iar `diff` raportează modificările doar relativ la un\n"
+"       părinte din fuziune."
 
 msgid ""
 "    If one revision is given, it is used as the base revision.\n"
@@ -8043,6 +9612,12 @@
 "    shown. The --change option can also be used as a shortcut to list\n"
 "    the changed files of a revision from its first parent."
 msgstr ""
+"    Dacă se furnizează o revizie, va fi folosită ca revizie\n"
+"    de bază. Dacă se furnizează două revizii, se arată\n"
+"    diferențele dintre ele. Opțiunea `--change` poate fi\n"
+"    de asemenea folosită drept scurtătură pentru a afișa\n"
+"    fișierele modificate de către o revizie în raport cu\n"
+"    primul ei părinte."
 
 msgid "    The codes used to show the status of files are::"
 msgstr "    Codurile folosite pentru a arăta starea fișierelor sunt::"
@@ -8066,18 +9641,25 @@
 "      I = ignorat\n"
 "        = originea fișierului precedent listat ca A (adăugat)"
 
+msgid "check for push and pull"
+msgstr "Verifică pentru `push` și `pull`"
+
 msgid "summarize working directory state"
-msgstr ""
+msgstr "sumarizează starea directorului de lucru"
 
 msgid ""
 "    This generates a brief summary of the working directory state,\n"
 "    including parents, branch, commit status, and available updates."
 msgstr ""
+"    Generează un sumar al stării directorului curent, incluzând\n"
+"    părinții, ramura, starea depozitării și actualizările disponibile."
 
 msgid ""
 "    With the --remote option, this will check the default paths for\n"
 "    incoming and outgoing changes. This can be time-consuming."
 msgstr ""
+"    Cu opțiunea --remote, vor fi verificate căile implicite pentru\n"
+"    modificări de primit și de trimis. Acțiunea poate consuma timp."
 
 #, python-format
 msgid "parent: %d:%s "
@@ -8086,7 +9668,6 @@
 msgid " (empty repository)"
 msgstr " (depozit vid)"
 
-#, fuzzy
 msgid " (no revision checked out)"
 msgstr " (nu există nicio revizie extrasă)"
 
@@ -8173,12 +9754,38 @@
 msgstr "%d de trimis"
 
 #, python-format
+msgid "%d incoming bookmarks"
+msgstr "%d semne de carte de primit"
+
+#, python-format
+msgid "%d outgoing bookmarks"
+msgstr "%d semne de carte de trimis"
+
+#, python-format
 msgid "remote: %s\n"
 msgstr "la distanță: %s\n"
 
 msgid "remote: (synced)\n"
 msgstr "la distanță: (sincronizat)\n"
 
+msgid "force tag"
+msgstr "forțează eticheta"
+
+msgid "make the tag local"
+msgstr "fă eticheta locală"
+
+msgid "revision to tag"
+msgstr ""
+
+msgid "remove a tag"
+msgstr "înlătură o etichetă"
+
+msgid "use <text> as commit message"
+msgstr "folosește <text> drept mesaj de depozitare"
+
+msgid "[-f] [-l] [-m TEXT] [-d DATE] [-u USER] [-r REV] NAME..."
+msgstr "[-f] [-l] [-m TEXT] [-d DATĂ] [-u UTILIZATOR] [-r REV] NUME..."
+
 msgid "add one or more tags for the current or given revision"
 msgstr ""
 "adaugă una sau mai multe etichete pentru revizia curentă\n"
@@ -8190,7 +9797,8 @@
 msgid ""
 "    Tags are used to name particular revisions of the repository and are\n"
 "    very useful to compare different revisions, to go back to significant\n"
-"    earlier versions or to mark branch points as releases, etc."
+"    earlier versions or to mark branch points as releases, etc. Changing\n"
+"    an existing tag is normally disallowed; use -f/--force to override."
 msgstr ""
 
 msgid ""
@@ -8200,10 +9808,18 @@
 
 msgid ""
 "    To facilitate version control, distribution, and merging of tags,\n"
-"    they are stored as a file named \".hgtags\" which is managed\n"
-"    similarly to other project files and can be hand-edited if\n"
-"    necessary. The file '.hg/localtags' is used for local tags (not\n"
-"    shared among repositories)."
+"    they are stored as a file named \".hgtags\" which is managed similarly\n"
+"    to other project files and can be hand-edited if necessary. This\n"
+"    also means that tagging creates a new commit. The file\n"
+"    \".hg/localtags\" is used for local tags (not shared among\n"
+"    repositories)."
+msgstr ""
+
+msgid ""
+"    Tag commits are usually made at the head of a branch. If the parent\n"
+"    of the working directory is not a branch head, :hg:`tag` aborts; use\n"
+"    -f/--force to force the tag commit to be based on a non-head\n"
+"    changeset."
 msgstr ""
 
 msgid ""
@@ -8236,6 +9852,12 @@
 msgid "tag '%s' already exists (use -f to force)"
 msgstr ""
 
+msgid "uncommitted merge"
+msgstr "fuziune nedepozitată"
+
+msgid "not at a branch head (use -f to force)"
+msgstr ""
+
 msgid "list repository tags"
 msgstr ""
 
@@ -8244,6 +9866,9 @@
 "    switch is used, a third column \"local\" is printed for local tags."
 msgstr ""
 
+msgid "[-p] [-g]"
+msgstr "[-p] [-g]"
+
 msgid "show the tip revision"
 msgstr "afișează revizia vârf"
 
@@ -8260,6 +9885,14 @@
 "    and cannot be renamed or assigned to a different changeset."
 msgstr ""
 
+msgid "update to new branch head if changesets were unbundled"
+msgstr ""
+"actualizează la noul capăt de ramură, dacă au fost despachetate\n"
+"(unbundled) seturi de modificări"
+
+msgid "[-u] FILE..."
+msgstr "[-u] FIȘIER..."
+
 msgid "apply one or more changegroup files"
 msgstr ""
 
@@ -8276,33 +9909,47 @@
 "    fișiere nerezolvate.\n"
 "    "
 
+msgid "discard uncommitted changes (no backup)"
+msgstr "înlătură modificările nedepozitate (fără copie de siguranță)"
+
+msgid "update across branches if no uncommitted changes"
+msgstr "actualizează peste ramuri dacă nu există modificări nedepozitate"
+
+msgid "[-c] [-C] [-d DATE] [[-r] REV]"
+msgstr "[-c] [-C] [-d DATĂ] [[-r] REV]"
+
 msgid "update working directory (or switch revisions)"
 msgstr "actualizează directorul de lucru (sau comută între revizii)"
 
 msgid ""
 "    Update the repository's working directory to the specified\n"
-"    changeset."
+"    changeset. If no changeset is specified, update to the tip of the\n"
+"    current named branch."
 msgstr ""
 "    Actualizează directorul de lucru al depozitului la setul de\n"
+"    modificări specificat. Dacă nu se specifică niciun set de\n"
+"    modificări, actualizarea are loc la vârful ramurii cu nume\n"
+"    curente."
+
+msgid ""
+"    If the changeset is not a descendant of the working directory's\n"
+"    parent, the update is aborted. With the -c/--check option, the\n"
+"    working directory is checked for uncommitted changes; if none are\n"
+"    found, the working directory is updated to the specified\n"
+"    changeset."
+msgstr ""
+"    Dacă setul de modificări nu e un descendent al părintelui directorului\n"
+"    de lucru, actualizarea este abandonată. Cu opțiunea `-c/--check`,\n"
+"    se verifică în directorul de lucru modificări nedepozitate; dacă nu se\n"
+"    găsește niciuna, directorul de lucru este actualizat la setul de\n"
 "    modificări specificat."
 
 msgid ""
-"    If no changeset is specified, attempt to update to the tip of the\n"
-"    current branch. If this changeset is a descendant of the working\n"
-"    directory's parent, update to it, otherwise abort."
-msgstr ""
-"    Dacă nu se specifică nici un set de modificări, se încearcă "
-"actualizarea\n"
-"    la vârful ramurii curente. Dacă acest set de modificări este descendent\n"
-"    al părintelui directorului de lucru, se actualizează la el, altfel se "
-"renunță."
-
-msgid ""
 "    The following rules apply when the working directory contains\n"
 "    uncommitted changes:"
 msgstr ""
-"   Când directorul de lucru conține modificări nedepozitate, se\n"
-"   aplică următoarele reguli:"
+"    Când directorul de lucru conține modificări nedepozitate, se\n"
+"    aplică următoarele reguli:"
 
 msgid ""
 "    1. If neither -c/--check nor -C/--clean is specified, and if\n"
@@ -8345,8 +9992,8 @@
 "    lucru (similar cu :hg:`clone -U`)."
 
 msgid ""
-"    If you want to update just one file to an older changeset, use :hg:"
-"`revert`."
+"    If you want to update just one file to an older changeset, use\n"
+"    :hg:`revert`."
 msgstr ""
 "    Dacă doriți să actualizați doar un singur fișier la un set de\n"
 "    modificări mai vechi, folosiți :hg:`revert`."
@@ -8379,795 +10026,19 @@
 "Mercurial - gestionar distribuit pentru controlul codului sursă\n"
 "(versiunea %s)\n"
 
-msgid ""
-"\n"
-"Copyright (C) 2005-2010 Matt Mackall <mpm@selenic.com> and others\n"
+msgid "(see http://mercurial.selenic.com for more information)"
+msgstr "(vezi http://mercurial.selenic.com pentru mai multe informații)"
+
+msgid ""
+"Copyright (C) 2005-2011 Matt Mackall and others\n"
 "This is free software; see the source for copying conditions. There is NO\n"
 "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
 msgstr ""
-"\n"
-"Copyright (C) 2005-2010 Matt Mackall <mpm@selenic.com> și alții\n"
+"Copyright (C) 2005-2011 Matt Mackall și alții\n"
 "Acesta este software liber; vezi sursa pentru condițiile de copiere.\n"
 "Nu există NICIO garanție; nici măcar pentru COMERCIALIZARE sau\n"
 "COMPATIBILITATE ÎN ANUMITE SCOPURI.\n"
 
-msgid "repository root directory or name of overlay bundle file"
-msgstr ""
-
-msgid "DIR"
-msgstr "DIR"
-
-msgid "change working directory"
-msgstr "schimbă directorul de lucru "
-
-msgid "do not prompt, assume 'yes' for any required answers"
-msgstr "nu întreba, presupune 'da' pentru orice răspuns solicitat"
-
-msgid "suppress output"
-msgstr "suprimă afișarea"
-
-msgid "enable additional output"
-msgstr "activează afișarea informațiilor suplimentare"
-
-msgid "set/override config option (use 'section.name=value')"
-msgstr ""
-"setează/suprascrie opțiunea de configurare (folosiți 'secțiune.nume=valoare')"
-
-msgid "CONFIG"
-msgstr ""
-
-msgid "enable debugging output"
-msgstr "activează afișarea informațiilor pentru depanare"
-
-msgid "start debugger"
-msgstr "pornește depanatorul (debugger)"
-
-msgid "set the charset encoding"
-msgstr "setează codificarea pentru setul de caractere"
-
-msgid "ENCODE"
-msgstr ""
-
-msgid "MODE"
-msgstr ""
-
-msgid "set the charset encoding mode"
-msgstr "setează modul de codificare pentru setul de caractere"
-
-msgid "always print a traceback on exception"
-msgstr ""
-
-msgid "time how long the command takes"
-msgstr "durata de execuție a comenzii"
-
-msgid "print command execution profile"
-msgstr "afișează profilul executării comenzii"
-
-msgid "output version information and exit"
-msgstr "afișează informații despre versiune și ieși"
-
-msgid "display help and exit"
-msgstr "afișează ajutorul și ieși"
-
-msgid "do not perform actions, just print output"
-msgstr "acțiunea nu se execută, doar se afișează mesajele"
-
-msgid "specify ssh command to use"
-msgstr "specifică comanda ssh care va fi folosită"
-
-msgid "specify hg command to run on the remote side"
-msgstr "specifică comanda hg care va fi executată pe mașina la distanță"
-
-msgid "PATTERN"
-msgstr "TIPAR"
-
-msgid "include names matching the given patterns"
-msgstr "include numele care se potrivesc cu tiparele specificate"
-
-msgid "exclude names matching the given patterns"
-msgstr "exclude numele care se potrivesc cu tiparele specificate"
-
-msgid "use text as commit message"
-msgstr "folosește textul drept mesaj de depozitare"
-
-msgid "read commit message from file"
-msgstr "citește mesajul pentru depozitare din fișier"
-
-msgid "record datecode as commit date"
-msgstr "înregistrează codul de dată ca dată a depozitării"
-
-msgid "record the specified user as committer"
-msgstr ""
-"înregistrează utilizatorul specificat ca fiind cel care a făcut depozitarea"
-
-msgid "STYLE"
-msgstr "STIL"
-
-msgid "display using template map file"
-msgstr "afișează folosind fișierul cu harta de șabloane"
-
-msgid "display with template"
-msgstr "afișează cu șablon"
-
-msgid "do not show merges"
-msgstr "nu afișa fuziunile"
-
-msgid "output diffstat-style summary of changes"
-msgstr ""
-
-msgid "treat all files as text"
-msgstr "tratează toate fișierele ca text"
-
-msgid "omit dates from diff headers"
-msgstr "omite datele din antetele diff"
-
-msgid "show which function each change is in"
-msgstr "afișează funcția în care se află fiecare modificare"
-
-msgid "produce a diff that undoes the changes"
-msgstr ""
-
-msgid "ignore white space when comparing lines"
-msgstr "ignoră spațiul alb la compararea liniilor"
-
-msgid "ignore changes in the amount of white space"
-msgstr "ignoră modificările cantității de spațiu alb"
-
-msgid "ignore changes whose lines are all blank"
-msgstr "ignoră modificările ale căror linii sunt toate vide"
-
-msgid "number of lines of context to show"
-msgstr "numărul liniilor de context care vor fi afișate"
-
-msgid "SIMILARITY"
-msgstr "ASEMĂNARE"
-
-msgid "guess renamed files by similarity (0<=s<=100)"
-msgstr "ghicește fișierele redenumite după asemănare (0<=s<=100)"
-
-msgid "[OPTION]... [FILE]..."
-msgstr "[OPȚIUNE]... [FIȘIER]..."
-
-msgid "annotate the specified revision"
-msgstr "adnotează revizia specificată"
-
-msgid "follow copies/renames and list the filename (DEPRECATED)"
-msgstr ""
-"urmărește copierile/redenumirile și afișează numele\n"
-"fișierului (ÎNVECHIT)"
-
-msgid "don't follow copies and renames"
-msgstr "nu urmări copierile și redenumirile"
-
-msgid "list the author (long with -v)"
-msgstr "afișează autorul (lung cu -v)"
-
-msgid "list the filename"
-msgstr "afișează numele fișierului"
-
-msgid "list the date (short with -q)"
-msgstr "afișează data (scurt cu -q)"
-
-msgid "list the revision number (default)"
-msgstr "afișează numele reviziei (implicit)"
-
-msgid "list the changeset"
-msgstr "afișează setul de modificări"
-
-msgid "show line number at the first appearance"
-msgstr "afișează numărul liniei la prima apariție"
-
-msgid "[-r REV] [-f] [-a] [-u] [-d] [-n] [-c] [-l] FILE..."
-msgstr "[-r REV] [-f] [-a] [-u] [-d] [-n] [-c] [-l] FIȘIER..."
-
-msgid "do not pass files through decoders"
-msgstr ""
-
-msgid "PREFIX"
-msgstr "PREFIX"
-
-msgid "directory prefix for files in archive"
-msgstr ""
-
-msgid "revision to distribute"
-msgstr ""
-
-msgid "type of distribution to create"
-msgstr ""
-
-msgid "[OPTION]... DEST"
-msgstr "[OPȚIUNE]... DEST"
-
-msgid "merge with old dirstate parent after backout"
-msgstr ""
-
-msgid "parent to choose when backing out merge"
-msgstr ""
-
-msgid "revision to backout"
-msgstr ""
-
-msgid "[OPTION]... [-r] REV"
-msgstr "[OPȚIUNE]... [-r] REV"
-
-msgid "reset bisect state"
-msgstr ""
-
-msgid "mark changeset good"
-msgstr "marchează setul de modificări drept bun"
-
-msgid "mark changeset bad"
-msgstr "marchează setul de modificări drept rău"
-
-msgid "skip testing changeset"
-msgstr "omite testarea setului de modificări"
-
-msgid "use command to check changeset state"
-msgstr ""
-
-msgid "do not update to target"
-msgstr "nu actualiza la destinație"
-
-msgid "[-gbsr] [-U] [-c CMD] [REV]"
-msgstr "[-gbsr] [-U] [-c CMD] [REV]"
-
-msgid "set branch name even if it shadows an existing branch"
-msgstr ""
-
-msgid "reset branch name to parent branch name"
-msgstr ""
-
-msgid "[-fC] [NAME]"
-msgstr "[-fC] [NAME]"
-
-msgid "show only branches that have unmerged heads"
-msgstr "afișează doar ramurile care au capete nefuzionate"
-
-msgid "show normal and closed branches"
-msgstr "afișează ramurile normale și închise"
-
-msgid "[-ac]"
-msgstr ""
-
-msgid "run even when the destination is unrelated"
-msgstr ""
-
-msgid "a changeset intended to be added to the destination"
-msgstr ""
-
-msgid "a specific branch you would like to bundle"
-msgstr ""
-
-msgid "a base changeset assumed to be available at the destination"
-msgstr ""
-
-msgid "bundle all changesets in the repository"
-msgstr ""
-
-msgid "bundle compression type to use"
-msgstr ""
-
-msgid "[-f] [-t TYPE] [-a] [-r REV]... [--base REV]... FILE [DEST]"
-msgstr ""
-
-msgid "print output to file with formatted name"
-msgstr ""
-
-msgid "print the given revision"
-msgstr ""
-
-msgid "apply any matching decode filter"
-msgstr ""
-
-msgid "[OPTION]... FILE..."
-msgstr "[OPȚIUNE]... FIȘIER"
-
-msgid "the clone will include an empty working copy (only a repository)"
-msgstr "clona va include o copie de lucru vidă (doar un depozit)"
-
-msgid "revision, tag or branch to check out"
-msgstr "revizia, eticheta sau ramura care va fi actualizată"
-
-msgid "include the specified changeset"
-msgstr "include setul de modificări specificat"
-
-msgid "clone only the specified branch"
-msgstr "clonează doar ramura specificată"
-
-msgid "[OPTION]... SOURCE [DEST]"
-msgstr "[OPȚIUNE]... SURSĂ [DEST]"
-
-msgid "mark new/missing files as added/removed before committing"
-msgstr ""
-"marchează fișierele noi/lipsă ca adăugate/eliminate înainte de depozitare"
-
-msgid "mark a branch as closed, hiding it from the branch list"
-msgstr "marchează o ramură ca închisă, ascunzând-o din lista ramurilor"
-
-msgid "record a copy that has already occurred"
-msgstr ""
-
-msgid "forcibly copy over an existing managed file"
-msgstr ""
-
-msgid "[OPTION]... [SOURCE]... DEST"
-msgstr "[OPȚIUNE]... [SURSĂ]... DEST"
-
-msgid "[INDEX] REV1 REV2"
-msgstr ""
-
-msgid "add single file mergeable changes"
-msgstr ""
-
-msgid "add single file all revs append to"
-msgstr ""
-
-msgid "add single file all revs overwrite"
-msgstr ""
-
-msgid "add new file at each rev"
-msgstr ""
-
-msgid "[OPTION]... TEXT"
-msgstr "[OPȚIUNE]... TEXT"
-
-msgid "[COMMAND]"
-msgstr ""
-
-msgid "show the command options"
-msgstr "afișează opțiunile comenzii"
-
-msgid "[-o] CMD"
-msgstr ""
-
-msgid "use tags as labels"
-msgstr ""
-
-msgid "annotate with branch names"
-msgstr ""
-
-msgid "use dots for runs"
-msgstr ""
-
-msgid "separate elements by spaces"
-msgstr ""
-
-msgid "[OPTION]... [FILE [REV]...]"
-msgstr "[OPȚIUNE]... [FIȘIER [REV]...]"
-
-msgid "try extended date formats"
-msgstr ""
-
-msgid "[-e] DATE [RANGE]"
-msgstr ""
-
-msgid "FILE REV"
-msgstr ""
-
-msgid "[PATH]"
-msgstr ""
-
-msgid "REPO NAMESPACE [KEY OLD NEW]"
-msgstr ""
-
-msgid "revision to rebuild to"
-msgstr ""
-
-msgid "[-r REV] [REV]"
-msgstr ""
-
-msgid "revision to debug"
-msgstr ""
-
-msgid "[-r REV] FILE"
-msgstr ""
-
-msgid "REV1 [REV2]"
-msgstr ""
-
-msgid "do not display the saved mtime"
-msgstr ""
-
-msgid "[OPTION]..."
-msgstr "[OPȚIUNE]..."
-
-msgid "revision to check"
-msgstr ""
-
-msgid "[OPTION]... ([-c REV] | [-r REV1 [-r REV2]]) [FILE]..."
-msgstr "[OPȚIUNE]... ([-c REV] | [-r REV1 [-r REV2]]) [FIȘIER]..."
-
-msgid "diff against the second parent"
-msgstr ""
-
-msgid "revisions to export"
-msgstr ""
-
-msgid "[OPTION]... [-o OUTFILESPEC] REV..."
-msgstr "[OPȚIUNE]... [-o SPECFIȘIEȘIRE] REV..."
-
-msgid "end fields with NUL"
-msgstr ""
-
-msgid "print all revisions that match"
-msgstr ""
-
-msgid "follow changeset history, or file history across copies and renames"
-msgstr ""
-"urmărește istoricul seturilor de modificări sau al fișierelor, ținând cont "
-"de copieri și redenumiri"
-
-msgid "ignore case when matching"
-msgstr "ignoră minuscule/majuscule la potrivire"
-
-msgid "print only filenames and revisions that match"
-msgstr "afișează doar numele de fișiere și reviziile care se potrivesc"
-
-msgid "print matching line numbers"
-msgstr "afișează numerele liniilor care se potrivesc"
-
-msgid "only search files changed within revision range"
-msgstr "caută doar fișierele modificate în intervalul de revizii"
-
-msgid "[OPTION]... PATTERN [FILE]..."
-msgstr "[OPȚIUNE]... TIPAR [FIȘIER]..."
-
-msgid "show only heads which are descendants of REV"
-msgstr "afișează doar capetele care sunt descendenți ai REV"
-
-msgid "show topological heads only"
-msgstr "afișează doar capetele topologice"
-
-msgid "show active branchheads only (DEPRECATED)"
-msgstr "afișează doar capetele de ramură active [ÎNVECHIT]"
-
-msgid "show normal and closed branch heads"
-msgstr " afișează capetele de ramură normale și închise"
-
-msgid "[-ac] [-r REV] [REV]..."
-msgstr "[-ac] [-r REV] [REV]..."
-
-msgid "[TOPIC]"
-msgstr "[SUBIECT]"
-
-msgid "identify the specified revision"
-msgstr "identifică revizia specificată"
-
-msgid "show local revision number"
-msgstr "afișează numărul de revizie local"
-
-msgid "show global revision id"
-msgstr "afișează id-ul global al reviziei"
-
-msgid "show branch"
-msgstr "afișează ramura"
-
-msgid "show tags"
-msgstr "afișează etichetele"
-
-msgid "[-nibt] [-r REV] [SOURCE]"
-msgstr "[-nibt] [-r REV] [SURSĂ]"
-
-msgid ""
-"directory strip option for patch. This has the same meaning as the "
-"corresponding patch option"
-msgstr ""
-
-msgid "PATH"
-msgstr "CALE"
-
-msgid "base path"
-msgstr "calea de bază"
-
-msgid "skip check for outstanding uncommitted changes"
-msgstr "omite verificarea pentru modificări nedepozitate în suspensie"
-
-msgid "don't commit, just update the working directory"
-msgstr "nu depozita, doar actualizează directorul de lucru"
-
-msgid "apply patch to the nodes from which it was generated"
-msgstr "aplică patch-ul nodurilor pentru care a fost generat"
-
-msgid "use any branch information in patch (implied by --exact)"
-msgstr ""
-"folosește orice informație despre ramură din patch\n"
-"(implicat de --exact)"
-
-msgid "[OPTION]... PATCH..."
-msgstr "[OPȚIUNE]... PATCH"
-
-msgid "run even if remote repository is unrelated"
-msgstr "execută chiar dacă depozitul la distanță este neînrudit"
-
-msgid "show newest record first"
-msgstr "afișează începând cu cea mai nouă înregistrare"
-
-msgid "file to store the bundles into"
-msgstr ""
-
-msgid "a remote changeset intended to be added"
-msgstr ""
-
-msgid "a specific branch you would like to pull"
-msgstr ""
-
-msgid "[-p] [-n] [-M] [-f] [-r REV]... [--bundle FILENAME] [SOURCE]"
-msgstr "[-p] [-n] [-M] [-f] [-r REV]... [--bundle NUMEFIȘIER] [SURSĂ]"
-
-msgid "[-e CMD] [--remotecmd CMD] [DEST]"
-msgstr "[-e CMD] [--remotecmd CMD] [DEST]"
-
-msgid "search the repository as it is in REV"
-msgstr "caută depozitul așa cum este el în REV"
-
-msgid "end filenames with NUL, for use with xargs"
-msgstr "termină numele de fișiere cu NUL, pentru utilizare cu xargs"
-
-msgid "print complete paths from the filesystem root"
-msgstr "afișează căi complete de la rădăcina sistemului de fișiere"
-
-msgid "[OPTION]... [PATTERN]..."
-msgstr "[OPȚIUNE]... [TIPAR]..."
-
-msgid "only follow the first parent of merge changesets"
-msgstr "urmărește doar primul părinte al seturilor de modificări de fuziune"
-
-msgid "show revisions matching date spec"
-msgstr "afișează reviziile care se potrivesc cu data"
-
-msgid "show copied files"
-msgstr "afișează fișierele copiate"
-
-msgid "do case-insensitive search for a given text"
-msgstr "caută textul specificat fără a diferenția între minuscule și majuscule"
-
-msgid "include revisions where files were removed"
-msgstr "include reviziile în care au fost eliminate fișiere"
-
-msgid "show only merges"
-msgstr "afișează doar fuziunile"
-
-msgid "revisions committed by user"
-msgstr "reviziile depozitate de utilizatorul"
-
-msgid "show only changesets within the given named branch (DEPRECATED)"
-msgstr ""
-"afișează doar seturile de modificări din interiorul ramurii denumite\n"
-"specificate (ÎNVECHIT)"
-
-msgid "show changesets within the given named branch"
-msgstr ""
-"afișează seturile de modificări din cadrul ramurii denumite specificate"
-
-msgid "do not display revision or any of its ancestors"
-msgstr "nu afișa revizia sau oricare din strămoșii ei"
-
-msgid "[OPTION]... [FILE]"
-msgstr "[OPȚIUNE]... [FIȘIER]"
-
-msgid "revision to display"
-msgstr "revizia de afișat"
-
-msgid "[-r REV]"
-msgstr "[-r REV]"
-
-msgid "force a merge with outstanding changes"
-msgstr "forțează o fuziune cu modificări în suspensie"
-
-msgid "revision to merge"
-msgstr "revizia de fuzionat"
-
-msgid "review revisions to merge (no merge is performed)"
-msgstr ""
-"treci în revistă reviziile de fuzionat (nu se execută\n"
-"nicio fuziune)"
-
-msgid "[-P] [-f] [[-r] REV]"
-msgstr "[-P] [-f] [[-r] REV]"
-
-msgid "a changeset intended to be included in the destination"
-msgstr "un set de modificări care se dorește a fi inclus în destinație"
-
-msgid "a specific branch you would like to push"
-msgstr ""
-
-msgid "[-M] [-p] [-n] [-f] [-r REV]... [DEST]"
-msgstr "[-M] [-p] [-n] [-f] [-r REV]... [DEST]"
-
-msgid "show parents of the specified revision"
-msgstr "afișează părinții reviziei specificate"
-
-msgid "[-r REV] [FILE]"
-msgstr "[-r REV] [FIȘIER]"
-
-msgid "[NAME]"
-msgstr "[NUME]"
-
-msgid "update to new branch head if changesets were pulled"
-msgstr ""
-
-msgid "run even when remote repository is unrelated"
-msgstr "execută chiar când depozitul la distanță este neînrudit"
-
-msgid "[-u] [-f] [-r REV]... [-e CMD] [--remotecmd CMD] [SOURCE]"
-msgstr "[-u] [-f] [-r REV]... [-e CMD] [--remotecmd CMD] [SURSĂ]"
-
-msgid "force push"
-msgstr ""
-
-msgid "allow pushing a new branch"
-msgstr ""
-
-msgid "[-f] [-r REV]... [-e CMD] [--remotecmd CMD] [DEST]"
-msgstr "[-f] [-r REV]... [-e CMD] [--remotecmd CMD] [DEST]"
-
-msgid "record delete for missing files"
-msgstr "înregistrează ștergere pentru fișierele lipsă"
-
-msgid "remove (and delete) file even if added or modified"
-msgstr "înlătură (și șterge) fișierul chiar dacă este adăugat sau modificat"
-
-msgid "record a rename that has already occurred"
-msgstr "înregistrează o redenumire care a avut deja loc"
-
-msgid "[OPTION]... SOURCE... DEST"
-msgstr "[OPȚIUNE]... SURSĂ... DEST"
-
-msgid "select all unresolved files"
-msgstr "selectează toate fișierele nerezolvate"
-
-msgid "list state of files needing merge"
-msgstr "afișează starea fișierelor care au nevoie de fuziune"
-
-msgid "mark files as resolved"
-msgstr "marchează fișierul drept rezolvat"
-
-msgid "mark files as unresolved"
-msgstr "marchează fișierul drept rezolvat"
-
-msgid "hide status prefix"
-msgstr "ascunde prefixul stării"
-
-msgid "revert all changes when no arguments given"
-msgstr ""
-
-msgid "tipmost revision matching date"
-msgstr "revizia cea mai apropiată de vârf care se potrivește cu data"
-
-msgid "revert to the specified revision"
-msgstr ""
-
-msgid "do not save backup copies of files"
-msgstr "nu salva copii de siguranță ale fișierelor"
-
-msgid "[OPTION]... [-r REV] [NAME]..."
-msgstr "[OPȚIUNE]... [-r REV] [NUME]..."
-
-msgid "name of access log file to write to"
-msgstr "numele fișierului jurnal de acces în care să se scrie"
-
-msgid "name of error log file to write to"
-msgstr "numele fișierului jurnal de eroare în care să se scrie"
-
-msgid "PORT"
-msgstr "PORT"
-
-msgid "port to listen on (default: 8000)"
-msgstr "portul pe care se va asculta (implicit: 8000)"
-
-msgid "ADDR"
-msgstr "ADRESĂ"
-
-msgid "address to listen on (default: all interfaces)"
-msgstr ""
-
-msgid "prefix path to serve from (default: server root)"
-msgstr ""
-
-msgid "name to show in web pages (default: working directory)"
-msgstr ""
-"numele care va fi afișat în paginile web (implicit: directorul de lucru)"
-
-msgid "name of the hgweb config file (serve more than one repository)"
-msgstr ""
-
-msgid "name of the hgweb config file (DEPRECATED)"
-msgstr ""
-
-msgid "for remote clients"
-msgstr ""
-
-msgid "web templates to use"
-msgstr ""
-
-msgid "template style to use"
-msgstr ""
-
-msgid "use IPv6 in addition to IPv4"
-msgstr ""
-
-msgid "SSL certificate file"
-msgstr ""
-
-#, fuzzy
-msgid "show untrusted configuration options"
-msgstr "afișează opțiunile de configurare 'untrusted'"
-
-msgid "[-u] [NAME]..."
-msgstr ""
-
-msgid "check for push and pull"
-msgstr ""
-
-msgid "show status of all files"
-msgstr "afișează starea tuturor fișierelor"
-
-msgid "show only modified files"
-msgstr "afișează doar fișierele modificate"
-
-msgid "show only added files"
-msgstr "afișează doar fișierele adăugate"
-
-msgid "show only removed files"
-msgstr "afișează doar fișierele înlăturate"
-
-msgid "show only deleted (but tracked) files"
-msgstr "afișează doar fișierele șterse (dar urmărite)"
-
-msgid "show only files without changes"
-msgstr "afișează doar fișierele fără modificări"
-
-msgid "show only unknown (not tracked) files"
-msgstr "afișează doar fișierele necunoscute (neurmărite)"
-
-msgid "show only ignored files"
-msgstr "afișează doar fișierele ignorate"
-
-msgid "show source of copied files"
-msgstr "afișează sursa fișierelor copiate"
-
-msgid "show difference from revision"
-msgstr "afișează diferențele față de revizie"
-
-msgid "list the changed files of a revision"
-msgstr "afișează fișierele modificate ale unei revizii"
-
-msgid "replace existing tag"
-msgstr "înlocuiește o etichetă existentă"
-
-msgid "make the tag local"
-msgstr "fă eticheta locală"
-
-msgid "revision to tag"
-msgstr ""
-
-msgid "remove a tag"
-msgstr "înlătură o etichetă"
-
-msgid "use <text> as commit message"
-msgstr "folosește <text> drept mesaj de depozitare"
-
-msgid "[-f] [-l] [-m TEXT] [-d DATE] [-u USER] [-r REV] NAME..."
-msgstr "[-f] [-l] [-m TEXT] [-d DATĂ] [-u UTILIZATOR] [-r REV] NUME..."
-
-msgid "[-p] [-g]"
-msgstr "[-p] [-g]"
-
-msgid "update to new branch head if changesets were unbundled"
-msgstr ""
-
-msgid "[-u] FILE..."
-msgstr "[-u] FIȘIER..."
-
-msgid "discard uncommitted changes (no backup)"
-msgstr "înlătură modificările nedepozitate (fără copie de siguranță)"
-
-msgid "check for uncommitted changes"
-msgstr "verifică dacă există modificări nedepozitate"
-
-msgid "[-c] [-C] [-d DATE] [[-r] REV]"
-msgstr "[-c] [-C] [-d DATĂ] [[-r] REV]"
-
 #, python-format
 msgid "cannot include %s (%s)"
 msgstr ""
@@ -9175,6 +10046,10 @@
 msgid "not found in manifest"
 msgstr "nu s-a găsit în manifest"
 
+#, python-format
+msgid "no such file in rev %s"
+msgstr ""
+
 msgid "branch name not in UTF-8!"
 msgstr ""
 
@@ -9197,14 +10072,6 @@
 msgstr ""
 
 #, python-format
-msgid "%s not added!\n"
-msgstr ""
-
-#, python-format
-msgid "%s still exists!\n"
-msgstr ""
-
-#, python-format
 msgid "%s not tracked!\n"
 msgstr ""
 
@@ -9217,17 +10084,28 @@
 msgstr ""
 
 #, python-format
+msgid "invalid character in dag description: %s..."
+msgstr ""
+
+#, python-format
+msgid "expected id %i, got %i"
+msgstr ""
+
+#, python-format
+msgid "parent id %i is larger than current id %i"
+msgstr ""
+
+#, python-format
 msgid "invalid event type in dag: %s"
 msgstr ""
 
+msgid "nullid"
+msgstr ""
+
 msgid "working directory state appears damaged!"
 msgstr ""
 
 #, python-format
-msgid "'\\n' and '\\r' disallowed in filenames: %r"
-msgstr ""
-
-#, python-format
 msgid "directory %r already in dirstate"
 msgstr ""
 
@@ -9239,10 +10117,6 @@
 msgid "setting %r to other parent only allowed in merges"
 msgstr ""
 
-#, python-format
-msgid "not in dirstate: %s\n"
-msgstr ""
-
 msgid "unknown"
 msgstr ""
 
@@ -9265,21 +10139,6 @@
 msgid "unsupported file type (type is %s)"
 msgstr ""
 
-msgid "queries"
-msgstr ""
-
-msgid "searching"
-msgstr ""
-
-msgid "already have changeset "
-msgstr ""
-
-msgid "warning: repository is unrelated\n"
-msgstr ""
-
-msgid "repository is unrelated"
-msgstr ""
-
 #, python-format
 msgid "push creates new remote branches: %s!"
 msgstr ""
@@ -9288,10 +10147,11 @@
 msgstr ""
 
 #, python-format
-msgid "push creates new remote heads on branch '%s'!"
-msgstr ""
-
-msgid "push creates new remote heads!"
+msgid "push creates new remote head %s on branch '%s'!"
+msgstr ""
+
+#, python-format
+msgid "push creates new remote head %s!"
 msgstr ""
 
 msgid "you should pull and merge or use push -f to force"
@@ -9299,6 +10159,7 @@
 
 msgid "did you forget to merge? use push -f to force"
 msgstr ""
+"ați uitat să executați fuziunea? folosiți `push -f` pentru a forța acțiunea"
 
 msgid "note: unsynced remote changes!\n"
 msgstr ""
@@ -9396,13 +10257,10 @@
 msgid "abort: out of memory\n"
 msgstr "abandon: memorie epuizată\n"
 
-msgid "** unknown exception encountered, details follow\n"
-msgstr ""
-
-msgid "** report bug details to http://mercurial.selenic.com/bts/\n"
-msgstr ""
-
-msgid "** or mercurial@selenic.com\n"
+msgid "** unknown exception encountered, please report by visiting\n"
+msgstr ""
+
+msgid "**  http://mercurial.selenic.com/wiki/BugTracker\n"
 msgstr ""
 
 #, python-format
@@ -9425,6 +10283,11 @@
 
 #, python-format
 msgid ""
+"No argument found for substitution of %i variable in alias '%s' definition."
+msgstr ""
+
+#, python-format
+msgid ""
 "error in definition for alias '%s': %s may only be given on the command "
 "line\n"
 msgstr ""
@@ -9449,10 +10312,10 @@
 msgid "extension '%s' overrides commands: %s\n"
 msgstr ""
 
-msgid "Option --config may not be abbreviated!"
-msgstr ""
-
-msgid "Option --cwd may not be abbreviated!"
+msgid "option --config may not be abbreviated!"
+msgstr ""
+
+msgid "option --cwd may not be abbreviated!"
 msgstr ""
 
 msgid ""
@@ -9468,12 +10331,13 @@
 msgid "repository '%s' is not local"
 msgstr ""
 
+#, python-format
+msgid "no repository found in %r (.hg not found)"
+msgstr "nu s-a găsit niciun depozit în %r (nu s-a găsit .hg)"
+
 msgid "warning: --repository ignored\n"
 msgstr ""
 
-msgid "invalid arguments"
-msgstr ""
-
 #, python-format
 msgid "unrecognized profiling format '%s' - Ignored\n"
 msgstr ""
@@ -9492,6 +10356,10 @@
 msgstr ""
 
 #, python-format
+msgid "warning: error finding commands in %s\n"
+msgstr ""
+
+#, python-format
 msgid "couldn't find merge tool %s\n"
 msgstr ""
 
@@ -9535,12 +10403,6 @@
 msgid "was merge of '%s' successful (yn)?"
 msgstr ""
 
-msgid "&No"
-msgstr ""
-
-msgid "&Yes"
-msgstr ""
-
 #, python-format
 msgid ""
 " output file %s appears unchanged\n"
@@ -9551,11 +10413,17 @@
 msgid "merging %s failed!\n"
 msgstr ""
 
+msgid "unterminated string"
+msgstr ""
+
+msgid "syntax error"
+msgstr ""
+
 msgid "starting revisions are not directly related"
 msgstr ""
 
 #, python-format
-msgid "Inconsistent state, %s:%s is good and bad"
+msgid "inconsistent state, %s:%s is good and bad"
 msgstr ""
 
 #, python-format
@@ -9589,6 +10457,9 @@
 msgid "Diff Formats"
 msgstr "Formate pentru diff"
 
+msgid "Merge Tools"
+msgstr ""
+
 msgid "Template Usage"
 msgstr "Folosirea șabloanelor"
 
@@ -9598,74 +10469,27 @@
 msgid "Using additional features"
 msgstr "Folosirea facilităților suplimentare"
 
+msgid "Subrepositories"
+msgstr "Subdepozite"
+
 msgid "Configuring hgweb"
 msgstr "Configurarea hgweb"
 
 msgid "Glossary"
 msgstr "Glosar"
 
-msgid ""
-"Mercurial reads configuration data from several files, if they exist.\n"
-"Below we list the most specific file first."
-msgstr ""
-
-msgid "On Windows, these configuration files are read:"
-msgstr ""
-
-msgid ""
-"- ``<repo>\\.hg\\hgrc``\n"
-"- ``%USERPROFILE%\\.hgrc``\n"
-"- ``%USERPROFILE%\\mercurial.ini``\n"
-"- ``%HOME%\\.hgrc``\n"
-"- ``%HOME%\\mercurial.ini``\n"
-"- ``C:\\mercurial\\mercurial.ini`` (unless regkey or hgrc.d\\ or mercurial."
-"ini found)\n"
-"- ``HKEY_LOCAL_MACHINE\\SOFTWARE\\Mercurial`` (unless hgrc.d\\ or mercurial."
-"ini found)\n"
-"- ``<hg.exe-dir>\\hgrc.d\\*.rc`` (unless mercurial.ini found)\n"
-"- ``<hg.exe-dir>\\mercurial.ini``"
-msgstr ""
-
-msgid "On Unix, these files are read:"
-msgstr ""
-
-msgid ""
-"- ``<repo>/.hg/hgrc``\n"
-"- ``$HOME/.hgrc``\n"
-"- ``/etc/mercurial/hgrc``\n"
-"- ``/etc/mercurial/hgrc.d/*.rc``\n"
-"- ``<install-root>/etc/mercurial/hgrc``\n"
-"- ``<install-root>/etc/mercurial/hgrc.d/*.rc``"
-msgstr ""
-
-msgid ""
-"If there is a per-repository configuration file which is not owned by\n"
-"the active user, Mercurial will warn you that the file is skipped::"
-msgstr ""
-"Dacă există un fișier de configurare la nivelul depozitului care nu\n"
-"este proprietatea utilizatorului activ, Mercurial vă va avertiza că\n"
-"fișierul este omis::"
-
-msgid ""
-"  not trusting file <repo>/.hg/hgrc from untrusted user USER, group GROUP"
-msgstr ""
-
-msgid ""
-"If this bothers you, the warning can be silenced (the file would still\n"
-"be ignored) or trust can be established. Use one of the following\n"
-"settings, the syntax is explained below:"
-msgstr ""
-
-msgid ""
-"- ``ui.report_untrusted = False``\n"
-"- ``trusted.users = USER``\n"
-"- ``trusted.groups = GROUP``"
-msgstr ""
-
-msgid ""
-"The configuration files for Mercurial use a simple ini-file format. A\n"
-"configuration file consists of sections, led by a ``[section]`` header\n"
-"and followed by ``name = value`` entries::"
+msgid "syntax for Mercurial ignore files"
+msgstr "sintaxa pentru fișierele de ignorare Mercurial"
+
+msgid ""
+"The Mercurial system uses a set of configuration files to control\n"
+"aspects of its behavior."
+msgstr ""
+
+msgid ""
+"The configuration files use a simple ini-file format. A configuration\n"
+"file consists of sections, led by a ``[section]`` header and followed\n"
+"by ``name = value`` entries::"
 msgstr ""
 
 msgid ""
@@ -9676,13 +10500,1837 @@
 
 msgid ""
 "The above entries will be referred to as ``ui.username`` and\n"
-"``ui.verbose``, respectively. Please see the hgrc man page for a full\n"
-"description of the possible configuration values:"
-msgstr ""
-
-msgid ""
-"- on Unix-like systems: ``man hgrc``\n"
-"- online: http://www.selenic.com/mercurial/hgrc.5.html\n"
+"``ui.verbose``, respectively. See the Syntax section below."
+msgstr ""
+
+msgid ""
+"Files\n"
+"-----"
+msgstr ""
+
+msgid ""
+"Mercurial reads configuration data from several files, if they exist.\n"
+"These files do not exist by default and you will have to create the\n"
+"appropriate configuration files yourself: global configuration like\n"
+"the username setting is typically put into\n"
+"``%USERPROFILE%\\mercurial.ini`` or ``$HOME/.hgrc`` and local\n"
+"configuration is put into the per-repository ``<repo>/.hg/hgrc`` file."
+msgstr ""
+
+msgid ""
+"The names of these files depend on the system on which Mercurial is\n"
+"installed. ``*.rc`` files from a single directory are read in\n"
+"alphabetical order, later ones overriding earlier ones. Where multiple\n"
+"paths are given below, settings from earlier paths override later\n"
+"ones."
+msgstr ""
+
+msgid "| (Unix, Windows) ``<repo>/.hg/hgrc``"
+msgstr ""
+
+msgid ""
+"    Per-repository configuration options that only apply in a\n"
+"    particular repository. This file is not version-controlled, and\n"
+"    will not get transferred during a \"clone\" operation. Options in\n"
+"    this file override options in all other configuration files. On\n"
+"    Unix, most of this file will be ignored if it doesn't belong to a\n"
+"    trusted user or to a trusted group. See the documentation for the\n"
+"    Trusted section below for more details."
+msgstr ""
+
+msgid ""
+"| (Unix) ``$HOME/.hgrc``\n"
+"| (Windows) ``%USERPROFILE%\\.hgrc``\n"
+"| (Windows) ``%USERPROFILE%\\Mercurial.ini``\n"
+"| (Windows) ``%HOME%\\.hgrc``\n"
+"| (Windows) ``%HOME%\\Mercurial.ini``"
+msgstr ""
+
+msgid ""
+"    Per-user configuration file(s), for the user running Mercurial. On\n"
+"    Windows 9x, ``%HOME%`` is replaced by ``%APPDATA%``. Options in these\n"
+"    files apply to all Mercurial commands executed by this user in any\n"
+"    directory. Options in these files override per-system and per-"
+"installation\n"
+"    options."
+msgstr ""
+
+msgid ""
+"| (Unix) ``/etc/mercurial/hgrc``\n"
+"| (Unix) ``/etc/mercurial/hgrc.d/*.rc``"
+msgstr ""
+
+msgid ""
+"    Per-system configuration files, for the system on which Mercurial\n"
+"    is running. Options in these files apply to all Mercurial commands\n"
+"    executed by any user in any directory. Options in these files\n"
+"    override per-installation options."
+msgstr ""
+
+msgid ""
+"| (Unix) ``<install-root>/etc/mercurial/hgrc``\n"
+"| (Unix) ``<install-root>/etc/mercurial/hgrc.d/*.rc``"
+msgstr ""
+
+msgid ""
+"    Per-installation configuration files, searched for in the\n"
+"    directory where Mercurial is installed. ``<install-root>`` is the\n"
+"    parent directory of the **hg** executable (or symlink) being run. For\n"
+"    example, if installed in ``/shared/tools/bin/hg``, Mercurial will look\n"
+"    in ``/shared/tools/etc/mercurial/hgrc``. Options in these files apply\n"
+"    to all Mercurial commands executed by any user in any directory."
+msgstr ""
+
+msgid ""
+"| (Windows) ``<install-dir>\\Mercurial.ini`` **or**\n"
+"| (Windows) ``<install-dir>\\hgrc.d\\*.rc`` **or**\n"
+"| (Windows) ``HKEY_LOCAL_MACHINE\\SOFTWARE\\Mercurial``"
+msgstr ""
+
+msgid ""
+"    Per-installation/system configuration files, for the system on\n"
+"    which Mercurial is running. Options in these files apply to all\n"
+"    Mercurial commands executed by any user in any directory. Registry\n"
+"    keys contain PATH-like strings, every part of which must reference\n"
+"    a ``Mercurial.ini`` file or be a directory where ``*.rc`` files will\n"
+"    be read.  Mercurial checks each of these locations in the specified\n"
+"    order until one or more configuration files are detected.  If the\n"
+"    pywin32 extensions are not installed, Mercurial will only look for\n"
+"    site-wide configuration in ``C:\\Mercurial\\Mercurial.ini``."
+msgstr ""
+
+msgid ""
+"Syntax\n"
+"------"
+msgstr ""
+
+msgid ""
+"A configuration file consists of sections, led by a ``[section]`` header\n"
+"and followed by ``name = value`` entries (sometimes called\n"
+"``configuration keys``)::"
+msgstr ""
+
+msgid ""
+"    [spam]\n"
+"    eggs=ham\n"
+"    green=\n"
+"       eggs"
+msgstr ""
+
+msgid ""
+"Each line contains one entry. If the lines that follow are indented,\n"
+"they are treated as continuations of that entry. Leading whitespace is\n"
+"removed from values. Empty lines are skipped. Lines beginning with\n"
+"``#`` or ``;`` are ignored and may be used to provide comments."
+msgstr ""
+
+msgid ""
+"Configuration keys can be set multiple times, in which case mercurial\n"
+"will use the value that was configured last. As an example::"
+msgstr ""
+
+msgid ""
+"    [spam]\n"
+"    eggs=large\n"
+"    ham=serrano\n"
+"    eggs=small"
+msgstr ""
+
+msgid "This would set the configuration key named ``eggs`` to ``small``."
+msgstr ""
+
+msgid ""
+"It is also possible to define a section multiple times. A section can\n"
+"be redefined on the same and/or on different hgrc files. For example::"
+msgstr ""
+
+msgid ""
+"    [foo]\n"
+"    eggs=large\n"
+"    ham=serrano\n"
+"    eggs=small"
+msgstr ""
+
+msgid ""
+"    [bar]\n"
+"    eggs=ham\n"
+"    green=\n"
+"       eggs"
+msgstr ""
+
+msgid ""
+"    [foo]\n"
+"    ham=prosciutto\n"
+"    eggs=medium\n"
+"    bread=toasted"
+msgstr ""
+
+msgid ""
+"This would set the ``eggs``, ``ham``, and ``bread`` configuration keys\n"
+"of the ``foo`` section to ``medium``, ``prosciutto``, and ``toasted``,\n"
+"respectively. As you can see there only thing that matters is the last\n"
+"value that was set for each of the configuration keys."
+msgstr ""
+
+msgid ""
+"If a configuration key is set multiple times in different\n"
+"configuration files the final value will depend on the order in which\n"
+"the different configuration files are read, with settings from earlier\n"
+"paths overriding later ones as described on the ``Files`` section\n"
+"above."
+msgstr ""
+
+msgid ""
+"A line of the form ``%include file`` will include ``file`` into the\n"
+"current configuration file. The inclusion is recursive, which means\n"
+"that included files can include other files. Filenames are relative to\n"
+"the configuration file in which the ``%include`` directive is found.\n"
+"Environment variables and ``~user`` constructs are expanded in\n"
+"``file``. This lets you do something like::"
+msgstr ""
+
+msgid "  %include ~/.hgrc.d/$HOST.rc"
+msgstr ""
+
+msgid "to include a different configuration file on each computer you use."
+msgstr ""
+
+msgid ""
+"A line with ``%unset name`` will remove ``name`` from the current\n"
+"section, if it has been set previously."
+msgstr ""
+
+msgid ""
+"The values are either free-form text strings, lists of text strings,\n"
+"or Boolean values. Boolean values can be set to true using any of \"1\",\n"
+"\"yes\", \"true\", or \"on\" and to false using \"0\", \"no\", \"false\", or "
+"\"off\"\n"
+"(all case insensitive)."
+msgstr ""
+
+msgid ""
+"List values are separated by whitespace or comma, except when values are\n"
+"placed in double quotation marks::"
+msgstr ""
+
+msgid "  allow_read = \"John Doe, PhD\", brian, betty"
+msgstr ""
+
+msgid ""
+"Quotation marks can be escaped by prefixing them with a backslash. Only\n"
+"quotation marks at the beginning of a word is counted as a quotation\n"
+"(e.g., ``foo\"bar baz`` is the list of ``foo\"bar`` and ``baz``)."
+msgstr ""
+
+msgid ""
+"Sections\n"
+"--------"
+msgstr ""
+
+msgid ""
+"This section describes the different sections that may appear in a\n"
+"Mercurial \"hgrc\" file, the purpose of each section, its possible keys,\n"
+"and their possible values."
+msgstr ""
+
+msgid ""
+"``alias``\n"
+"\"\"\"\"\"\"\"\"\""
+msgstr ""
+
+msgid ""
+"Defines command aliases.\n"
+"Aliases allow you to define your own commands in terms of other\n"
+"commands (or aliases), optionally including arguments. Positional\n"
+"arguments in the form of ``$1``, ``$2``, etc in the alias definition\n"
+"are expanded by Mercurial before execution. Positional arguments not\n"
+"already used by ``$N`` in the definition are put at the end of the\n"
+"command to be executed."
+msgstr ""
+
+msgid "Alias definitions consist of lines of the form::"
+msgstr ""
+
+msgid "    <alias> = <command> [<argument]..."
+msgstr ""
+
+msgid "For example, this definition::"
+msgstr ""
+
+msgid "    latest = log --limit 5"
+msgstr ""
+
+msgid ""
+"creates a new command ``latest`` that shows only the five most recent\n"
+"changesets. You can define subsequent aliases using earlier ones::"
+msgstr ""
+
+msgid "    stable5 = latest -b stable"
+msgstr ""
+
+msgid ""
+".. note:: It is possible to create aliases with the same names as\n"
+"   existing commands, which will then override the original\n"
+"   definitions. This is almost always a bad idea!"
+msgstr ""
+
+msgid ""
+"An alias can start with an exclamation point (``!``) to make it a\n"
+"shell alias. A shell alias is executed with the shell and will let you\n"
+"run arbitrary commands. As an example, ::"
+msgstr ""
+
+msgid "   echo = !echo"
+msgstr ""
+
+msgid ""
+"will let you do ``hg echo foo`` to have ``foo`` printed in your\n"
+"terminal. A better example might be::"
+msgstr ""
+
+msgid "   purge = !$HG status --no-status --unknown -0 | xargs -0 rm"
+msgstr ""
+
+msgid ""
+"which will make ``hg purge`` delete all unknown files in the\n"
+"repository in the same manner as the purge extension."
+msgstr ""
+
+msgid ""
+"Shell aliases are executed in an environment where ``$HG`` expand to\n"
+"the path of the Mercurial that was used to execute the alias. This is\n"
+"useful when you want to call further Mercurial commands in a shell\n"
+"alias, as was done above for the purge alias. In addition,\n"
+"``$HG_ARGS`` expand to the arguments given to Mercurial. In the ``hg\n"
+"echo foo`` call above, ``$HG_ARGS`` would expand to ``echo foo``."
+msgstr ""
+
+msgid ""
+"``auth``\n"
+"\"\"\"\"\"\"\"\""
+msgstr ""
+
+msgid ""
+"Authentication credentials for HTTP authentication. This section\n"
+"allows you to store usernames and passwords for use when logging\n"
+"*into* HTTP servers. See the web_ configuration section if you want to\n"
+"configure *who* can login to your HTTP server."
+msgstr ""
+
+msgid "Each line has the following format::"
+msgstr ""
+
+msgid "    <name>.<argument> = <value>"
+msgstr ""
+
+msgid ""
+"where ``<name>`` is used to group arguments into authentication\n"
+"entries. Example::"
+msgstr ""
+
+msgid ""
+"    foo.prefix = hg.intevation.org/mercurial\n"
+"    foo.username = foo\n"
+"    foo.password = bar\n"
+"    foo.schemes = http https"
+msgstr ""
+
+msgid ""
+"    bar.prefix = secure.example.org\n"
+"    bar.key = path/to/file.key\n"
+"    bar.cert = path/to/file.cert\n"
+"    bar.schemes = https"
+msgstr ""
+
+msgid "Supported arguments:"
+msgstr ""
+
+msgid ""
+"``prefix``\n"
+"    Either ``*`` or a URI prefix with or without the scheme part.\n"
+"    The authentication entry with the longest matching prefix is used\n"
+"    (where ``*`` matches everything and counts as a match of length\n"
+"    1). If the prefix doesn't include a scheme, the match is performed\n"
+"    against the URI with its scheme stripped as well, and the schemes\n"
+"    argument, q.v., is then subsequently consulted."
+msgstr ""
+
+msgid ""
+"``username``\n"
+"    Optional. Username to authenticate with. If not given, and the\n"
+"    remote site requires basic or digest authentication, the user will\n"
+"    be prompted for it. Environment variables are expanded in the\n"
+"    username letting you do ``foo.username = $USER``."
+msgstr ""
+
+msgid ""
+"``password``\n"
+"    Optional. Password to authenticate with. If not given, and the\n"
+"    remote site requires basic or digest authentication, the user\n"
+"    will be prompted for it."
+msgstr ""
+
+msgid ""
+"``key``\n"
+"    Optional. PEM encoded client certificate key file. Environment\n"
+"    variables are expanded in the filename."
+msgstr ""
+
+msgid ""
+"``cert``\n"
+"    Optional. PEM encoded client certificate chain file. Environment\n"
+"    variables are expanded in the filename."
+msgstr ""
+
+msgid ""
+"``schemes``\n"
+"    Optional. Space separated list of URI schemes to use this\n"
+"    authentication entry with. Only used if the prefix doesn't include\n"
+"    a scheme. Supported schemes are http and https. They will match\n"
+"    static-http and static-https respectively, as well.\n"
+"    Default: https."
+msgstr ""
+
+msgid ""
+"If no suitable authentication entry is found, the user is prompted\n"
+"for credentials as usual if required by the remote."
+msgstr ""
+
+msgid ""
+"\n"
+"``decode/encode``\n"
+"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\""
+msgstr ""
+
+msgid ""
+"Filters for transforming files on checkout/checkin. This would\n"
+"typically be used for newline processing or other\n"
+"localization/canonicalization of files."
+msgstr ""
+
+msgid ""
+"Filters consist of a filter pattern followed by a filter command.\n"
+"Filter patterns are globs by default, rooted at the repository root.\n"
+"For example, to match any file ending in ``.txt`` in the root\n"
+"directory only, use the pattern ``*.txt``. To match any file ending\n"
+"in ``.c`` anywhere in the repository, use the pattern ``**.c``.\n"
+"For each file only the first matching filter applies."
+msgstr ""
+
+msgid ""
+"The filter command can start with a specifier, either ``pipe:`` or\n"
+"``tempfile:``. If no specifier is given, ``pipe:`` is used by default."
+msgstr ""
+
+msgid ""
+"A ``pipe:`` command must accept data on stdin and return the transformed\n"
+"data on stdout."
+msgstr ""
+
+msgid "Pipe example::"
+msgstr ""
+
+msgid ""
+"  [encode]\n"
+"  # uncompress gzip files on checkin to improve delta compression\n"
+"  # note: not necessarily a good idea, just an example\n"
+"  *.gz = pipe: gunzip"
+msgstr ""
+
+msgid ""
+"  [decode]\n"
+"  # recompress gzip files when writing them to the working dir (we\n"
+"  # can safely omit \"pipe:\", because it's the default)\n"
+"  *.gz = gzip"
+msgstr ""
+
+msgid ""
+"A ``tempfile:`` command is a template. The string ``INFILE`` is replaced\n"
+"with the name of a temporary file that contains the data to be\n"
+"filtered by the command. The string ``OUTFILE`` is replaced with the name\n"
+"of an empty temporary file, where the filtered data must be written by\n"
+"the command."
+msgstr ""
+
+msgid ""
+".. note:: The tempfile mechanism is recommended for Windows systems,\n"
+"   where the standard shell I/O redirection operators often have\n"
+"   strange effects and may corrupt the contents of your files."
+msgstr ""
+
+msgid ""
+"This filter mechanism is used internally by the ``eol`` extension to\n"
+"translate line ending characters between Windows (CRLF) and Unix (LF)\n"
+"format. We suggest you use the ``eol`` extension for convenience."
+msgstr ""
+
+msgid ""
+"\n"
+"``defaults``\n"
+"\"\"\"\"\"\"\"\"\"\"\"\""
+msgstr ""
+
+msgid "(defaults are deprecated. Don't use them. Use aliases instead)"
+msgstr ""
+
+msgid ""
+"Use the ``[defaults]`` section to define command defaults, i.e. the\n"
+"default options/arguments to pass to the specified commands."
+msgstr ""
+
+msgid ""
+"The following example makes :hg:`log` run in verbose mode, and\n"
+":hg:`status` show only the modified files, by default::"
+msgstr ""
+
+msgid ""
+"  [defaults]\n"
+"  log = -v\n"
+"  status = -m"
+msgstr ""
+
+msgid ""
+"The actual commands, instead of their aliases, must be used when\n"
+"defining command defaults. The command defaults will also be applied\n"
+"to the aliases of the commands defined."
+msgstr ""
+
+msgid ""
+"\n"
+"``diff``\n"
+"\"\"\"\"\"\"\"\""
+msgstr ""
+
+msgid ""
+"Settings used when displaying diffs. Everything except for ``unified`` is a\n"
+"Boolean and defaults to False."
+msgstr ""
+
+msgid ""
+"``git``\n"
+"    Use git extended diff format."
+msgstr ""
+"``git``\n"
+"    Folosește formatul diff extins al lui git."
+
+msgid ""
+"``nodates``\n"
+"    Don't include dates in diff headers."
+msgstr ""
+
+msgid ""
+"``showfunc``\n"
+"    Show which function each change is in."
+msgstr ""
+"``showfunc``\n"
+"    Afișează funcția în care se află fiecare modificare."
+
+msgid ""
+"``ignorews``\n"
+"    Ignore white space when comparing lines."
+msgstr ""
+"``ignorews``\n"
+"    Ignoră spațiul alb la compararea liniilor."
+
+msgid ""
+"``ignorewsamount``\n"
+"    Ignore changes in the amount of white space."
+msgstr ""
+"``ignorewsamount``\n"
+"    Ignoră modificările cantității de spațiu alb."
+
+msgid ""
+"``ignoreblanklines``\n"
+"    Ignore changes whose lines are all blank."
+msgstr ""
+"``ignoreblanklines``\n"
+"    Ignoră modificările ale căror linii sunt toate vide."
+
+msgid ""
+"``unified``\n"
+"    Number of lines of context to show."
+msgstr ""
+"``unified``\n"
+"    Numărul liniilor de context care vor fi afișate."
+
+msgid ""
+"``email``\n"
+"\"\"\"\"\"\"\"\"\""
+msgstr ""
+
+msgid "Settings for extensions that send email messages."
+msgstr ""
+
+msgid ""
+"``from``\n"
+"    Optional. Email address to use in \"From\" header and SMTP envelope\n"
+"    of outgoing messages."
+msgstr ""
+
+msgid ""
+"``to``\n"
+"    Optional. Comma-separated list of recipients' email addresses."
+msgstr ""
+
+msgid ""
+"``cc``\n"
+"    Optional. Comma-separated list of carbon copy recipients'\n"
+"    email addresses."
+msgstr ""
+
+msgid ""
+"``bcc``\n"
+"    Optional. Comma-separated list of blind carbon copy recipients'\n"
+"    email addresses."
+msgstr ""
+
+msgid ""
+"``method``\n"
+"    Optional. Method to use to send email messages. If value is ``smtp``\n"
+"    (default), use SMTP (see the SMTP_ section for configuration).\n"
+"    Otherwise, use as name of program to run that acts like sendmail\n"
+"    (takes ``-f`` option for sender, list of recipients on command line,\n"
+"    message on stdin). Normally, setting this to ``sendmail`` or\n"
+"    ``/usr/sbin/sendmail`` is enough to use sendmail to send messages."
+msgstr ""
+
+msgid ""
+"``charsets``\n"
+"    Optional. Comma-separated list of character sets considered\n"
+"    convenient for recipients. Addresses, headers, and parts not\n"
+"    containing patches of outgoing messages will be encoded in the\n"
+"    first character set to which conversion from local encoding\n"
+"    (``$HGENCODING``, ``ui.fallbackencoding``) succeeds. If correct\n"
+"    conversion fails, the text in question is sent as is. Defaults to\n"
+"    empty (explicit) list."
+msgstr ""
+
+msgid "    Order of outgoing email character sets:"
+msgstr ""
+
+msgid ""
+"    1. ``us-ascii``: always first, regardless of settings\n"
+"    2. ``email.charsets``: in order given by user\n"
+"    3. ``ui.fallbackencoding``: if not in email.charsets\n"
+"    4. ``$HGENCODING``: if not in email.charsets\n"
+"    5. ``utf-8``: always last, regardless of settings"
+msgstr ""
+
+msgid "Email example::"
+msgstr ""
+
+msgid ""
+"  [email]\n"
+"  from = Joseph User <joe.user@example.com>\n"
+"  method = /usr/sbin/sendmail\n"
+"  # charsets for western Europeans\n"
+"  # us-ascii, utf-8 omitted, as they are tried first and last\n"
+"  charsets = iso-8859-1, iso-8859-15, windows-1252"
+msgstr ""
+
+msgid ""
+"\n"
+"``extensions``\n"
+"\"\"\"\"\"\"\"\"\"\"\"\"\"\""
+msgstr ""
+
+msgid ""
+"Mercurial has an extension mechanism for adding new features. To\n"
+"enable an extension, create an entry for it in this section."
+msgstr ""
+
+msgid ""
+"If you know that the extension is already in Python's search path,\n"
+"you can give the name of the module, followed by ``=``, with nothing\n"
+"after the ``=``."
+msgstr ""
+
+msgid ""
+"Otherwise, give a name that you choose, followed by ``=``, followed by\n"
+"the path to the ``.py`` file (including the file name extension) that\n"
+"defines the extension."
+msgstr ""
+
+msgid ""
+"To explicitly disable an extension that is enabled in an hgrc of\n"
+"broader scope, prepend its path with ``!``, as in ``foo = !/ext/path``\n"
+"or ``foo = !`` when path is not supplied."
+msgstr ""
+
+msgid "Example for ``~/.hgrc``::"
+msgstr ""
+
+msgid ""
+"  [extensions]\n"
+"  # (the mq extension will get loaded from Mercurial's path)\n"
+"  mq =\n"
+"  # (this extension will get loaded from the file specified)\n"
+"  myfeature = ~/.hgext/myfeature.py"
+msgstr ""
+
+msgid ""
+"\n"
+"``hostfingerprints``\n"
+"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\""
+msgstr ""
+
+msgid ""
+"Fingerprints of the certificates of known HTTPS servers.\n"
+"A HTTPS connection to a server with a fingerprint configured here will\n"
+"only succeed if the servers certificate matches the fingerprint.\n"
+"This is very similar to how ssh known hosts works.\n"
+"The fingerprint is the SHA-1 hash value of the DER encoded certificate.\n"
+"The CA chain and web.cacerts is not used for servers with a fingerprint."
+msgstr ""
+
+msgid "For example::"
+msgstr ""
+
+msgid ""
+"    [hostfingerprints]\n"
+"    hg.intevation.org = 38:76:52:7c:87:26:9a:8f:4a:f8:d3:de:08:45:3b:ea:"
+"d6:4b:ee:cc"
+msgstr ""
+
+msgid "This feature is only supported when using Python 2.6 or later."
+msgstr ""
+
+msgid ""
+"\n"
+"``format``\n"
+"\"\"\"\"\"\"\"\"\"\""
+msgstr ""
+
+msgid ""
+"``usestore``\n"
+"    Enable or disable the \"store\" repository format which improves\n"
+"    compatibility with systems that fold case or otherwise mangle\n"
+"    filenames. Enabled by default. Disabling this option will allow\n"
+"    you to store longer filenames in some situations at the expense of\n"
+"    compatibility and ensures that the on-disk format of newly created\n"
+"    repositories will be compatible with Mercurial before version 0.9.4."
+msgstr ""
+
+msgid ""
+"``usefncache``\n"
+"    Enable or disable the \"fncache\" repository format which enhances\n"
+"    the \"store\" repository format (which has to be enabled to use\n"
+"    fncache) to allow longer filenames and avoids using Windows\n"
+"    reserved names, e.g. \"nul\". Enabled by default. Disabling this\n"
+"    option ensures that the on-disk format of newly created\n"
+"    repositories will be compatible with Mercurial before version 1.1."
+msgstr ""
+
+msgid ""
+"``dotencode``\n"
+"    Enable or disable the \"dotencode\" repository format which enhances\n"
+"    the \"fncache\" repository format (which has to be enabled to use\n"
+"    dotencode) to avoid issues with filenames starting with ._ on\n"
+"    Mac OS X and spaces on Windows. Enabled by default. Disabling this\n"
+"    option ensures that the on-disk format of newly created\n"
+"    repositories will be compatible with Mercurial before version 1.7."
+msgstr ""
+
+msgid ""
+"``merge-patterns``\n"
+"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\""
+msgstr ""
+
+msgid ""
+"This section specifies merge tools to associate with particular file\n"
+"patterns. Tools matched here will take precedence over the default\n"
+"merge tool. Patterns are globs by default, rooted at the repository\n"
+"root."
+msgstr ""
+
+msgid ""
+"  [merge-patterns]\n"
+"  **.c = kdiff3\n"
+"  **.jpg = myimgmerge"
+msgstr ""
+
+msgid ""
+"``merge-tools``\n"
+"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\""
+msgstr ""
+
+msgid ""
+"This section configures external merge tools to use for file-level\n"
+"merges."
+msgstr ""
+
+msgid "Example ``~/.hgrc``::"
+msgstr ""
+
+msgid ""
+"  [merge-tools]\n"
+"  # Override stock tool location\n"
+"  kdiff3.executable = ~/bin/kdiff3\n"
+"  # Specify command line\n"
+"  kdiff3.args = $base $local $other -o $output\n"
+"  # Give higher priority\n"
+"  kdiff3.priority = 1"
+msgstr ""
+
+msgid ""
+"  # Define new tool\n"
+"  myHtmlTool.args = -m $local $other $base $output\n"
+"  myHtmlTool.regkey = Software\\FooSoftware\\HtmlMerge\n"
+"  myHtmlTool.priority = 1"
+msgstr ""
+
+msgid ""
+"``priority``\n"
+"  The priority in which to evaluate this tool.\n"
+"  Default: 0."
+msgstr ""
+
+msgid ""
+"``executable``\n"
+"  Either just the name of the executable or its pathname.  On Windows,\n"
+"  the path can use environment variables with ${ProgramFiles} syntax.\n"
+"  Default: the tool name."
+msgstr ""
+
+msgid ""
+"``args``\n"
+"  The arguments to pass to the tool executable. You can refer to the\n"
+"  files being merged as well as the output file through these\n"
+"  variables: ``$base``, ``$local``, ``$other``, ``$output``.\n"
+"  Default: ``$local $base $other``"
+msgstr ""
+
+msgid ""
+"``premerge``\n"
+"  Attempt to run internal non-interactive 3-way merge tool before\n"
+"  launching external tool.  Options are ``true``, ``false``, or ``keep``\n"
+"  to leave markers in the file if the premerge fails.\n"
+"  Default: True"
+msgstr ""
+
+msgid ""
+"``binary``\n"
+"  This tool can merge binary files. Defaults to False, unless tool\n"
+"  was selected by file pattern match."
+msgstr ""
+
+msgid ""
+"``symlink``\n"
+"  This tool can merge symlinks. Defaults to False, even if tool was\n"
+"  selected by file pattern match."
+msgstr ""
+
+msgid ""
+"``check``\n"
+"  A list of merge success-checking options:"
+msgstr ""
+
+msgid ""
+"  ``changed``\n"
+"    Ask whether merge was successful when the merged file shows no changes.\n"
+"  ``conflicts``\n"
+"    Check whether there are conflicts even though the tool reported "
+"success.\n"
+"  ``prompt``\n"
+"    Always prompt for merge success, regardless of success reported by tool."
+msgstr ""
+
+msgid ""
+"``checkchanged``\n"
+"  True is equivalent to ``check = changed``.\n"
+"  Default: False"
+msgstr ""
+
+msgid ""
+"``checkconflicts``\n"
+"  True is equivalent to ``check = conflicts``.\n"
+"  Default: False"
+msgstr ""
+
+msgid ""
+"``fixeol``\n"
+"  Attempt to fix up EOL changes caused by the merge tool.\n"
+"  Default: False"
+msgstr ""
+
+msgid ""
+"``gui``\n"
+"  This tool requires a graphical interface to run. Default: False"
+msgstr ""
+
+msgid ""
+"``regkey``\n"
+"  Windows registry key which describes install location of this\n"
+"  tool. Mercurial will search for this key first under\n"
+"  ``HKEY_CURRENT_USER`` and then under ``HKEY_LOCAL_MACHINE``.\n"
+"  Default: None"
+msgstr ""
+
+msgid ""
+"``regkeyalt``\n"
+"  An alternate Windows registry key to try if the first key is not\n"
+"  found.  The alternate key uses the same ``regname`` and ``regappend``\n"
+"  semantics of the primary key.  The most common use for this key\n"
+"  is to search for 32bit applications on 64bit operating systems.\n"
+"  Default: None"
+msgstr ""
+
+msgid ""
+"``regname``\n"
+"  Name of value to read from specified registry key. Defaults to the\n"
+"  unnamed (default) value."
+msgstr ""
+
+msgid ""
+"``regappend``\n"
+"  String to append to the value read from the registry, typically\n"
+"  the executable name of the tool.\n"
+"  Default: None"
+msgstr ""
+
+msgid ""
+"\n"
+"``hooks``\n"
+"\"\"\"\"\"\"\"\"\""
+msgstr ""
+
+msgid ""
+"Commands or Python functions that get automatically executed by\n"
+"various actions such as starting or finishing a commit. Multiple\n"
+"hooks can be run for the same action by appending a suffix to the\n"
+"action. Overriding a site-wide hook can be done by changing its\n"
+"value or setting it to an empty string."
+msgstr ""
+
+msgid "Example ``.hg/hgrc``::"
+msgstr ""
+
+msgid ""
+"  [hooks]\n"
+"  # update working directory after adding changesets\n"
+"  changegroup.update = hg update\n"
+"  # do not use the site-wide hook\n"
+"  incoming =\n"
+"  incoming.email = /my/email/hook\n"
+"  incoming.autobuild = /my/build/hook"
+msgstr ""
+
+msgid ""
+"Most hooks are run with environment variables set that give useful\n"
+"additional information. For each hook below, the environment\n"
+"variables it is passed are listed with names of the form ``$HG_foo``."
+msgstr ""
+
+msgid ""
+"``changegroup``\n"
+"  Run after a changegroup has been added via push, pull or unbundle.\n"
+"  ID of the first new changeset is in ``$HG_NODE``. URL from which\n"
+"  changes came is in ``$HG_URL``."
+msgstr ""
+
+msgid ""
+"``commit``\n"
+"  Run after a changeset has been created in the local repository. ID\n"
+"  of the newly created changeset is in ``$HG_NODE``. Parent changeset\n"
+"  IDs are in ``$HG_PARENT1`` and ``$HG_PARENT2``."
+msgstr ""
+
+msgid ""
+"``incoming``\n"
+"  Run after a changeset has been pulled, pushed, or unbundled into\n"
+"  the local repository. The ID of the newly arrived changeset is in\n"
+"  ``$HG_NODE``. URL that was source of changes came is in ``$HG_URL``."
+msgstr ""
+
+msgid ""
+"``outgoing``\n"
+"  Run after sending changes from local repository to another. ID of\n"
+"  first changeset sent is in ``$HG_NODE``. Source of operation is in\n"
+"  ``$HG_SOURCE``; see \"preoutgoing\" hook for description."
+msgstr ""
+
+msgid ""
+"``post-<command>``\n"
+"  Run after successful invocations of the associated command. The\n"
+"  contents of the command line are passed as ``$HG_ARGS`` and the result\n"
+"  code in ``$HG_RESULT``. Parsed command line arguments are passed as \n"
+"  ``$HG_PATS`` and ``$HG_OPTS``. These contain string representations of\n"
+"  the python data internally passed to <command>. ``$HG_OPTS`` is a \n"
+"  dictionary of options (with unspecified options set to their defaults).\n"
+"  ``$HG_PATS`` is a list of arguments. Hook failure is ignored."
+msgstr ""
+
+msgid ""
+"``pre-<command>``\n"
+"  Run before executing the associated command. The contents of the\n"
+"  command line are passed as ``$HG_ARGS``. Parsed command line arguments\n"
+"  are passed as ``$HG_PATS`` and ``$HG_OPTS``. These contain string\n"
+"  representations of the data internally passed to <command>. ``$HG_OPTS``\n"
+"  is a  dictionary of options (with unspecified options set to their\n"
+"  defaults). ``$HG_PATS`` is a list of arguments. If the hook returns \n"
+"  failure, the command doesn't execute and Mercurial returns the failure\n"
+"  code."
+msgstr ""
+
+msgid ""
+"``prechangegroup``\n"
+"  Run before a changegroup is added via push, pull or unbundle. Exit\n"
+"  status 0 allows the changegroup to proceed. Non-zero status will\n"
+"  cause the push, pull or unbundle to fail. URL from which changes\n"
+"  will come is in ``$HG_URL``."
+msgstr ""
+
+msgid ""
+"``precommit``\n"
+"  Run before starting a local commit. Exit status 0 allows the\n"
+"  commit to proceed. Non-zero status will cause the commit to fail.\n"
+"  Parent changeset IDs are in ``$HG_PARENT1`` and ``$HG_PARENT2``."
+msgstr ""
+
+msgid ""
+"``prelistkeys``\n"
+"  Run before listing pushkeys (like bookmarks) in the\n"
+"  repository. Non-zero status will cause failure. The key namespace is\n"
+"  in ``$HG_NAMESPACE``."
+msgstr ""
+
+msgid ""
+"``preoutgoing``\n"
+"  Run before collecting changes to send from the local repository to\n"
+"  another. Non-zero status will cause failure. This lets you prevent\n"
+"  pull over HTTP or SSH. Also prevents against local pull, push\n"
+"  (outbound) or bundle commands, but not effective, since you can\n"
+"  just copy files instead then. Source of operation is in\n"
+"  ``$HG_SOURCE``. If \"serve\", operation is happening on behalf of remote\n"
+"  SSH or HTTP repository. If \"push\", \"pull\" or \"bundle\", operation\n"
+"  is happening on behalf of repository on same system."
+msgstr ""
+
+msgid ""
+"``prepushkey``\n"
+"  Run before a pushkey (like a bookmark) is added to the\n"
+"  repository. Non-zero status will cause the key to be rejected. The\n"
+"  key namespace is in ``$HG_NAMESPACE``, the key is in ``$HG_KEY``,\n"
+"  the old value (if any) is in ``$HG_OLD``, and the new value is in\n"
+"  ``$HG_NEW``."
+msgstr ""
+
+msgid ""
+"``pretag``\n"
+"  Run before creating a tag. Exit status 0 allows the tag to be\n"
+"  created. Non-zero status will cause the tag to fail. ID of\n"
+"  changeset to tag is in ``$HG_NODE``. Name of tag is in ``$HG_TAG``. Tag "
+"is\n"
+"  local if ``$HG_LOCAL=1``, in repository if ``$HG_LOCAL=0``."
+msgstr ""
+
+msgid ""
+"``pretxnchangegroup``\n"
+"  Run after a changegroup has been added via push, pull or unbundle,\n"
+"  but before the transaction has been committed. Changegroup is\n"
+"  visible to hook program. This lets you validate incoming changes\n"
+"  before accepting them. Passed the ID of the first new changeset in\n"
+"  ``$HG_NODE``. Exit status 0 allows the transaction to commit. Non-zero\n"
+"  status will cause the transaction to be rolled back and the push,\n"
+"  pull or unbundle will fail. URL that was source of changes is in\n"
+"  ``$HG_URL``."
+msgstr ""
+
+msgid ""
+"``pretxncommit``\n"
+"  Run after a changeset has been created but the transaction not yet\n"
+"  committed. Changeset is visible to hook program. This lets you\n"
+"  validate commit message and changes. Exit status 0 allows the\n"
+"  commit to proceed. Non-zero status will cause the transaction to\n"
+"  be rolled back. ID of changeset is in ``$HG_NODE``. Parent changeset\n"
+"  IDs are in ``$HG_PARENT1`` and ``$HG_PARENT2``."
+msgstr ""
+
+msgid ""
+"``preupdate``\n"
+"  Run before updating the working directory. Exit status 0 allows\n"
+"  the update to proceed. Non-zero status will prevent the update.\n"
+"  Changeset ID of first new parent is in ``$HG_PARENT1``. If merge, ID\n"
+"  of second new parent is in ``$HG_PARENT2``."
+msgstr ""
+
+msgid ""
+"``listkeys``\n"
+"  Run after listing pushkeys (like bookmarks) in the repository. The\n"
+"  key namespace is in ``$HG_NAMESPACE``. ``$HG_VALUES`` is a\n"
+"  dictionary containing the keys and values."
+msgstr ""
+
+msgid ""
+"``pushkey``\n"
+"  Run after a pushkey (like a bookmark) is added to the\n"
+"  repository. The key namespace is in ``$HG_NAMESPACE``, the key is in\n"
+"  ``$HG_KEY``, the old value (if any) is in ``$HG_OLD``, and the new\n"
+"  value is in ``$HG_NEW``."
+msgstr ""
+
+msgid ""
+"``tag``\n"
+"  Run after a tag is created. ID of tagged changeset is in ``$HG_NODE``.\n"
+"  Name of tag is in ``$HG_TAG``. Tag is local if ``$HG_LOCAL=1``, in\n"
+"  repository if ``$HG_LOCAL=0``."
+msgstr ""
+
+msgid ""
+"``update``\n"
+"  Run after updating the working directory. Changeset ID of first\n"
+"  new parent is in ``$HG_PARENT1``. If merge, ID of second new parent is\n"
+"  in ``$HG_PARENT2``. If the update succeeded, ``$HG_ERROR=0``. If the\n"
+"  update failed (e.g. because conflicts not resolved), ``$HG_ERROR=1``."
+msgstr ""
+
+msgid ""
+".. note:: It is generally better to use standard hooks rather than the\n"
+"   generic pre- and post- command hooks as they are guaranteed to be\n"
+"   called in the appropriate contexts for influencing transactions.\n"
+"   Also, hooks like \"commit\" will be called in all contexts that\n"
+"   generate a commit (e.g. tag) and not just the commit command."
+msgstr ""
+
+msgid ""
+".. note:: Environment variables with empty values may not be passed to\n"
+"   hooks on platforms such as Windows. As an example, ``$HG_PARENT2``\n"
+"   will have an empty value under Unix-like platforms for non-merge\n"
+"   changesets, while it will not be available at all under Windows."
+msgstr ""
+
+msgid "The syntax for Python hooks is as follows::"
+msgstr ""
+
+msgid ""
+"  hookname = python:modulename.submodule.callable\n"
+"  hookname = python:/path/to/python/module.py:callable"
+msgstr ""
+
+msgid ""
+"Python hooks are run within the Mercurial process. Each hook is\n"
+"called with at least three keyword arguments: a ui object (keyword\n"
+"``ui``), a repository object (keyword ``repo``), and a ``hooktype``\n"
+"keyword that tells what kind of hook is used. Arguments listed as\n"
+"environment variables above are passed as keyword arguments, with no\n"
+"``HG_`` prefix, and names in lower case."
+msgstr ""
+
+msgid ""
+"If a Python hook returns a \"true\" value or raises an exception, this\n"
+"is treated as a failure."
+msgstr ""
+
+msgid ""
+"\n"
+"``http_proxy``\n"
+"\"\"\"\"\"\"\"\"\"\"\"\"\"\""
+msgstr ""
+
+msgid ""
+"Used to access web-based Mercurial repositories through a HTTP\n"
+"proxy."
+msgstr ""
+
+msgid ""
+"``host``\n"
+"    Host name and (optional) port of the proxy server, for example\n"
+"    \"myproxy:8000\"."
+msgstr ""
+
+msgid ""
+"``no``\n"
+"    Optional. Comma-separated list of host names that should bypass\n"
+"    the proxy."
+msgstr ""
+
+msgid ""
+"``passwd``\n"
+"    Optional. Password to authenticate with at the proxy server."
+msgstr ""
+
+msgid ""
+"``user``\n"
+"    Optional. User name to authenticate with at the proxy server."
+msgstr ""
+
+msgid ""
+"``always``\n"
+"    Optional. Always use the proxy, even for localhost and any entries\n"
+"    in ``http_proxy.no``. True or False. Default: False."
+msgstr ""
+
+msgid ""
+"``smtp``\n"
+"\"\"\"\"\"\"\"\""
+msgstr ""
+
+msgid "Configuration for extensions that need to send email messages."
+msgstr ""
+
+msgid ""
+"``host``\n"
+"    Host name of mail server, e.g. \"mail.example.com\"."
+msgstr ""
+
+msgid ""
+"``port``\n"
+"    Optional. Port to connect to on mail server. Default: 25."
+msgstr ""
+
+msgid ""
+"``tls``\n"
+"    Optional. Method to enable TLS when connecting to mail server: "
+"starttls,\n"
+"    smtps or none. Default: none."
+msgstr ""
+
+msgid ""
+"``username``\n"
+"    Optional. User name for authenticating with the SMTP server.\n"
+"    Default: none."
+msgstr ""
+
+msgid ""
+"``password``\n"
+"    Optional. Password for authenticating with the SMTP server. If not\n"
+"    specified, interactive sessions will prompt the user for a\n"
+"    password; non-interactive sessions will fail. Default: none."
+msgstr ""
+
+msgid ""
+"``local_hostname``\n"
+"    Optional. It's the hostname that the sender can use to identify\n"
+"    itself to the MTA."
+msgstr ""
+
+msgid ""
+"\n"
+"``patch``\n"
+"\"\"\"\"\"\"\"\"\""
+msgstr ""
+
+msgid ""
+"Settings used when applying patches, for instance through the 'import'\n"
+"command or with Mercurial Queues extension."
+msgstr ""
+
+msgid ""
+"``eol``\n"
+"    When set to 'strict' patch content and patched files end of lines\n"
+"    are preserved. When set to ``lf`` or ``crlf``, both files end of\n"
+"    lines are ignored when patching and the result line endings are\n"
+"    normalized to either LF (Unix) or CRLF (Windows). When set to\n"
+"    ``auto``, end of lines are again ignored while patching but line\n"
+"    endings in patched files are normalized to their original setting\n"
+"    on a per-file basis. If target file does not exist or has no end\n"
+"    of line, patch line endings are preserved.\n"
+"    Default: strict."
+msgstr ""
+
+msgid ""
+"\n"
+"``paths``\n"
+"\"\"\"\"\"\"\"\"\""
+msgstr ""
+
+msgid ""
+"Assigns symbolic names to repositories. The left side is the\n"
+"symbolic name, and the right gives the directory or URL that is the\n"
+"location of the repository. Default paths can be declared by setting\n"
+"the following entries."
+msgstr ""
+
+msgid ""
+"``default``\n"
+"    Directory or URL to use when pulling if no source is specified.\n"
+"    Default is set to repository from which the current repository was\n"
+"    cloned."
+msgstr ""
+
+msgid ""
+"``default-push``\n"
+"    Optional. Directory or URL to use when pushing if no destination\n"
+"    is specified."
+msgstr ""
+
+msgid ""
+"\n"
+"``profiling``\n"
+"\"\"\"\"\"\"\"\"\"\"\"\"\""
+msgstr ""
+
+msgid ""
+"Specifies profiling format and file output. In this section\n"
+"description, 'profiling data' stands for the raw data collected\n"
+"during profiling, while 'profiling report' stands for a statistical\n"
+"text report generated from the profiling data. The profiling is done\n"
+"using lsprof."
+msgstr ""
+
+msgid ""
+"``format``\n"
+"    Profiling format.\n"
+"    Default: text."
+msgstr ""
+
+msgid ""
+"    ``text``\n"
+"      Generate a profiling report. When saving to a file, it should be\n"
+"      noted that only the report is saved, and the profiling data is\n"
+"      not kept.\n"
+"    ``kcachegrind``\n"
+"      Format profiling data for kcachegrind use: when saving to a\n"
+"      file, the generated file can directly be loaded into\n"
+"      kcachegrind."
+msgstr ""
+
+msgid ""
+"``output``\n"
+"    File path where profiling data or report should be saved. If the\n"
+"    file exists, it is replaced. Default: None, data is printed on\n"
+"    stderr"
+msgstr ""
+
+msgid ""
+"``server``\n"
+"\"\"\"\"\"\"\"\"\"\""
+msgstr ""
+
+msgid "Controls generic server settings."
+msgstr ""
+
+msgid ""
+"``uncompressed``\n"
+"    Whether to allow clients to clone a repository using the\n"
+"    uncompressed streaming protocol. This transfers about 40% more\n"
+"    data than a regular clone, but uses less memory and CPU on both\n"
+"    server and client. Over a LAN (100 Mbps or better) or a very fast\n"
+"    WAN, an uncompressed streaming clone is a lot faster (~10x) than a\n"
+"    regular clone. Over most WAN connections (anything slower than\n"
+"    about 6 Mbps), uncompressed streaming is slower, because of the\n"
+"    extra data transfer overhead. This mode will also temporarily hold\n"
+"    the write lock while determining what data to transfer.\n"
+"    Default is True."
+msgstr ""
+
+msgid ""
+"``validate``\n"
+"    Whether to validate the completeness of pushed changesets by\n"
+"    checking that all new file revisions specified in manifests are\n"
+"    present. Default is False."
+msgstr ""
+
+msgid ""
+"``subpaths``\n"
+"\"\"\"\"\"\"\"\"\"\"\"\""
+msgstr ""
+
+msgid "Defines subrepositories source locations rewriting rules of the form::"
+msgstr ""
+
+msgid "    <pattern> = <replacement>"
+msgstr ""
+
+msgid ""
+"Where ``pattern`` is a regular expression matching the source and\n"
+"``replacement`` is the replacement string used to rewrite it. Groups\n"
+"can be matched in ``pattern`` and referenced in ``replacements``. For\n"
+"instance::"
+msgstr ""
+
+msgid "    http://server/(.*)-hg/ = http://hg.server/\\1/"
+msgstr ""
+
+msgid "rewrites ``http://server/foo-hg/`` into ``http://hg.server/foo/``."
+msgstr ""
+
+msgid "All patterns are applied in definition order."
+msgstr ""
+
+msgid ""
+"``trusted``\n"
+"\"\"\"\"\"\"\"\"\"\"\""
+msgstr ""
+
+msgid ""
+"Mercurial will not use the settings in the\n"
+"``.hg/hgrc`` file from a repository if it doesn't belong to a trusted\n"
+"user or to a trusted group, as various hgrc features allow arbitrary\n"
+"commands to be run. This issue is often encountered when configuring\n"
+"hooks or extensions for shared repositories or servers. However,\n"
+"the web interface will use some safe settings from the ``[web]``\n"
+"section."
+msgstr ""
+
+msgid ""
+"This section specifies what users and groups are trusted. The\n"
+"current user is always trusted. To trust everybody, list a user or a\n"
+"group with name ``*``. These settings must be placed in an\n"
+"*already-trusted file* to take effect, such as ``$HOME/.hgrc`` of the\n"
+"user or service running Mercurial."
+msgstr ""
+
+msgid ""
+"``users``\n"
+"  Comma-separated list of trusted users."
+msgstr ""
+
+msgid ""
+"``groups``\n"
+"  Comma-separated list of trusted groups."
+msgstr ""
+
+msgid ""
+"\n"
+"``ui``\n"
+"\"\"\"\"\"\""
+msgstr ""
+
+msgid "User interface controls."
+msgstr ""
+
+msgid ""
+"``archivemeta``\n"
+"    Whether to include the .hg_archival.txt file containing meta data\n"
+"    (hashes for the repository base and for tip) in archives created\n"
+"    by the :hg:`archive` command or downloaded via hgweb.\n"
+"    Default is True."
+msgstr ""
+
+msgid ""
+"``askusername``\n"
+"    Whether to prompt for a username when committing. If True, and\n"
+"    neither ``$HGUSER`` nor ``$EMAIL`` has been specified, then the user "
+"will\n"
+"    be prompted to enter a username. If no username is entered, the\n"
+"    default ``USER@HOST`` is used instead.\n"
+"    Default is False."
+msgstr ""
+
+msgid ""
+"``commitsubrepos``\n"
+"    Whether to commit modified subrepositories when committing the\n"
+"    parent repository. If False and one subrepository has uncommitted\n"
+"    changes, abort the commit.\n"
+"    Default is True."
+msgstr ""
+
+msgid ""
+"``debug``\n"
+"    Print debugging information. True or False. Default is False."
+msgstr ""
+
+msgid ""
+"``editor``\n"
+"    The editor to use during a commit. Default is ``$EDITOR`` or ``vi``."
+msgstr ""
+
+msgid ""
+"``fallbackencoding``\n"
+"    Encoding to try if it's not possible to decode the changelog using\n"
+"    UTF-8. Default is ISO-8859-1."
+msgstr ""
+
+msgid ""
+"``ignore``\n"
+"    A file to read per-user ignore patterns from. This file should be\n"
+"    in the same format as a repository-wide .hgignore file. This\n"
+"    option supports hook syntax, so if you want to specify multiple\n"
+"    ignore files, you can do so by setting something like\n"
+"    ``ignore.other = ~/.hgignore2``. For details of the ignore file\n"
+"    format, see the |hgignore(5)|_ man page."
+msgstr ""
+
+msgid ""
+"``interactive``\n"
+"    Allow to prompt the user. True or False. Default is True."
+msgstr ""
+
+msgid ""
+"``logtemplate``\n"
+"    Template string for commands that print changesets."
+msgstr ""
+
+msgid ""
+"``merge``\n"
+"    The conflict resolution program to use during a manual merge.\n"
+"    For more information on merge tools see :hg:`help merge-tools`.\n"
+"    For configuring merge tools see the merge-tools_ section."
+msgstr ""
+
+msgid ""
+"``portablefilenames``\n"
+"    Check for portable filenames. Can be ``warn``, ``ignore`` or ``abort``.\n"
+"    Default is ``warn``.\n"
+"    If set to ``warn`` (or ``true``), a warning message is printed on POSIX\n"
+"    platforms, if a file with a non-portable filename is added (e.g. a file\n"
+"    with a name that can't be created on Windows because it contains "
+"reserved\n"
+"    parts like ``AUX``, reserved characters like ``:``, or would cause a "
+"case\n"
+"    collision with an existing file).\n"
+"    If set to ``ignore`` (or ``false``), no warning is printed.\n"
+"    If set to ``abort``, the command is aborted.\n"
+"    On Windows, this configuration option is ignored and the command aborted."
+msgstr ""
+
+msgid ""
+"``quiet``\n"
+"    Reduce the amount of output printed. True or False. Default is False."
+msgstr ""
+
+msgid ""
+"``remotecmd``\n"
+"    remote command to use for clone/push/pull operations. Default is ``hg``."
+msgstr ""
+
+msgid ""
+"``report_untrusted``\n"
+"    Warn if a ``.hg/hgrc`` file is ignored due to not being owned by a\n"
+"    trusted user or group. True or False. Default is True."
+msgstr ""
+
+msgid ""
+"``slash``\n"
+"    Display paths using a slash (``/``) as the path separator. This\n"
+"    only makes a difference on systems where the default path\n"
+"    separator is not the slash character (e.g. Windows uses the\n"
+"    backslash character (``\\``)).\n"
+"    Default is False."
+msgstr ""
+
+msgid ""
+"``ssh``\n"
+"    command to use for SSH connections. Default is ``ssh``."
+msgstr ""
+
+msgid ""
+"``strict``\n"
+"    Require exact command names, instead of allowing unambiguous\n"
+"    abbreviations. True or False. Default is False."
+msgstr ""
+
+msgid ""
+"``style``\n"
+"    Name of style to use for command output."
+msgstr ""
+
+msgid ""
+"``timeout``\n"
+"    The timeout used when a lock is held (in seconds), a negative value\n"
+"    means no timeout. Default is 600."
+msgstr ""
+
+msgid ""
+"``traceback``\n"
+"    Mercurial always prints a traceback when an unknown exception\n"
+"    occurs. Setting this to True will make Mercurial print a traceback\n"
+"    on all exceptions, even those recognized by Mercurial (such as\n"
+"    IOError or MemoryError). Default is False."
+msgstr ""
+
+msgid ""
+"``username``\n"
+"    The committer of a changeset created when running \"commit\".\n"
+"    Typically a person's name and email address, e.g. ``Fred Widget\n"
+"    <fred@example.com>``. Default is ``$EMAIL`` or ``username@hostname``. "
+"If\n"
+"    the username in hgrc is empty, it has to be specified manually or\n"
+"    in a different hgrc file (e.g. ``$HOME/.hgrc``, if the admin set\n"
+"    ``username =``  in the system hgrc). Environment variables in the\n"
+"    username are expanded."
+msgstr ""
+
+msgid ""
+"``verbose``\n"
+"    Increase the amount of output printed. True or False. Default is False."
+msgstr ""
+
+msgid ""
+"\n"
+"``web``\n"
+"\"\"\"\"\"\"\""
+msgstr ""
+
+msgid ""
+"Web interface configuration. The settings in this section apply to\n"
+"both the builtin webserver (started by :hg:`serve`) and the script you\n"
+"run through a webserver (``hgweb.cgi`` and the derivatives for FastCGI\n"
+"and WSGI)."
+msgstr ""
+
+msgid ""
+"The Mercurial webserver does no authentication (it does not prompt for\n"
+"usernames and passwords to validate *who* users are), but it does do\n"
+"authorization (it grants or denies access for *authenticated users*\n"
+"based on settings in this section). You must either configure your\n"
+"webserver to do authentication for you, or disable the authorization\n"
+"checks."
+msgstr ""
+
+msgid ""
+"For a quick setup in a trusted environment, e.g., a private LAN, where\n"
+"you want it to accept pushes from anybody, you can use the following\n"
+"command line::"
+msgstr ""
+
+msgid "    $ hg --config web.allow_push=* --config web.push_ssl=False serve"
+msgstr ""
+
+msgid ""
+"Note that this will allow anybody to push anything to the server and\n"
+"that this should not be used for public servers."
+msgstr ""
+
+msgid "The full set of options is:"
+msgstr "Setul complet de opțiuni este:"
+
+msgid ""
+"``accesslog``\n"
+"    Where to output the access log. Default is stdout."
+msgstr ""
+
+msgid ""
+"``address``\n"
+"    Interface address to bind to. Default is all."
+msgstr ""
+
+msgid ""
+"``allow_archive``\n"
+"    List of archive format (bz2, gz, zip) allowed for downloading.\n"
+"    Default is empty."
+msgstr ""
+
+msgid ""
+"``allowbz2``\n"
+"    (DEPRECATED) Whether to allow .tar.bz2 downloading of repository\n"
+"    revisions.\n"
+"    Default is False."
+msgstr ""
+
+msgid ""
+"``allowgz``\n"
+"    (DEPRECATED) Whether to allow .tar.gz downloading of repository\n"
+"    revisions.\n"
+"    Default is False."
+msgstr ""
+
+msgid ""
+"``allowpull``\n"
+"    Whether to allow pulling from the repository. Default is True."
+msgstr ""
+
+msgid ""
+"``allow_push``\n"
+"    Whether to allow pushing to the repository. If empty or not set,\n"
+"    push is not allowed. If the special value ``*``, any remote user can\n"
+"    push, including unauthenticated users. Otherwise, the remote user\n"
+"    must have been authenticated, and the authenticated user name must\n"
+"    be present in this list. The contents of the allow_push list are\n"
+"    examined after the deny_push list."
+msgstr ""
+
+msgid ""
+"``allow_read``\n"
+"    If the user has not already been denied repository access due to\n"
+"    the contents of deny_read, this list determines whether to grant\n"
+"    repository access to the user. If this list is not empty, and the\n"
+"    user is unauthenticated or not present in the list, then access is\n"
+"    denied for the user. If the list is empty or not set, then access\n"
+"    is permitted to all users by default. Setting allow_read to the\n"
+"    special value ``*`` is equivalent to it not being set (i.e. access\n"
+"    is permitted to all users). The contents of the allow_read list are\n"
+"    examined after the deny_read list."
+msgstr ""
+
+msgid ""
+"``allowzip``\n"
+"    (DEPRECATED) Whether to allow .zip downloading of repository\n"
+"    revisions. Default is False. This feature creates temporary files."
+msgstr ""
+
+msgid ""
+"``baseurl``\n"
+"    Base URL to use when publishing URLs in other locations, so\n"
+"    third-party tools like email notification hooks can construct\n"
+"    URLs. Example: ``http://hgserver/repos/``."
+msgstr ""
+
+msgid ""
+"``cacerts``\n"
+"    Path to file containing a list of PEM encoded certificate\n"
+"    authority certificates. Environment variables and ``~user``\n"
+"    constructs are expanded in the filename. If specified on the\n"
+"    client, then it will verify the identity of remote HTTPS servers\n"
+"    with these certificates. The form must be as follows::"
+msgstr ""
+
+msgid ""
+"        -----BEGIN CERTIFICATE-----\n"
+"        ... (certificate in base64 PEM encoding) ...\n"
+"        -----END CERTIFICATE-----\n"
+"        -----BEGIN CERTIFICATE-----\n"
+"        ... (certificate in base64 PEM encoding) ...\n"
+"        -----END CERTIFICATE-----"
+msgstr ""
+
+msgid ""
+"    This feature is only supported when using Python 2.6 or later. If you "
+"wish\n"
+"    to use it with earlier versions of Python, install the backported\n"
+"    version of the ssl library that is available from\n"
+"    ``http://pypi.python.org``."
+msgstr ""
+
+msgid ""
+"    You can use OpenSSL's CA certificate file if your platform has one.\n"
+"    On most Linux systems this will be ``/etc/ssl/certs/ca-certificates."
+"crt``.\n"
+"    Otherwise you will have to generate this file manually."
+msgstr ""
+
+msgid ""
+"    To disable SSL verification temporarily, specify ``--insecure`` from\n"
+"    command line."
+msgstr ""
+
+msgid ""
+"``cache``\n"
+"    Whether to support caching in hgweb. Defaults to True."
+msgstr ""
+
+msgid ""
+"``contact``\n"
+"    Name or email address of the person in charge of the repository.\n"
+"    Defaults to ui.username or ``$EMAIL`` or \"unknown\" if unset or empty."
+msgstr ""
+
+msgid ""
+"``deny_push``\n"
+"    Whether to deny pushing to the repository. If empty or not set,\n"
+"    push is not denied. If the special value ``*``, all remote users are\n"
+"    denied push. Otherwise, unauthenticated users are all denied, and\n"
+"    any authenticated user name present in this list is also denied. The\n"
+"    contents of the deny_push list are examined before the allow_push list."
+msgstr ""
+
+msgid ""
+"``deny_read``\n"
+"    Whether to deny reading/viewing of the repository. If this list is\n"
+"    not empty, unauthenticated users are all denied, and any\n"
+"    authenticated user name present in this list is also denied access to\n"
+"    the repository. If set to the special value ``*``, all remote users\n"
+"    are denied access (rarely needed ;). If deny_read is empty or not set,\n"
+"    the determination of repository access depends on the presence and\n"
+"    content of the allow_read list (see description). If both\n"
+"    deny_read and allow_read are empty or not set, then access is\n"
+"    permitted to all users by default. If the repository is being\n"
+"    served via hgwebdir, denied users will not be able to see it in\n"
+"    the list of repositories. The contents of the deny_read list have\n"
+"    priority over (are examined before) the contents of the allow_read\n"
+"    list."
+msgstr ""
+
+msgid ""
+"``descend``\n"
+"    hgwebdir indexes will not descend into subdirectories. Only "
+"repositories\n"
+"    directly in the current path will be shown (other repositories are "
+"still\n"
+"    available from the index corresponding to their containing path)."
+msgstr ""
+
+msgid ""
+"``description``\n"
+"    Textual description of the repository's purpose or contents.\n"
+"    Default is \"unknown\"."
+msgstr ""
+
+msgid ""
+"``encoding``\n"
+"    Character encoding name. Default is the current locale charset.\n"
+"    Example: \"UTF-8\""
+msgstr ""
+
+msgid ""
+"``errorlog``\n"
+"    Where to output the error log. Default is stderr."
+msgstr ""
+
+msgid ""
+"``hidden``\n"
+"    Whether to hide the repository in the hgwebdir index.\n"
+"    Default is False."
+msgstr ""
+
+msgid ""
+"``ipv6``\n"
+"    Whether to use IPv6. Default is False."
+msgstr ""
+
+msgid ""
+"``logourl``\n"
+"    Base URL to use for logos. If unset, ``http://mercurial.selenic.com/``\n"
+"    will be used."
+msgstr ""
+
+msgid ""
+"``name``\n"
+"    Repository name to use in the web interface. Default is current\n"
+"    working directory."
+msgstr ""
+
+msgid ""
+"``maxchanges``\n"
+"    Maximum number of changes to list on the changelog. Default is 10."
+msgstr ""
+
+msgid ""
+"``maxfiles``\n"
+"    Maximum number of files to list per changeset. Default is 10."
+msgstr ""
+
+msgid ""
+"``port``\n"
+"    Port to listen on. Default is 8000."
+msgstr ""
+"``port``\n"
+"    Portul pe care se va asculta (implicit: 8000)"
+
+msgid ""
+"``prefix``\n"
+"    Prefix path to serve from. Default is '' (server root)."
+msgstr ""
+
+msgid ""
+"``push_ssl``\n"
+"    Whether to require that inbound pushes be transported over SSL to\n"
+"    prevent password sniffing. Default is True."
+msgstr ""
+
+msgid ""
+"``staticurl``\n"
+"    Base URL to use for static files. If unset, static files (e.g. the\n"
+"    hgicon.png favicon) will be served by the CGI script itself. Use\n"
+"    this setting to serve them directly with the HTTP server.\n"
+"    Example: ``http://hgserver/static/``."
+msgstr ""
+
+msgid ""
+"``stripes``\n"
+"    How many lines a \"zebra stripe\" should span in multiline output.\n"
+"    Default is 1; set to 0 to disable."
+msgstr ""
+
+msgid ""
+"``style``\n"
+"    Which template map style to use."
+msgstr ""
+
+msgid ""
+"``templates``\n"
+"    Where to find the HTML templates. Default is install path.\n"
 msgstr ""
 
 msgid "Some commands allow the user to specify a date, e.g.:"
@@ -9733,20 +12381,20 @@
 msgstr ""
 
 msgid ""
-"This is the internal representation format for dates. unixtime is the\n"
-"number of seconds since the epoch (1970-01-01 00:00 UTC). offset is\n"
-"the offset of the local timezone, in seconds west of UTC (negative if\n"
-"the timezone is east of UTC)."
+"This is the internal representation format for dates. The first number\n"
+"is the number of seconds since the epoch (1970-01-01 00:00 UTC). The\n"
+"second is the offset of the local timezone, in seconds west of UTC\n"
+"(negative if the timezone is east of UTC)."
 msgstr ""
 
 msgid "The log command also accepts date ranges:"
 msgstr ""
 
 msgid ""
-"- ``<{datetime}`` - at or before a given date/time\n"
-"- ``>{datetime}`` - on or after a given date/time\n"
-"- ``{datetime} to {datetime}`` - a date range, inclusive\n"
-"- ``-{days}`` - within a given number of days of today\n"
+"- ``<DATE`` - at or before a given date/time\n"
+"- ``>DATE`` - on or after a given date/time\n"
+"- ``DATE to DATE`` - a date range, inclusive\n"
+"- ``-DAYS`` - within a given number of days of today\n"
 msgstr ""
 
 msgid ""
@@ -9787,8 +12435,8 @@
 msgid ""
 "To make Mercurial produce the git extended diff format, use the --git\n"
 "option available for many commands, or set 'git = True' in the [diff]\n"
-"section of your hgrc. You do not need to set this option when\n"
-"importing diffs in this format or using them in the mq extension.\n"
+"section of your configuration file. You do not need to set this option\n"
+"when importing diffs in this format or using them in the mq extension.\n"
 msgstr ""
 
 msgid ""
@@ -9805,7 +12453,7 @@
 "    This is the name of the editor to run when committing. See EDITOR."
 msgstr ""
 
-msgid "    (deprecated, use .hgrc)"
+msgid "    (deprecated, use configuration file)"
 msgstr ""
 
 msgid ""
@@ -9827,6 +12475,15 @@
 msgstr ""
 
 msgid ""
+"HGENCODINGAMBIGUOUS\n"
+"    This sets Mercurial's behavior for handling characters with\n"
+"    \"ambiguous\" widths like accented Latin characters with East Asian\n"
+"    fonts. By default, Mercurial assumes ambiguous characters are\n"
+"    narrow, set this variable to \"wide\" if such characters cause\n"
+"    formatting problems."
+msgstr ""
+
+msgid ""
 "HGMERGE\n"
 "    An executable to use for resolving merge conflicts. The program\n"
 "    will be executed with three arguments: local file, remote file,\n"
@@ -9835,10 +12492,10 @@
 
 msgid ""
 "HGRCPATH\n"
-"    A list of files or directories to search for hgrc files. Item\n"
-"    separator is \":\" on Unix, \";\" on Windows. If HGRCPATH is not set,\n"
-"    platform default search path is used. If empty, only the .hg/hgrc\n"
-"    from the current repository is read."
+"    A list of files or directories to search for configuration\n"
+"    files. Item separator is \":\" on Unix, \";\" on Windows. If HGRCPATH\n"
+"    is not set, platform default search path is used. If empty, only\n"
+"    the .hg/hgrc from the current repository is read."
 msgstr ""
 
 msgid "    For each element in HGRCPATH:"
@@ -9851,9 +12508,9 @@
 
 msgid ""
 "HGPLAIN\n"
-"    When set, this disables any options in .hgrc that might change\n"
-"    Mercurial's default output. This includes encoding, defaults,\n"
-"    verbose mode, debug mode, quiet mode, tracebacks, and\n"
+"    When set, this disables any configuration settings that might\n"
+"    change Mercurial's default output. This includes encoding,\n"
+"    defaults, verbose mode, debug mode, quiet mode, tracebacks, and\n"
 "    localization. This can be useful when scripting against Mercurial\n"
 "    in the face of existing user configuration."
 msgstr ""
@@ -9864,6 +12521,18 @@
 msgstr ""
 
 msgid ""
+"HGPLAINEXCEPT\n"
+"    This is a comma-separated list of features to preserve when\n"
+"    HGPLAIN is enabled. Currently the only value supported is \"i18n\",\n"
+"    which preserves internationalization in plain mode."
+msgstr ""
+
+msgid ""
+"    Setting HGPLAINEXCEPT to anything (even an empty string) will\n"
+"    enable plain mode."
+msgstr ""
+
+msgid ""
 "HGUSER\n"
 "    This is the string used as the author of a commit. If not set,\n"
 "    available values will be considered in this order:"
@@ -9871,7 +12540,7 @@
 
 msgid ""
 "    - HGUSER (deprecated)\n"
-"    - hgrc files from the HGRCPATH\n"
+"    - configuration files from the HGRCPATH\n"
 "    - EMAIL\n"
 "    - interactive prompt\n"
 "    - LOGNAME (with ``@hostname`` appended)"
@@ -9926,9 +12595,9 @@
 msgstr ""
 
 msgid ""
-"To enable the \"foo\" extension, either shipped with Mercurial or in\n"
-"the Python search path, create an entry for it in your hgrc, like\n"
-"this::"
+"To enable the \"foo\" extension, either shipped with Mercurial or in the\n"
+"Python search path, create an entry for it in your configuration file,\n"
+"like this::"
 msgstr ""
 
 msgid ""
@@ -9945,8 +12614,8 @@
 msgstr ""
 
 msgid ""
-"To explicitly disable an extension enabled in an hgrc of broader\n"
-"scope, prepend its path with !::"
+"To explicitly disable an extension enabled in a configuration file of\n"
+"broader scope, prepend its path with !::"
 msgstr ""
 
 msgid ""
@@ -10485,6 +13154,125 @@
 msgstr ""
 
 msgid ""
+"Synopsis\n"
+"--------"
+msgstr ""
+
+msgid ""
+"The Mercurial system uses a file called ``.hgignore`` in the root\n"
+"directory of a repository to control its behavior when it searches\n"
+"for files that it is not currently tracking."
+msgstr ""
+
+msgid ""
+"Description\n"
+"-----------"
+msgstr ""
+"Descriere\n"
+"---------"
+
+msgid ""
+"The working directory of a Mercurial repository will often contain\n"
+"files that should not be tracked by Mercurial. These include backup\n"
+"files created by editors and build products created by compilers.\n"
+"These files can be ignored by listing them in a ``.hgignore`` file in\n"
+"the root of the working directory. The ``.hgignore`` file must be\n"
+"created manually. It is typically put under version control, so that\n"
+"the settings will propagate to other repositories with push and pull."
+msgstr ""
+
+msgid ""
+"An untracked file is ignored if its path relative to the repository\n"
+"root directory, or any prefix path of that path, is matched against\n"
+"any pattern in ``.hgignore``."
+msgstr ""
+
+msgid ""
+"For example, say we have an untracked file, ``file.c``, at\n"
+"``a/b/file.c`` inside our repository. Mercurial will ignore ``file.c``\n"
+"if any pattern in ``.hgignore`` matches ``a/b/file.c``, ``a/b`` or ``a``."
+msgstr ""
+
+msgid ""
+"In addition, a Mercurial configuration file can reference a set of\n"
+"per-user or global ignore files. See the\n"
+"``http://www.selenic.com/mercurial/hgrc.5.html`` man page for details\n"
+"of how to configure these files. Look for the \"ignore\" entry in the\n"
+"\"ui\" section."
+msgstr ""
+
+msgid ""
+"To control Mercurial's handling of files that it manages, see the\n"
+"``http://www.selenic.com/mercurial/hg.1.html`` man page. Look for\n"
+"the ``-I`` and ``-X`` options."
+msgstr ""
+
+msgid ""
+"An ignore file is a plain text file consisting of a list of patterns,\n"
+"with one pattern per line. Empty lines are skipped. The ``#``\n"
+"character is treated as a comment character, and the ``\\`` character\n"
+"is treated as an escape character."
+msgstr ""
+
+msgid ""
+"Mercurial supports several pattern syntaxes. The default syntax used\n"
+"is Python/Perl-style regular expressions."
+msgstr ""
+
+msgid "To change the syntax used, use a line of the following form::"
+msgstr ""
+
+msgid "  syntax: NAME"
+msgstr ""
+
+msgid "where ``NAME`` is one of the following:"
+msgstr ""
+
+msgid ""
+"``regexp``\n"
+"  Regular expression, Python/Perl syntax.\n"
+"``glob``\n"
+"  Shell-style glob."
+msgstr ""
+
+msgid ""
+"The chosen syntax stays in effect when parsing all patterns that\n"
+"follow, until another syntax is selected."
+msgstr ""
+
+msgid ""
+"Neither glob nor regexp patterns are rooted. A glob-syntax pattern of\n"
+"the form ``*.c`` will match a file ending in ``.c`` in any directory,\n"
+"and a regexp pattern of the form ``\\.c$`` will do the same. To root a\n"
+"regexp pattern, start it with ``^``."
+msgstr ""
+
+msgid ""
+"Example\n"
+"-------"
+msgstr ""
+
+msgid "Here is an example ignore file. ::"
+msgstr ""
+
+msgid ""
+"  # use glob syntax.\n"
+"  syntax: glob"
+msgstr ""
+
+msgid ""
+"  *.elc\n"
+"  *.pyc\n"
+"  *~"
+msgstr ""
+
+msgid ""
+"  # switch to regexp syntax.\n"
+"  syntax: regexp\n"
+"  ^\\.pc/\n"
+msgstr ""
+
+msgid ""
 "Mercurial's internal web server, hgweb, can serve either a single\n"
 "repository, or a collection of them. In the latter case, a special\n"
 "configuration file can be used to specify the repository paths to use\n"
@@ -10492,8 +13280,8 @@
 msgstr ""
 
 msgid ""
-"This file uses the same syntax as hgrc configuration files, but only\n"
-"the following sections are recognized:"
+"This file uses the same syntax as other Mercurial configuration files,\n"
+"but only the following sections are recognized:"
 msgstr ""
 
 msgid ""
@@ -10504,7 +13292,8 @@
 
 msgid ""
 "The ``web`` section can specify all the settings described in the web\n"
-"section of the hgrc documentation."
+"section of the hgrc(5) documentation. See :hg:`help config` for\n"
+"information on where to find the manual page."
 msgstr ""
 
 msgid ""
@@ -10552,6 +13341,182 @@
 "``bar`` and ``quux/baz`` respectively.\n"
 msgstr ""
 
+msgid "To merge files Mercurial uses merge tools."
+msgstr ""
+
+msgid ""
+"A merge tool combines two different versions of a file into a merged\n"
+"file. Merge tools are given the two files and the greatest common\n"
+"ancestor of the two file versions, so they can determine the changes\n"
+"made on both branches."
+msgstr ""
+
+msgid ""
+"Merge tools are used both for :hg:`resolve`, :hg:`merge`, :hg:`update`,\n"
+":hg:`backout` and in several extensions."
+msgstr ""
+
+msgid ""
+"Usually, the merge tool tries to automatically reconcile the files by\n"
+"combining all non-overlapping changes that occurred separately in\n"
+"the two different evolutions of the same initial base file. Furthermore, "
+"some\n"
+"interactive merge programs make it easier to manually resolve\n"
+"conflicting merges, either in a graphical way, or by inserting some\n"
+"conflict markers. Mercurial does not include any interactive merge\n"
+"programs but relies on external tools for that."
+msgstr ""
+
+msgid ""
+"Available merge tools\n"
+"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\""
+msgstr ""
+
+msgid ""
+"External merge tools and their properties are configured in the\n"
+"merge-tools configuration section - see hgrc(5) - but they can often just\n"
+"be named by their executable."
+msgstr ""
+
+msgid ""
+"A merge tool is generally usable if its executable can be found on the\n"
+"system and if it can handle the merge. The executable is found if it\n"
+"is an absolute or relative executable path or the name of an\n"
+"application in the executable search path. The tool is assumed to be\n"
+"able to handle the merge if it can handle symlinks if the file is a\n"
+"symlink, if it can handle binary files if the file is binary, and if a\n"
+"GUI is available if the tool requires a GUI."
+msgstr ""
+
+msgid ""
+"There are some internal merge tools which can be used. The internal\n"
+"merge tools are:"
+msgstr ""
+
+msgid ""
+"``internal:merge``\n"
+"   Uses the internal non-interactive simple merge algorithm for merging\n"
+"   files. It will fail if there are any conflicts and leave markers in\n"
+"   the partially merged file."
+msgstr ""
+
+msgid ""
+"``internal:fail``\n"
+"   Rather than attempting to merge files that were modified on both\n"
+"   branches, it marks them as unresolved. The resolve command must be\n"
+"   used to resolve these conflicts."
+msgstr ""
+
+msgid ""
+"``internal:local``\n"
+"   Uses the local version of files as the merged version."
+msgstr ""
+
+msgid ""
+"``internal:other``\n"
+"   Uses the other version of files as the merged version."
+msgstr ""
+
+msgid ""
+"``internal:prompt``\n"
+"   Asks the user which of the local or the other version to keep as\n"
+"   the merged version."
+msgstr ""
+
+msgid ""
+"``internal:dump``\n"
+"   Creates three versions of the files to merge, containing the\n"
+"   contents of local, other and base. These files can then be used to\n"
+"   perform a merge manually. If the file to be merged is named\n"
+"   ``a.txt``, these files will accordingly be named ``a.txt.local``,\n"
+"   ``a.txt.other`` and ``a.txt.base`` and they will be placed in the\n"
+"   same directory as ``a.txt``."
+msgstr ""
+
+msgid ""
+"Internal tools are always available and do not require a GUI but will by "
+"default\n"
+"not handle symlinks or binary files."
+msgstr ""
+
+msgid ""
+"Choosing a merge tool\n"
+"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\""
+msgstr ""
+
+msgid "Mercurial uses these rules when deciding which merge tool to use:"
+msgstr ""
+
+msgid ""
+"1. If a tool has been specified with the --tool option to merge or resolve, "
+"it\n"
+"   is used.  If it is the name of a tool in the merge-tools configuration, "
+"its\n"
+"   configuration is used. Otherwise the specified tool must be executable "
+"by\n"
+"   the shell."
+msgstr ""
+
+msgid ""
+"2. If the ``HGMERGE`` environment variable is present, its value is used "
+"and\n"
+"   must be executable by the shell."
+msgstr ""
+
+msgid ""
+"3. If the filename of the file to be merged matches any of the patterns in "
+"the\n"
+"   merge-patterns configuration section, the first usable merge tool\n"
+"   corresponding to a matching pattern is used. Here, binary capabilities of "
+"the\n"
+"   merge tool are not considered."
+msgstr ""
+
+msgid ""
+"4. If ui.merge is set it will be considered next. If the value is not the "
+"name\n"
+"   of a configured tool, the specified value is used and must be executable "
+"by\n"
+"   the shell. Otherwise the named tool is used if it is usable."
+msgstr ""
+
+msgid ""
+"5. If any usable merge tools are present in the merge-tools configuration\n"
+"   section, the one with the highest priority is used."
+msgstr ""
+
+msgid ""
+"6. If a program named ``hgmerge`` can be found on the system, it is used - "
+"but\n"
+"   it will by default not be used for symlinks and binary files."
+msgstr ""
+
+msgid ""
+"7. If the file to be merged is not binary and is not a symlink, then\n"
+"   ``internal:merge`` is used."
+msgstr ""
+
+msgid "8. The merge of the file fails and must be resolved before commit."
+msgstr ""
+
+msgid ""
+".. note::\n"
+"   After selecting a merge program, Mercurial will by default attempt\n"
+"   to merge the files using a simple merge algorithm first. Only if it "
+"doesn't\n"
+"   succeed because of conflicting changes Mercurial will actually execute "
+"the\n"
+"   merge program. Whether to use the simple merge algorithm first can be\n"
+"   controlled by the premerge setting of the merge tool. Premerge is enabled "
+"by\n"
+"   default unless the file is binary or a symlink."
+msgstr ""
+
+msgid ""
+"See the merge-tools and ui sections of hgrc(5) for details on the\n"
+"configuration of merge tools.\n"
+msgstr ""
+
 msgid ""
 "When Mercurial accepts more than one revision, they may be specified\n"
 "individually, or provided as a topologically continuous range,\n"
@@ -10608,6 +13573,13 @@
 "Regexp pattern matching is anchored at the root of the repository."
 msgstr ""
 
+msgid ""
+"To read name patterns from a file, use ``listfile:`` or ``listfile0:``.\n"
+"The latter expects null delimited patterns while the former expects line\n"
+"feeds. Each string read from the file is itself treated as a file\n"
+"pattern."
+msgstr ""
+
 msgid "Plain examples::"
 msgstr ""
 
@@ -10633,8 +13605,15 @@
 msgid "Regexp examples::"
 msgstr ""
 
-msgid ""
-"  re:.*\\.c$      any name ending in \".c\", anywhere in the repository\n"
+msgid "  re:.*\\.c$      any name ending in \".c\", anywhere in the repository"
+msgstr ""
+
+msgid "File examples::"
+msgstr ""
+
+msgid ""
+"  listfile:list.txt  read list from list.txt with one file pattern per line\n"
+"  listfile0:list.txt read list from list.txt with null byte delimiters\n"
 msgstr ""
 
 msgid "Mercurial supports several ways to specify individual revisions."
@@ -10696,8 +13675,13 @@
 "Identifiers such as branch names must be quoted with single or double\n"
 "quotes if they contain characters outside of\n"
 "``[._a-zA-Z0-9\\x80-\\xff]`` or if they match one of the predefined\n"
-"predicates. Special characters can be used in quoted identifiers by\n"
-"escaping them, e.g., ``\\n`` is interpreted as a newline."
+"predicates."
+msgstr ""
+
+msgid ""
+"Special characters can be used in quoted identifiers by escaping them,\n"
+"e.g., ``\\n`` is interpreted as a newline. To prevent them from being\n"
+"interpreted, strings can be prefixed with ``r``, e.g. ``r'...'``."
 msgstr ""
 
 msgid "There is a single prefix operator:"
@@ -10742,193 +13726,63 @@
 
 msgid ""
 "``x - y``\n"
-"  Changesets in x but not in y."
-msgstr ""
-
-msgid "The following predicates are supported:"
-msgstr ""
-
-msgid ""
-"``adds(pattern)``\n"
-"  Changesets that add a file matching pattern."
-msgstr ""
-
-msgid ""
-"``all()``\n"
-"  All changesets, the same as ``0:tip``."
-msgstr ""
-
-msgid ""
-"``ancestor(single, single)``\n"
-"  Greatest common ancestor of the two changesets."
-msgstr ""
-
-msgid ""
-"``ancestors(set)``\n"
-"  Changesets that are ancestors of a changeset in set."
-msgstr ""
-
-msgid ""
-"``author(string)``\n"
-"  Alias for ``user(string)``."
-msgstr ""
-
-msgid ""
-"``branch(set)``\n"
-"  All changesets belonging to the branches of changesets in set."
-msgstr ""
-
-msgid ""
-"``children(set)``\n"
-"  Child changesets of changesets in set."
-msgstr ""
-
-msgid ""
-"``closed()``\n"
-"  Changeset is closed."
-msgstr ""
-
-msgid ""
-"``contains(pattern)``\n"
-"  Revision contains pattern."
-msgstr ""
-
-msgid ""
-"``date(interval)``\n"
-"  Changesets within the interval, see :hg:`help dates`."
-msgstr ""
-
-msgid ""
-"``descendants(set)``\n"
-"  Changesets which are descendants of changesets in set."
-msgstr ""
-
-msgid ""
-"``file(pattern)``\n"
-"  Changesets affecting files matched by pattern."
-msgstr ""
-
-msgid ""
-"``follow()``\n"
-"  An alias for ``::.`` (ancestors of the working copy's first parent)."
-msgstr ""
-
-msgid ""
-"``grep(regex)``\n"
-"  Like ``keyword(string)`` but accepts a regex."
-msgstr ""
-
-msgid ""
-"``head()``\n"
-"  Changeset is a head."
-msgstr ""
-
-msgid ""
-"``heads(set)``\n"
-"  Members of set with no children in set."
-msgstr ""
-
-msgid ""
-"``keyword(string)``\n"
-"  Search commit message, user name, and names of changed files for\n"
-"  string."
-msgstr ""
-
-msgid ""
-"``limit(set, n)``\n"
-"  First n members of set."
-msgstr ""
-
-msgid ""
-"``max(set)``\n"
-"  Changeset with highest revision number in set."
-msgstr ""
-
-msgid ""
-"``min(set)``\n"
-"  Changeset with lowest revision number in set."
-msgstr ""
-
-msgid ""
-"``merge()``\n"
-"  Changeset is a merge changeset."
-msgstr ""
-
-msgid ""
-"``modifies(pattern)``\n"
-"  Changesets modifying files matched by pattern."
-msgstr ""
-
-msgid ""
-"``outgoing([path])``\n"
-"  Changesets not found in the specified destination repository, or the\n"
-"  default push location."
-msgstr ""
-"``outgoing([cale])``\n"
-"  Nu s-au găsit seturi de modificări în depozitul destinație specificat\n"
-"  sau în amplasarea implicită pentru `push`."
-
-msgid ""
-"``p1(set)``\n"
-"  First parent of changesets in set."
-msgstr ""
-
-msgid ""
-"``p2(set)``\n"
-"  Second parent of changesets in set."
-msgstr ""
-
-msgid ""
-"``parents(set)``\n"
-"  The set of all parents for all changesets in set."
-msgstr ""
-
-msgid ""
-"``present(set)``\n"
-"  An empty set, if any revision in set isn't found; otherwise,\n"
-"  all revisions in set."
-msgstr ""
-
-msgid ""
-"``removes(pattern)``\n"
-"  Changesets which remove files matching pattern."
-msgstr ""
-
-msgid ""
-"``reverse(set)``\n"
-"  Reverse order of set."
-msgstr ""
-
-msgid ""
-"``roots(set)``\n"
-"  Changesets with no parent changeset in set."
-msgstr ""
-
-msgid ""
-"``sort(set[, [-]key...])``\n"
-"  Sort set by keys. The default sort order is ascending, specify a key\n"
-"  as ``-key`` to sort in descending order."
-msgstr ""
-
-msgid "  The keys can be:"
-msgstr ""
-
-msgid ""
-"  - ``rev`` for the revision number,\n"
-"  - ``branch`` for the branch name,\n"
-"  - ``desc`` for the commit message (description),\n"
-"  - ``user`` for user name (``author`` can be used as an alias),\n"
-"  - ``date`` for the commit date"
-msgstr ""
-
-msgid ""
-"``tagged()``\n"
-"  Changeset is tagged."
-msgstr ""
-
-msgid ""
-"``user(string)``\n"
-"  User name is string."
+"  Changesets in x but not in y.\n"
+"  \n"
+"``x^n``\n"
+"  The nth parent of x, n == 0, 1, or 2.\n"
+"  For n == 0, x; for n == 1, the first parent of each changeset in x;\n"
+"  for n == 2, the second parent of changeset in x."
+msgstr ""
+
+msgid ""
+"``x~n``\n"
+"  The nth first ancestor of x; ``x~0`` is x; ``x~3`` is ``x^^^``."
+msgstr ""
+
+msgid "There is a single postfix operator:"
+msgstr ""
+
+msgid ""
+"``x^``\n"
+"  Equivalent to ``x^1``, the first parent of each changeset in x."
+msgstr ""
+
+msgid ""
+"\n"
+"The following predicates are supported:"
+msgstr ""
+
+msgid ".. predicatesmarker"
+msgstr ""
+
+msgid ""
+"New predicates (known as \"aliases\") can be defined, using any combination "
+"of\n"
+"existing predicates or other aliases. An alias definition looks like::"
+msgstr ""
+
+msgid "  <alias> = <definition>"
+msgstr ""
+
+msgid ""
+"in the ``revsetalias`` section of ``.hgrc``. Arguments of the form `$1`, `"
+"$2`,\n"
+"etc. are substituted from the alias into the definition."
+msgstr ""
+
+msgid "For example,"
+msgstr ""
+
+msgid ""
+"  [revsetalias]\n"
+"  h = heads()\n"
+"  d($1) = sort($1, date)\n"
+"  rs($1, $2) = reverse(sort($1, $2))"
+msgstr ""
+
+msgid ""
+"defines three aliases, ``h``, ``d``, and ``rs``. ``rs(0:tip, author)`` is\n"
+"exactly equivalent to ``reverse(sort(0:tip, author))``."
 msgstr ""
 
 msgid "Command line equivalents for :hg:`log`::"
@@ -10945,15 +13799,244 @@
 "  -l x  ->  limit(expr, x)"
 msgstr ""
 
-msgid "Some sample queries::"
-msgstr ""
-
-msgid ""
-"  hg log -r 'branch(default)'\n"
-"  hg log -r 'branch(default) and 1.5:: and not merge()'\n"
-"  hg log -r '1.3::1.5 and keyword(bug) and file(\"hgext/*\")'\n"
-"  hg log -r 'sort(date(\"May 2008\"), user)'\n"
-"  hg log -r '(keyword(bug) or keyword(issue)) and not ancestors(tagged())'\n"
+msgid "Some sample queries:"
+msgstr ""
+
+msgid "- Changesets on the default branch::"
+msgstr "- Seturi de modificări pe ramura curentă::"
+
+msgid "    hg log -r \"branch(default)\""
+msgstr ""
+
+msgid "- Changesets on the default branch since tag 1.5 (excluding merges)::"
+msgstr ""
+
+msgid "    hg log -r \"branch(default) and 1.5:: and not merge()\""
+msgstr ""
+
+msgid "- Open branch heads::"
+msgstr "- Capete de ramură deschise::"
+
+msgid "    hg log -r \"head() and not closed()\""
+msgstr ""
+
+msgid ""
+"- Changesets between tags 1.3 and 1.5 mentioning \"bug\" that affect\n"
+"  ``hgext/*``::"
+msgstr ""
+
+msgid "    hg log -r \"1.3::1.5 and keyword(bug) and file('hgext/*')\""
+msgstr ""
+
+msgid "- Changesets committed in May 2008, sorted by user::"
+msgstr ""
+
+msgid "    hg log -r \"sort(date('May 2008'), user)\""
+msgstr ""
+
+msgid ""
+"- Changesets mentioning \"bug\" or \"issue\" that are not in a tagged\n"
+"  release::"
+msgstr ""
+
+msgid ""
+"    hg log -r \"(keyword(bug) or keyword(issue)) and not ancestors(tagged())"
+"\"\n"
+msgstr ""
+
+msgid ""
+"Subrepositories let you nest external repositories or projects into a\n"
+"parent Mercurial repository, and make commands operate on them as a\n"
+"group. External Mercurial and Subversion projects are currently\n"
+"supported."
+msgstr ""
+
+msgid "Subrepositories are made of three components:"
+msgstr ""
+
+msgid ""
+"1. Nested repository checkouts. They can appear anywhere in the\n"
+"   parent working directory, and are Mercurial clones or Subversion\n"
+"   checkouts."
+msgstr ""
+
+msgid ""
+"2. Nested repository references. They are defined in ``.hgsub`` and\n"
+"   tell where the subrepository checkouts come from. Mercurial\n"
+"   subrepositories are referenced like:"
+msgstr ""
+
+msgid "     path/to/nested = https://example.com/nested/repo/path"
+msgstr ""
+
+msgid ""
+"   where ``path/to/nested`` is the checkout location relatively to the\n"
+"   parent Mercurial root, and ``https://example.com/nested/repo/path``\n"
+"   is the source repository path. The source can also reference a\n"
+"   filesystem path. Subversion repositories are defined with:"
+msgstr ""
+
+msgid "     path/to/nested = [svn]https://example.com/nested/trunk/path"
+msgstr ""
+
+msgid ""
+"   Note that ``.hgsub`` does not exist by default in Mercurial\n"
+"   repositories, you have to create and add it to the parent\n"
+"   repository before using subrepositories."
+msgstr ""
+
+msgid ""
+"3. Nested repository states. They are defined in ``.hgsubstate`` and\n"
+"   capture whatever information is required to restore the\n"
+"   subrepositories to the state they were committed in a parent\n"
+"   repository changeset. Mercurial automatically record the nested\n"
+"   repositories states when committing in the parent repository."
+msgstr ""
+
+msgid ""
+"   .. note::\n"
+"      The ``.hgsubstate`` file should not be edited manually."
+msgstr ""
+
+msgid ""
+"\n"
+"Adding a Subrepository\n"
+"----------------------"
+msgstr ""
+
+msgid ""
+"If ``.hgsub`` does not exist, create it and add it to the parent\n"
+"repository. Clone or checkout the external projects where you want it\n"
+"to live in the parent repository. Edit ``.hgsub`` and add the\n"
+"subrepository entry as described above. At this point, the\n"
+"subrepository is tracked and the next commit will record its state in\n"
+"``.hgsubstate`` and bind it to the committed changeset."
+msgstr ""
+
+msgid ""
+"Synchronizing a Subrepository\n"
+"-----------------------------"
+msgstr ""
+"Sincronizarea unui subdepozit\n"
+"-----------------------------"
+
+msgid ""
+"Subrepos do not automatically track the latest changeset of their\n"
+"sources. Instead, they are updated to the changeset that corresponds\n"
+"with the changeset checked out in the top-level changeset. This is so\n"
+"developers always get a consistent set of compatible code and\n"
+"libraries when they update."
+msgstr ""
+
+msgid ""
+"Thus, updating subrepos is a manual process. Simply check out target\n"
+"subrepo at the desired revision, test in the top-level repo, then\n"
+"commit in the parent repository to record the new combination."
+msgstr ""
+
+msgid ""
+"Deleting a Subrepository\n"
+"------------------------"
+msgstr ""
+"Ștergerea unui subdepozit\n"
+"-------------------------"
+
+msgid ""
+"To remove a subrepository from the parent repository, delete its\n"
+"reference from ``.hgsub``, then remove its files."
+msgstr ""
+
+msgid ""
+"Interaction with Mercurial Commands\n"
+"-----------------------------------"
+msgstr ""
+"Interacțiunea cu comenzile Mercurial\n"
+"------------------------------------"
+
+msgid ""
+":add: add does not recurse in subrepos unless -S/--subrepos is\n"
+"    specified. Subversion subrepositories are currently silently\n"
+"    ignored."
+msgstr ""
+
+msgid ""
+":archive: archive does not recurse in subrepositories unless\n"
+"    -S/--subrepos is specified."
+msgstr ""
+
+msgid ""
+":commit: commit creates a consistent snapshot of the state of the\n"
+"    entire project and its subrepositories. It does this by first\n"
+"    attempting to commit all modified subrepositories, then recording\n"
+"    their state and finally committing it in the parent\n"
+"    repository. Mercurial can be made to abort if any subrepository\n"
+"    content is modified by setting \"ui.commitsubrepos=no\" in a\n"
+"    configuration file (see :hg:`help config`)."
+msgstr ""
+
+msgid ""
+":diff: diff does not recurse in subrepos unless -S/--subrepos is\n"
+"    specified. Changes are displayed as usual, on the subrepositories\n"
+"    elements. Subversion subrepositories are currently silently\n"
+"    ignored."
+msgstr ""
+
+msgid ""
+":incoming: incoming does not recurse in subrepos unless -S/--subrepos\n"
+"    is specified. Subversion subrepositories are currently silently\n"
+"    ignored."
+msgstr ""
+
+msgid ""
+":outgoing: outgoing does not recurse in subrepos unless -S/--subrepos\n"
+"    is specified. Subversion subrepositories are currently silently\n"
+"    ignored."
+msgstr ""
+
+msgid ""
+":pull: pull is not recursive since it is not clear what to pull prior\n"
+"    to running :hg:`update`. Listing and retrieving all\n"
+"    subrepositories changes referenced by the parent repository pulled\n"
+"    changesets is expensive at best, impossible in the Subversion\n"
+"    case."
+msgstr ""
+
+msgid ""
+":push: Mercurial will automatically push all subrepositories first\n"
+"    when the parent repository is being pushed. This ensures new\n"
+"    subrepository changes are available when referenced by top-level\n"
+"    repositories."
+msgstr ""
+
+msgid ""
+":status: status does not recurse into subrepositories unless\n"
+"    -S/--subrepos is specified. Subrepository changes are displayed as\n"
+"    regular Mercurial changes on the subrepository\n"
+"    elements. Subversion subrepositories are currently silently\n"
+"    ignored."
+msgstr ""
+
+msgid ""
+":update: update restores the subrepos in the state they were\n"
+"    originally committed in target changeset. If the recorded\n"
+"    changeset is not available in the current subrepository, Mercurial\n"
+"    will pull it in first before updating.  This means that updating\n"
+"    can require network access when using subrepositories."
+msgstr ""
+
+msgid ""
+"Remapping Subrepositories Sources\n"
+"---------------------------------"
+msgstr ""
+"Refacerea corespondențelor cu sursele subdepozitelor\n"
+"----------------------------------------------------"
+
+msgid ""
+"A subrepository source location may change during a project life,\n"
+"invalidating references stored in the parent repository history. To\n"
+"fix this, rewriting rules can be defined in parent repository ``hgrc``\n"
+"file or in Mercurial configuration. See the ``[subpaths]`` section in\n"
+"hgrc(5) for more details."
 msgstr ""
 
 msgid ""
@@ -10994,72 +14077,7 @@
 "keywords are usually available for templating a log-like command:"
 msgstr ""
 
-msgid ":author: String. The unmodified author of the changeset."
-msgstr ""
-
-msgid ""
-":branches: String. The name of the branch on which the changeset was\n"
-"    committed. Will be empty if the branch name was default."
-msgstr ""
-
-msgid ":children: List of strings. The children of the changeset."
-msgstr ""
-
-msgid ":date: Date information. The date when the changeset was committed."
-msgstr ""
-
-msgid ":desc: String. The text of the changeset description."
-msgstr ""
-
-msgid ""
-":diffstat: String. Statistics of changes with the following format:\n"
-"    \"modified files: +added/-removed lines\""
-msgstr ""
-
-msgid ""
-":files: List of strings. All files modified, added, or removed by this\n"
-"    changeset."
-msgstr ""
-
-msgid ":file_adds: List of strings. Files added by this changeset."
-msgstr ""
-
-msgid ""
-":file_copies: List of strings. Files copied in this changeset with\n"
-"    their sources."
-msgstr ""
-
-msgid ""
-":file_copies_switch: List of strings. Like \"file_copies\" but displayed\n"
-"    only if the --copied switch is set."
-msgstr ""
-
-msgid ":file_mods: List of strings. Files modified by this changeset."
-msgstr ""
-
-msgid ":file_dels: List of strings. Files removed by this changeset."
-msgstr ""
-
-msgid ""
-":node: String. The changeset identification hash, as a 40 hexadecimal\n"
-"    digit string."
-msgstr ""
-
-msgid ":parents: List of strings. The parents of the changeset."
-msgstr ""
-
-msgid ":rev: Integer. The repository-local changeset revision number."
-msgstr ""
-
-msgid ":tags: List of strings. Any tags associated with the changeset."
-msgstr ""
-
-msgid ""
-":latesttag: String. Most recent global tag in the ancestors of this\n"
-"    changeset."
-msgstr ""
-
-msgid ":latesttagdistance: Integer. Longest path to the latest tag."
+msgid ".. keywordsmarker"
 msgstr ""
 
 msgid ""
@@ -11079,128 +14097,8 @@
 msgid "List of filters:"
 msgstr ""
 
-msgid ""
-":addbreaks: Any text. Add an XHTML \"<br />\" tag before the end of\n"
-"    every line except the last."
-msgstr ""
-
-msgid ""
-":age: Date. Returns a human-readable date/time difference between the\n"
-"    given date/time and the current date/time."
-msgstr ""
-
-msgid ""
-":basename: Any text. Treats the text as a path, and returns the last\n"
-"    component of the path after splitting by the path separator\n"
-"    (ignoring trailing separators). For example, \"foo/bar/baz\" becomes\n"
-"    \"baz\" and \"foo/bar//\" becomes \"bar\"."
-msgstr ""
-
-msgid ""
-":stripdir: Treat the text as path and strip a directory level, if\n"
-"    possible. For example, \"foo\" and \"foo/bar\" becomes \"foo\"."
-msgstr ""
-
-msgid ""
-":date: Date. Returns a date in a Unix date format, including the\n"
-"    timezone: \"Mon Sep 04 15:13:13 2006 0700\"."
-msgstr ""
-
-msgid ""
-":domain: Any text. Finds the first string that looks like an email\n"
-"    address, and extracts just the domain component. Example: ``User\n"
-"    <user@example.com>`` becomes ``example.com``."
-msgstr ""
-
-msgid ""
-":email: Any text. Extracts the first string that looks like an email\n"
-"    address. Example: ``User <user@example.com>`` becomes\n"
-"    ``user@example.com``."
-msgstr ""
-
-msgid ""
-":escape: Any text. Replaces the special XML/XHTML characters \"&\", \"<\"\n"
-"    and \">\" with XML entities."
-msgstr ""
-
-msgid ":fill68: Any text. Wraps the text to fit in 68 columns."
-msgstr ""
-
-msgid ":fill76: Any text. Wraps the text to fit in 76 columns."
-msgstr ""
-
-msgid ":firstline: Any text. Returns the first line of text."
-msgstr ""
-
-msgid ":nonempty: Any text. Returns '(none)' if the string is empty."
-msgstr ""
-
-msgid ""
-":hgdate: Date. Returns the date as a pair of numbers: \"1157407993\n"
-"    25200\" (Unix timestamp, timezone offset)."
-msgstr ""
-
-msgid ""
-":isodate: Date. Returns the date in ISO 8601 format: \"2009-08-18 13:00\n"
-"    +0200\"."
-msgstr ""
-
-msgid ""
-":isodatesec: Date. Returns the date in ISO 8601 format, including\n"
-"    seconds: \"2009-08-18 13:00:13 +0200\". See also the rfc3339date\n"
-"    filter."
-msgstr ""
-
-msgid ":localdate: Date. Converts a date to local date."
-msgstr ""
-
-msgid ""
-":obfuscate: Any text. Returns the input text rendered as a sequence of\n"
-"    XML entities."
-msgstr ""
-
-msgid ":person: Any text. Returns the text before an email address."
-msgstr ""
-
-msgid ""
-":rfc822date: Date. Returns a date using the same format used in email\n"
-"    headers: \"Tue, 18 Aug 2009 13:00:13 +0200\"."
-msgstr ""
-
-msgid ""
-":rfc3339date: Date. Returns a date using the Internet date format\n"
-"    specified in RFC 3339: \"2009-08-18T13:00:13+02:00\"."
-msgstr ""
-
-msgid ""
-":short: Changeset hash. Returns the short form of a changeset hash,\n"
-"    i.e. a 12 hexadecimal digit string."
-msgstr ""
-
-msgid ":shortdate: Date. Returns a date like \"2006-09-18\"."
-msgstr ""
-
-msgid ""
-":stringify: Any type. Turns the value into text by converting values into\n"
-"    text and concatenating them."
-msgstr ""
-
-msgid ":strip: Any text. Strips all leading and trailing whitespace."
-msgstr ""
-
-msgid ""
-":tabindent: Any text. Returns the text, with every line except the\n"
-"     first starting with a tab character."
-msgstr ""
-
-msgid ""
-":urlescape: Any text. Escapes all \"special\" characters. For example,\n"
-"    \"foo bar\" becomes \"foo%20bar\"."
-msgstr ""
-
-msgid ":user: Any text. Returns the user portion of an email address.\n"
-msgstr ""
-":user: Orice text. Returnează porțiunea utilizator a unei adrese de e-mail.\n"
+msgid ".. filtersmarker\n"
+msgstr ""
 
 msgid "Valid URLs are of the form::"
 msgstr ""
@@ -11210,13 +14108,13 @@
 "  file://local/filesystem/path[#revision]\n"
 "  http://[user[:pass]@]host[:port]/[path][#revision]\n"
 "  https://[user[:pass]@]host[:port]/[path][#revision]\n"
-"  ssh://[user[:pass]@]host[:port]/[path][#revision]"
+"  ssh://[user@]host[:port]/[path][#revision]"
 msgstr ""
 
 msgid ""
 "Paths in the local filesystem can either point to Mercurial\n"
 "repositories or to bundle files (as created by :hg:`bundle` or :hg:`\n"
-"incoming --bundle`)."
+"incoming --bundle`). See also :hg:`help paths`."
 msgstr ""
 
 msgid ""
@@ -11231,6 +14129,11 @@
 "server."
 msgstr ""
 
+msgid ""
+"Note that the security of HTTPS URLs depends on proper configuration of\n"
+"web.cacerts."
+msgstr ""
+
 msgid "Some notes about using SSH with Mercurial:"
 msgstr ""
 
@@ -11257,13 +14160,13 @@
 msgstr ""
 
 msgid ""
-"  Alternatively specify \"ssh -C\" as your ssh command in your hgrc or\n"
-"  with the --ssh command line option."
-msgstr ""
-
-msgid ""
-"These URLs can all be stored in your hgrc with path aliases under the\n"
-"[paths] section like so::"
+"  Alternatively specify \"ssh -C\" as your ssh command in your\n"
+"  configuration file or with the --ssh command line option."
+msgstr ""
+
+msgid ""
+"These URLs can all be stored in your configuration file with path\n"
+"aliases under the [paths] section like so::"
 msgstr ""
 
 msgid ""
@@ -11351,17 +14254,25 @@
 msgstr ""
 
 msgid ""
-"use 'hg resolve' to retry unresolved file merges or 'hg update -C' to "
+"use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to "
 "abandon\n"
 msgstr ""
 
 msgid "(branch merge, don't forget to commit)\n"
-msgstr ""
+msgstr "(fuziune între ramuri, nu uitați să depozitați)\n"
+
+#, python-format
+msgid "config file %s not found!"
+msgstr "nu s-a găsit fișierul de configurare %s!"
 
 #, python-format
 msgid "error reading %s/.hg/hgrc: %s\n"
 msgstr ""
 
+#, python-format
+msgid "error accessing repository at %s\n"
+msgstr ""
+
 msgid "SSL support is unavailable"
 msgstr ""
 
@@ -11426,6 +14337,13 @@
 msgid "warning: %s hook %s\n"
 msgstr ""
 
+msgid "kb"
+msgstr ""
+
+#, python-format
+msgid "ignoring invalid [auth] key '%s'\n"
+msgstr ""
+
 msgid "connection ended unexpectedly"
 msgstr ""
 
@@ -11489,14 +14407,14 @@
 msgstr "depozitul %s există deja"
 
 #, python-format
-msgid "requirement '%s' not supported"
-msgstr ""
-
-#, python-format
 msgid ".hg/sharedpath points to nonexistent directory %s"
 msgstr ""
 
 #, python-format
+msgid "warning: ignoring unknown working parent %s!\n"
+msgstr ""
+
+#, python-format
 msgid "%r cannot be used in a tag name"
 msgstr ""
 
@@ -11525,19 +14443,27 @@
 msgstr ""
 
 #, python-format
-msgid "rolling back to revision %s (undo %s: %s)\n"
-msgstr ""
-
-#, python-format
-msgid "rolling back to revision %s (undo %s)\n"
+msgid "repository tip rolled back to revision %s (undo %s: %s)\n"
+msgstr ""
+
+#, python-format
+msgid "repository tip rolled back to revision %s (undo %s)\n"
 msgstr ""
 
 msgid "rolling back unknown transaction\n"
 msgstr ""
 
 #, python-format
-msgid "Named branch could not be reset, current branch still is: %s\n"
-msgstr ""
+msgid "named branch could not be reset, current branch is still: %s\n"
+msgstr ""
+
+#, python-format
+msgid "working directory now based on revisions %d and %d\n"
+msgstr "directorul de lucru se bazează acum pe reviziile %d și %d\n"
+
+#, python-format
+msgid "working directory now based on revision %d\n"
+msgstr "directorul de lucru se bazează acum pe revizia %d\n"
 
 msgid "no rollback information available\n"
 msgstr ""
@@ -11554,12 +14480,20 @@
 msgid "working directory of %s"
 msgstr "directorul de lucrul al %s"
 
+#, python-format
+msgid "warning: can't find ancestor for '%s' copied from '%s'!\n"
+msgstr ""
+
 msgid "cannot partially commit a merge (do not specify files or patterns)"
 msgstr ""
 
 msgid "can't commit subrepos without .hgsub"
 msgstr ""
 
+#, python-format
+msgid "uncommitted changes in subrepo %s"
+msgstr "modificări nedepozitate în subdepozitul %s"
+
 msgid "file not found!"
 msgstr ""
 
@@ -11569,7 +14503,7 @@
 msgid "file not tracked!"
 msgstr ""
 
-msgid "unresolved merge conflicts (see hg resolve)"
+msgid "unresolved merge conflicts (see hg help resolve)"
 msgstr ""
 
 #, python-format
@@ -11588,7 +14522,7 @@
 msgstr "se solicită toate modificările\n"
 
 msgid ""
-"Partial pull cannot be done because other repository doesn't support "
+"partial pull cannot be done because other repository doesn't support "
 "changegroupsubset."
 msgstr ""
 
@@ -11596,26 +14530,20 @@
 msgid "%d changesets found\n"
 msgstr ""
 
-msgid "bundling changes"
-msgstr ""
-
-msgid "chunks"
-msgstr ""
-
-msgid "bundling manifests"
+msgid "bundling"
+msgstr "se creează bundle-ul"
+
+msgid "manifests"
 msgstr ""
 
 #, python-format
 msgid "empty or missing revlog for %s"
 msgstr ""
 
-msgid "bundling files"
-msgstr ""
-
 msgid "adding changesets\n"
 msgstr "se adaugă seturile de modificări\n"
 
-msgid "changesets"
+msgid "chunks"
 msgstr ""
 
 msgid "received changelog group is empty"
@@ -11624,9 +14552,6 @@
 msgid "adding manifests\n"
 msgstr "se adaugă manifestele\n"
 
-msgid "manifests"
-msgstr ""
-
 msgid "adding file changes\n"
 msgstr "se adaugă modificările fișierelor\n"
 
@@ -11670,17 +14595,20 @@
 msgid "transferred %s in %.1f seconds (%s/sec)\n"
 msgstr ""
 
-msgid "no [smtp]host in hgrc - cannot send mail"
+msgid "can't use TLS: Python SSL support not installed"
+msgstr ""
+
+msgid "(using smtps)\n"
+msgstr ""
+
+msgid "smtp.host not configured - cannot send mail"
 msgstr ""
 
 #, python-format
 msgid "sending mail: smtp host %s, port %s\n"
 msgstr ""
 
-msgid "can't use TLS: Python SSL support not installed"
-msgstr ""
-
-msgid "(using tls)\n"
+msgid "(using starttls)\n"
 msgstr ""
 
 #, python-format
@@ -11711,10 +14639,25 @@
 msgstr ""
 
 #, python-format
+msgid "'\\n' and '\\r' disallowed in filenames: %r"
+msgstr ""
+
+#, python-format
 msgid "failed to remove %s from manifest"
 msgstr ""
 
 #, python-format
+msgid "invalid pattern (%s): %s"
+msgstr ""
+
+msgid "invalid pattern"
+msgstr ""
+
+#, python-format
+msgid "unable to read file list (%s)"
+msgstr ""
+
+#, python-format
 msgid "diff context lines count must be an integer, not %r"
 msgstr ""
 
@@ -11783,11 +14726,7 @@
 msgstr "se obține %s în %s\n"
 
 #, python-format
-msgid "warning: detected divergent renames of %s to:\n"
-msgstr ""
-
-#, python-format
-msgid "branch %s not found"
+msgid "note: possible conflict - %s was renamed multiple times to:\n"
 msgstr ""
 
 msgid "merging with a working directory ancestor has no effect"
@@ -11801,20 +14740,49 @@
 "modificări nedepozitate în suspensie (folosiți 'hg status' pentru a afișa "
 "modificările)"
 
-msgid ""
-"crosses branches (use 'hg merge' to merge or use 'hg update -C' to discard "
-"changes)"
-msgstr ""
-
-msgid "crosses branches (use 'hg merge' or use 'hg update -c')"
-msgstr ""
-
-#, python-format
-msgid "cannot create %s: destination already exists"
-msgstr ""
-
-#, python-format
-msgid "cannot create %s: unable to create destination directory"
+#, python-format
+msgid "outstanding uncommitted changes in subrepository '%s'"
+msgstr "modificările încă nedepozitate în subdepozitul '%s'"
+
+msgid "crosses branches (merge branches or use --clean to discard changes)"
+msgstr ""
+
+msgid "crosses branches (merge branches or update --check to force update)"
+msgstr ""
+
+msgid "Attention:"
+msgstr ""
+
+msgid "Caution:"
+msgstr ""
+
+msgid "!Danger!"
+msgstr ""
+
+msgid "Error:"
+msgstr ""
+
+msgid "Hint:"
+msgstr ""
+
+msgid "Important:"
+msgstr ""
+
+msgid "Note:"
+msgstr "Notă:"
+
+msgid "Tip:"
+msgstr ""
+
+msgid "Warning!"
+msgstr ""
+
+#, python-format
+msgid "%d out of %d hunks FAILED -- saving rejects to file %s\n"
+msgstr ""
+
+#, python-format
+msgid "cannot patch %s: file is not tracked"
 msgstr ""
 
 #, python-format
@@ -11826,14 +14794,14 @@
 msgstr ""
 
 #, python-format
-msgid "%d out of %d hunks FAILED -- saving rejects to file %s\n"
-msgstr ""
-
-#, python-format
 msgid "bad hunk #%d %s (%d %d %d %d)"
 msgstr ""
 
 #, python-format
+msgid "cannot create %s: destination already exists\n"
+msgstr ""
+
+#, python-format
 msgid "file %s already exists\n"
 msgstr ""
 
@@ -11872,7 +14840,7 @@
 msgstr ""
 
 #, python-format
-msgid "malformed patch %s %s"
+msgid "cannot create %s: destination already exists"
 msgstr ""
 
 #, python-format
@@ -11884,13 +14852,10 @@
 msgstr ""
 
 #, python-format
-msgid "Unsupported line endings type: %s"
-msgstr ""
-
-msgid ""
-"internal patcher failed\n"
-"please report details to http://mercurial.selenic.com/bts/\n"
-"or mercurial@selenic.com\n"
+msgid "unsupported line endings type: %s"
+msgstr ""
+
+msgid "patch failed to apply"
 msgstr ""
 
 #, python-format
@@ -11964,17 +14929,11 @@
 msgid "%s not found in the transaction"
 msgstr "%s nu a fost găsit în tranzacție"
 
-msgid "unknown base"
-msgstr ""
-
-msgid "consistency error adding group"
-msgstr "eroare de consistență la adăugarea grupului"
-
-msgid "unterminated string"
-msgstr ""
-
-msgid "syntax error"
-msgstr ""
+msgid "consistency error in delta"
+msgstr "eroare de consistență în delta"
+
+msgid "unknown delta base"
+msgstr "bază necunoscută pentru delta"
 
 msgid "missing argument"
 msgstr ""
@@ -11990,61 +14949,363 @@
 msgid "not a function: %s"
 msgstr ""
 
-msgid "limit wants two arguments"
-msgstr ""
-
-msgid "limit wants a number"
-msgstr ""
-
-msgid "limit expects a number"
-msgstr ""
-
-msgid "ancestor wants two arguments"
-msgstr ""
-
+msgid ""
+"``adds(pattern)``\n"
+"    Changesets that add a file matching pattern."
+msgstr ""
+
+#. i18n: "adds" is a keyword
+msgid "adds requires a pattern"
+msgstr ""
+
+msgid ""
+"``ancestor(single, single)``\n"
+"    Greatest common ancestor of the two changesets."
+msgstr ""
+
+#. i18n: "ancestor" is a keyword
+msgid "ancestor requires two arguments"
+msgstr ""
+
+#. i18n: "ancestor" is a keyword
 msgid "ancestor arguments must be single revisions"
 msgstr ""
 
+msgid ""
+"``ancestors(set)``\n"
+"    Changesets that are ancestors of a changeset in set."
+msgstr ""
+
+msgid "~ expects a number"
+msgstr ""
+
+msgid ""
+"``author(string)``\n"
+"    Alias for ``user(string)``."
+msgstr ""
+
+#. i18n: "author" is a keyword
+msgid "author requires a string"
+msgstr ""
+
+msgid ""
+"``bisected(string)``\n"
+"    Changesets marked in the specified bisect state (good, bad, skip)."
+msgstr ""
+
+msgid "bisect requires a string"
+msgstr ""
+
+msgid "invalid bisect state"
+msgstr ""
+
+msgid ""
+"``bookmark([name])``\n"
+"    The named bookmark or all bookmarks."
+msgstr ""
+
+#. i18n: "bookmark" is a keyword
+msgid "bookmark takes one or no arguments"
+msgstr ""
+
+#. i18n: "bookmark" is a keyword
+msgid "the argument to bookmark must be a string"
+msgstr ""
+
+msgid ""
+"``branch(string or set)``\n"
+"    All changesets belonging to the given branch or the branches of the "
+"given\n"
+"    changesets."
+msgstr ""
+
+msgid ""
+"``children(set)``\n"
+"    Child changesets of changesets in set."
+msgstr ""
+
+msgid ""
+"``closed()``\n"
+"    Changeset is closed."
+msgstr ""
+
+#. i18n: "closed" is a keyword
+msgid "closed takes no arguments"
+msgstr ""
+
+msgid ""
+"``contains(pattern)``\n"
+"    Revision contains a file matching pattern. See :hg:`help patterns`\n"
+"    for information about file patterns."
+msgstr ""
+
+#. i18n: "contains" is a keyword
+msgid "contains requires a pattern"
+msgstr ""
+
+msgid ""
+"``date(interval)``\n"
+"    Changesets within the interval, see :hg:`help dates`."
+msgstr ""
+
+#. i18n: "date" is a keyword
+msgid "date requires a string"
+msgstr ""
+
+msgid ""
+"``descendants(set)``\n"
+"    Changesets which are descendants of changesets in set."
+msgstr ""
+
+msgid ""
+"``filelog(pattern)``\n"
+"    Changesets connected to the specified filelog."
+msgstr ""
+
+msgid "filelog requires a pattern"
+msgstr ""
+
+msgid ""
+"``follow([file])``\n"
+"    An alias for ``::.`` (ancestors of the working copy's first parent).\n"
+"    If a filename is specified, the history of the given file is followed,\n"
+"    including copies."
+msgstr ""
+
+#. i18n: "follow" is a keyword
+msgid "follow takes no arguments or a filename"
+msgstr ""
+
+#. i18n: "follow" is a keyword
 msgid "follow takes no arguments"
 msgstr ""
 
-msgid "date wants a string"
-msgstr ""
-
-msgid "keyword wants a string"
-msgstr ""
-
-msgid "grep wants a string"
-msgstr ""
-
-msgid "author wants a string"
-msgstr ""
-
-msgid "file wants a pattern"
-msgstr ""
-
-msgid "contains wants a pattern"
-msgstr ""
-
-msgid "modifies wants a pattern"
-msgstr ""
-
-msgid "adds wants a pattern"
-msgstr ""
-
-msgid "removes wants a pattern"
-msgstr ""
-
+msgid ""
+"``all()``\n"
+"    All changesets, the same as ``0:tip``."
+msgstr ""
+
+#. i18n: "all" is a keyword
+msgid "all takes no arguments"
+msgstr ""
+
+msgid ""
+"``grep(regex)``\n"
+"    Like ``keyword(string)`` but accepts a regex. Use ``grep(r'...')``\n"
+"    to ensure special escape characters are handled correctly. Unlike\n"
+"    ``keyword(string)``, the match is case-sensitive."
+msgstr ""
+
+#. i18n: "grep" is a keyword
+msgid "grep requires a string"
+msgstr ""
+
+#, python-format
+msgid "invalid match pattern: %s"
+msgstr ""
+
+msgid ""
+"``file(pattern)``\n"
+"    Changesets affecting files matched by pattern."
+msgstr ""
+
+#. i18n: "file" is a keyword
+msgid "file requires a pattern"
+msgstr ""
+
+msgid ""
+"``head()``\n"
+"    Changeset is a named branch head."
+msgstr ""
+
+#. i18n: "head" is a keyword
+msgid "head takes no arguments"
+msgstr ""
+
+msgid ""
+"``heads(set)``\n"
+"    Members of set with no children in set."
+msgstr ""
+
+msgid ""
+"``keyword(string)``\n"
+"    Search commit message, user name, and names of changed files for\n"
+"    string. The match is case-insensitive."
+msgstr ""
+
+#. i18n: "keyword" is a keyword
+msgid "keyword requires a string"
+msgstr ""
+
+msgid ""
+"``limit(set, n)``\n"
+"    First n members of set."
+msgstr ""
+
+#. i18n: "limit" is a keyword
+msgid "limit requires two arguments"
+msgstr ""
+
+#. i18n: "limit" is a keyword
+msgid "limit requires a number"
+msgstr ""
+
+#. i18n: "limit" is a keyword
+msgid "limit expects a number"
+msgstr ""
+
+msgid ""
+"``last(set, n)``\n"
+"    Last n members of set."
+msgstr ""
+
+#. i18n: "last" is a keyword
+msgid "last requires two arguments"
+msgstr ""
+
+#. i18n: "last" is a keyword
+msgid "last requires a number"
+msgstr ""
+
+#. i18n: "last" is a keyword
+msgid "last expects a number"
+msgstr ""
+
+msgid ""
+"``max(set)``\n"
+"    Changeset with highest revision number in set."
+msgstr ""
+
+msgid ""
+"``merge()``\n"
+"    Changeset is a merge changeset."
+msgstr ""
+
+#. i18n: "merge" is a keyword
 msgid "merge takes no arguments"
 msgstr ""
 
-msgid "closed takes no arguments"
-msgstr ""
-
-msgid "head takes no arguments"
-msgstr ""
-
-msgid "sort wants one or two arguments"
+msgid ""
+"``min(set)``\n"
+"    Changeset with lowest revision number in set."
+msgstr ""
+
+msgid ""
+"``modifies(pattern)``\n"
+"    Changesets modifying files matched by pattern."
+msgstr ""
+
+#. i18n: "modifies" is a keyword
+msgid "modifies requires a pattern"
+msgstr ""
+
+msgid ""
+"``id(string)``\n"
+"    Revision non-ambiguously specified by the given hex string prefix."
+msgstr ""
+
+#. i18n: "id" is a keyword
+msgid "id requires one argument"
+msgstr ""
+
+#. i18n: "id" is a keyword
+msgid "id requires a string"
+msgstr ""
+
+#, fuzzy
+msgid ""
+"``outgoing([path])``\n"
+"    Changesets not found in the specified destination repository, or the\n"
+"    default push location."
+msgstr ""
+"``outgoing([cale])``\n"
+"  Nu s-au găsit seturi de modificări în depozitul destinație specificat\n"
+"  sau în amplasarea implicită pentru `push`."
+
+#. i18n: "outgoing" is a keyword
+msgid "outgoing requires a repository path"
+msgstr ""
+
+msgid ""
+"``p1([set])``\n"
+"    First parent of changesets in set, or the working directory."
+msgstr ""
+
+msgid ""
+"``p2([set])``\n"
+"    Second parent of changesets in set, or the working directory."
+msgstr ""
+
+msgid ""
+"``parents([set])``\n"
+"    The set of all parents for all changesets in set, or the working "
+"directory."
+msgstr ""
+
+msgid "^ expects a number 0, 1, or 2"
+msgstr ""
+
+msgid ""
+"``present(set)``\n"
+"    An empty set, if any revision in set isn't found; otherwise,\n"
+"    all revisions in set."
+msgstr ""
+
+msgid ""
+"``removes(pattern)``\n"
+"    Changesets which remove files matching pattern."
+msgstr ""
+
+#. i18n: "removes" is a keyword
+msgid "removes requires a pattern"
+msgstr ""
+
+msgid ""
+"``rev(number)``\n"
+"    Revision with the given numeric identifier."
+msgstr ""
+
+#. i18n: "rev" is a keyword
+msgid "rev requires one argument"
+msgstr ""
+
+#. i18n: "rev" is a keyword
+msgid "rev requires a number"
+msgstr ""
+
+#. i18n: "rev" is a keyword
+msgid "rev expects a number"
+msgstr ""
+
+msgid ""
+"``reverse(set)``\n"
+"    Reverse order of set."
+msgstr ""
+
+msgid ""
+"``roots(set)``\n"
+"    Changesets with no parent changeset in set."
+msgstr ""
+
+msgid ""
+"``sort(set[, [-]key...])``\n"
+"    Sort set by keys. The default sort order is ascending, specify a key\n"
+"    as ``-key`` to sort in descending order."
+msgstr ""
+
+msgid "    The keys can be:"
+msgstr ""
+
+msgid ""
+"    - ``rev`` for the revision number,\n"
+"    - ``branch`` for the branch name,\n"
+"    - ``desc`` for the commit message (description),\n"
+"    - ``user`` for user name (``author`` can be used as an alias),\n"
+"    - ``date`` for the commit date"
+msgstr ""
+
+#. i18n: "sort" is a keyword
+msgid "sort requires one or two arguments"
 msgstr ""
 
 msgid "sort spec must be a string"
@@ -12054,13 +15315,22 @@
 msgid "unknown sort key %r"
 msgstr ""
 
-msgid "all takes no arguments"
-msgstr ""
-
-msgid "outgoing wants a repository path"
-msgstr ""
-
-msgid "tagged takes no arguments"
+msgid ""
+"``tag([name])``\n"
+"    The specified tag by name, or all tagged revisions if no name is given."
+msgstr ""
+
+#. i18n: "tag" is a keyword
+msgid "tag takes one or no arguments"
+msgstr ""
+
+#. i18n: "tag" is a keyword
+msgid "the argument to tag must be a string"
+msgstr ""
+
+msgid ""
+"``user(string)``\n"
+"    User name contains string. The match is case-insensitive."
 msgstr ""
 
 msgid "can't negate that"
@@ -12072,6 +15342,64 @@
 msgid "empty query"
 msgstr ""
 
+#, python-format
+msgid "ui.portablefilenames value is invalid ('%s')"
+msgstr ""
+
+#, python-format
+msgid "possible case-folding collision for %s"
+msgstr ""
+
+#, python-format
+msgid "path ends in directory separator: %s"
+msgstr ""
+
+#, python-format
+msgid "path contains illegal component: %s"
+msgstr ""
+
+#, python-format
+msgid "path %r is inside nested repo %r"
+msgstr ""
+
+#, python-format
+msgid "path %r traverses symbolic link %r"
+msgstr ""
+
+#, python-format
+msgid "could not symlink to %r: %s"
+msgstr ""
+
+#, python-format
+msgid "recording removal of %s as rename to %s (%d%% similar)\n"
+msgstr ""
+
+#, python-format
+msgid "%s has not been committed yet, so no copy data will be stored for %s.\n"
+msgstr ""
+
+msgid ".hg/requires file is corrupt"
+msgstr ""
+
+#, python-format
+msgid "unknown repository format: requires feature '%s' (upgrade Mercurial)"
+msgstr ""
+
+msgid "searching for changes\n"
+msgstr "se caută modificări\n"
+
+msgid "queries"
+msgstr ""
+
+msgid "searching"
+msgstr ""
+
+msgid "repository is unrelated"
+msgstr ""
+
+msgid "warning: repository is unrelated\n"
+msgstr ""
+
 msgid "searching for exact renames"
 msgstr ""
 
@@ -12092,6 +15420,9 @@
 msgid "couldn't parse location %s"
 msgstr ""
 
+msgid "password in URL not supported"
+msgstr ""
+
 msgid "could not create remote repo"
 msgstr ""
 
@@ -12108,6 +15439,49 @@
 msgid "push refused: %s"
 msgstr ""
 
+msgid "certificate checking requires Python 2.6"
+msgstr "verificarea certificatului necesită Python 2.6"
+
+msgid "no certificate received"
+msgstr ""
+
+#, python-format
+msgid "certificate is for %s"
+msgstr ""
+
+msgid "IDN in certificate not supported"
+msgstr ""
+
+msgid "no commonName or subjectAltName found in certificate"
+msgstr ""
+
+#, python-format
+msgid "could not find web.cacerts: %s"
+msgstr ""
+
+#, python-format
+msgid "%s certificate error: %s (use --insecure to connect insecurely)"
+msgstr ""
+
+#, python-format
+msgid "invalid certificate for %s with fingerprint %s"
+msgstr ""
+
+#, python-format
+msgid ""
+"warning: %s certificate with fingerprint %s not verified (check "
+"hostfingerprints or web.cacerts config setting)\n"
+msgstr ""
+
+#, python-format
+msgid "no certificate for %s with configured hostfingerprint"
+msgstr ""
+
+#, python-format
+msgid ""
+"warning: %s certificate not verified (check web.cacerts config setting)\n"
+msgstr ""
+
 #, python-format
 msgid "'%s' does not appear to be an hg repository"
 msgstr ""
@@ -12123,6 +15497,12 @@
 msgstr ""
 
 #, python-format
+msgid "warning: subrepo spec file %s not found\n"
+msgstr ""
+"avertisment: fișierul de specificație %s pentru subdepozit nu\n"
+"a fost găsit\n"
+
+#, python-format
 msgid "subrepo spec file %s not found"
 msgstr ""
 
@@ -12155,14 +15535,42 @@
 msgstr ""
 
 #, python-format
+msgid ""
+" subrepository sources for %s differ\n"
+"use (l)ocal source (%s) or (r)emote source (%s)?\n"
+msgstr ""
+
+#, python-format
+msgid ""
+" subrepository sources for %s differ (in checked out version)\n"
+"use (l)ocal source (%s) or (r)emote source (%s)?\n"
+msgstr ""
+
+#, python-format
+msgid "default path for subrepository %s not found"
+msgstr "calea implicită pentru subdepozitul %s nu a fost găsită"
+
+#, python-format
 msgid "unknown subrepo type %s"
 msgstr ""
 
 #, python-format
+msgid "archiving (%s)"
+msgstr ""
+
+#, python-format
+msgid "warning: error \"%s\" in subrepository \"%s\"\n"
+msgstr ""
+
+#, python-format
 msgid "removing subrepo %s\n"
 msgstr ""
 
 #, python-format
+msgid "cloning subrepo %s from %s\n"
+msgstr "se clonează subdepozitul %s de la %s\n"
+
+#, python-format
 msgid "pulling subrepo %s from %s\n"
 msgstr ""
 
@@ -12170,6 +15578,9 @@
 msgid "pushing subrepo %s to %s\n"
 msgstr ""
 
+msgid "cannot retrieve svn tool version"
+msgstr ""
+
 msgid "cannot commit svn externals"
 msgstr ""
 
@@ -12178,6 +15589,35 @@
 msgstr ""
 
 #, python-format
+msgid "revision %s does not exist in subrepo %s\n"
+msgstr ""
+
+#, python-format
+msgid "checking out detached HEAD in subrepo %s\n"
+msgstr ""
+
+msgid "check out a git branch if you intend to make changes\n"
+msgstr ""
+
+#, python-format
+msgid "subrepo %s is missing"
+msgstr ""
+
+#, python-format
+msgid "unrelated git branch checked out in subrepo %s\n"
+msgstr ""
+
+#, python-format
+msgid "pushing branch %s of subrepo %s\n"
+msgstr ""
+
+#, python-format
+msgid ""
+"no branch checked out in subrepo %s\n"
+"cannot push revision %s"
+msgstr ""
+
+#, python-format
 msgid "%s, line %s: %s\n"
 msgstr ""
 
@@ -12188,22 +15628,39 @@
 msgid "node '%s' is not well formed"
 msgstr ""
 
+msgid ".hg/cache/tags is corrupt, rebuilding it\n"
+msgstr ""
+
+#, python-format
+msgid "unknown method '%s'"
+msgstr "metodă necunoscută '%s'"
+
+msgid "expected a symbol"
+msgstr ""
+
+#, python-format
+msgid "unknown function '%s'"
+msgstr "funcție necunoscută '%s'"
+
+msgid "expected template specifier"
+msgstr ""
+
+#, python-format
+msgid "filter %s expects one argument"
+msgstr ""
+
 msgid "unmatched quotes"
 msgstr ""
 
 #, python-format
-msgid "error expanding '%s%%%s'"
-msgstr ""
-
-#, python-format
-msgid "unknown filter '%s'"
-msgstr ""
-
-#, python-format
 msgid "style not found: %s"
 msgstr ""
 
 #, python-format
+msgid "\"%s\" not in template map"
+msgstr "\"%s\" nu se află în harta de șabloane"
+
+#, python-format
 msgid "template file %s: %s"
 msgstr ""
 
@@ -12223,6 +15680,9 @@
 msgid "rollback failed - please run hg recover\n"
 msgstr ""
 
+msgid "already have changeset "
+msgstr ""
+
 #, python-format
 msgid "Not trusting file %s from untrusted user %s, group %s\n"
 msgstr ""
@@ -12232,11 +15692,19 @@
 msgstr ""
 
 #, python-format
+msgid "(deprecated '%%' in path %s=%s from %s)\n"
+msgstr ""
+
+#, python-format
 msgid "ignoring untrusted configuration option %s.%s = %s\n"
 msgstr ""
 
 #, python-format
-msgid "%s.%s not a boolean ('%s')"
+msgid "%s.%s is not a boolean ('%s')"
+msgstr ""
+
+#, python-format
+msgid "%s.%s is not an integer ('%s')"
 msgstr ""
 
 msgid "enter a commit username:"
@@ -12253,10 +15721,6 @@
 msgid "username %s contains a newline\n"
 msgstr ""
 
-#, python-format
-msgid "(deprecated '%%' in path %s=%s from %s)\n"
-msgstr ""
-
 msgid "response expected"
 msgstr ""
 
@@ -12291,40 +15755,30 @@
 msgstr ""
 
 #, python-format
-msgid "ignoring invalid [auth] key '%s'\n"
-msgstr ""
-
-msgid "certificate checking requires Python 2.6"
-msgstr "verificarea certificatului necesită Python 2.6"
-
-msgid "server identity verification succeeded\n"
-msgstr ""
-
-#, python-format
 msgid "command '%s' failed: %s"
 msgstr ""
 
 #, python-format
-msgid "path contains illegal component: %s"
-msgstr ""
-
-#, python-format
-msgid "path %r is inside repo %r"
-msgstr ""
-
-#, python-format
-msgid "path %r traverses symbolic link %r"
-msgstr ""
-
-msgid "Hardlinks not supported"
-msgstr ""
-
-#, python-format
-msgid "could not symlink to %r: %s"
-msgstr ""
-
-#, python-format
-msgid "invalid date: %r "
+msgid "filename contains '%s', which is reserved on Windows"
+msgstr ""
+
+#, python-format
+msgid "filename contains %r, which is invalid on Windows"
+msgstr ""
+
+#, python-format
+msgid "filename ends with '%s', which is not allowed on Windows"
+msgstr ""
+
+msgid "check your clock"
+msgstr ""
+
+#, python-format
+msgid "negative timestamp: %d"
+msgstr ""
+
+#, python-format
+msgid "invalid date: %r"
 msgstr ""
 
 #, python-format
@@ -12332,14 +15786,31 @@
 msgstr ""
 
 #, python-format
+msgid "negative date value: %d"
+msgstr ""
+
+#, python-format
 msgid "impossible time zone offset: %d"
 msgstr ""
 
+msgid "dates cannot consist entirely of whitespace"
+msgstr ""
+
+msgid "invalid day spec, use '<DATE'"
+msgstr ""
+
+msgid "invalid day spec, use '>DATE'"
+msgstr ""
+
 #, python-format
 msgid "invalid day spec: %s"
 msgstr ""
 
 #, python-format
+msgid "%s must be nonnegative (see 'hg help dates')"
+msgstr ""
+
+#, python-format
 msgid "%.0f GB"
 msgstr ""
 
@@ -12379,6 +15850,13 @@
 msgid "%.0f bytes"
 msgstr ""
 
+#, python-format
+msgid "no port number associated with service '%s'"
+msgstr ""
+
+msgid "file:// URLs can only refer to localhost"
+msgstr ""
+
 msgid "cannot verify bundle or remote repos"
 msgstr ""
 
@@ -12443,6 +15921,9 @@
 msgid "checking changesets\n"
 msgstr "se verifică seturile de modificări\n"
 
+msgid "checking"
+msgstr "se verifică"
+
 #, python-format
 msgid "unpacking changeset %s"
 msgstr ""
@@ -12485,9 +15966,6 @@
 msgid "cannot decode filename '%s'"
 msgstr ""
 
-msgid "checking"
-msgstr "se verifică"
-
 #, python-format
 msgid "broken revlog! (%s)"
 msgstr ""
@@ -12547,20 +16025,80 @@
 msgid "(first damaged changeset appears to be %d)\n"
 msgstr ""
 
-msgid "user name not available - set USERNAME environment variable"
-msgstr ""
-
 msgid "look up remote revision"
 msgstr "se caută revizia"
 
+msgid "push failed (unexpected response):"
+msgstr ""
+
 msgid "look up remote changes"
 msgstr "se caută modificări la distanță"
 
 msgid "push failed:"
 msgstr ""
 
-msgid "push failed (unexpected response):"
-msgstr ""
+#~ msgid "not updating, since new heads added\n"
+#~ msgstr "nu se actualizează deoarece au fost adăugate noi capete\n"
+
+#~ msgid "record datecode as commit date"
+#~ msgstr "înregistrează codul de dată ca dată a depozitării"
+
+#~ msgid "base path"
+#~ msgstr "calea de bază"
+
+#~ msgid ""
+#~ "If there is a per-repository configuration file which is not owned by\n"
+#~ "the active user, Mercurial will warn you that the file is skipped::"
+#~ msgstr ""
+#~ "Dacă există un fișier de configurare la nivelul depozitului care nu\n"
+#~ "este proprietatea utilizatorului activ, Mercurial vă va avertiza că\n"
+#~ "fișierul este omis::"
+
+#~ msgid ""
+#~ "    Return 0 on succces.\n"
+#~ "    "
+#~ msgstr ""
+#~ "    Returnează 0 în caz de succes.\n"
+#~ "    "
+
+#~ msgid "Checking patch...\n"
+#~ msgstr "Se verifică patch-ul\n"
+
+#~ msgid ":user: Any text. Returns the user portion of an email address.\n"
+#~ msgstr ""
+#~ ":user: Orice text. Returnează porțiunea utilizator a unei adrese de e-"
+#~ "mail.\n"
+
+#, fuzzy
+#~ msgid "pulling subrepo %s\n"
+#~ msgstr "%d subdepozite"
+
+#~ msgid "options:"
+#~ msgstr "opțiuni:"
+
+#~ msgid "queue directory updating\n"
+#~ msgstr "actualizarea directorului se introduce în coadă\n"
+
+#~ msgid "replace existing tag"
+#~ msgstr "înlocuiește o etichetă existentă"
+
+#~ msgid " changesets"
+#~ msgstr "seturi de modificări"
+
+#~ msgid ""
+#~ "    If no changeset is specified, attempt to update to the tip of the\n"
+#~ "    current branch. If this changeset is a descendant of the working\n"
+#~ "    directory's parent, update to it, otherwise abort."
+#~ msgstr ""
+#~ "    Dacă nu se specifică nici un set de modificări, se încearcă "
+#~ "actualizarea\n"
+#~ "    la vârful ramurii curente. Dacă acest set de modificări este "
+#~ "descendent\n"
+#~ "    al părintelui directorului de lucru, se actualizează la el, altfel se "
+#~ "renunță."
+
+#~ msgid "check for uncommitted changes"
+#~ msgstr "verifică dacă există modificări nedepozitate"
 
 #~ msgid ""
 #~ "    If no commit message is specified, the configured editor is\n"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/i18n/ru.po	Sat Jun 18 17:03:01 2011 -0500
@@ -0,0 +1,14853 @@
+# Russian translations for Mercurial package.
+# Copyright (C) 2011 Matt Mackall <mpm@selenic.com> and others
+# This file is distributed under the same license as the Mercurial package.
+# Alexander Sauta <demosito@gmail.com>, 2011.
+msgid ""
+msgstr ""
+"Project-Id-Version: Mercurial\n"
+"Report-Msgid-Bugs-To: <mercurial-devel@selenic.com>\n"
+"POT-Creation-Date: 2011-06-09 20:39+0400\n"
+"PO-Revision-Date: 2011-05-12 23:48+0400\n"
+"Last-Translator: Alexander Sauta <demosito@gmail.com>\n"
+"Language-Team: Russian\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%"
+"10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
+
+#, python-format
+msgid " (default: %s)"
+msgstr " (по умолчанию: %s)"
+
+msgid "Options"
+msgstr "Настройки"
+
+msgid "Commands"
+msgstr "Команды"
+
+msgid "Extensions"
+msgstr "Расширения"
+
+msgid ""
+"This section contains help for extensions that are distributed together with "
+"Mercurial. Help for other extensions is available in the help system."
+msgstr ""
+"Этот раздел содержит справку по расширениям, включенным в стандартную "
+"комплектацию Mercurial. Справка по другим расширениям может быть получена в "
+"справочной системе."
+
+msgid "Options:"
+msgstr "Параметры:"
+
+#, python-format
+msgid "    aliases: %s"
+msgstr "    псевдонимы: %s"
+
+msgid "hooks for controlling repository access"
+msgstr "Хуки для контроля доступа к репозиторию"
+
+msgid ""
+"This hook makes it possible to allow or deny write access to given\n"
+"branches and paths of a repository when receiving incoming changesets\n"
+"via pretxnchangegroup and pretxncommit."
+msgstr ""
+
+msgid ""
+"The authorization is matched based on the local user name on the\n"
+"system where the hook runs, and not the committer of the original\n"
+"changeset (since the latter is merely informative)."
+msgstr ""
+
+msgid ""
+"The acl hook is best used along with a restricted shell like hgsh,\n"
+"preventing authenticating users from doing anything other than pushing\n"
+"or pulling. The hook is not safe to use if users have interactive\n"
+"shell access, as they can then disable the hook. Nor is it safe if\n"
+"remote users share an account, because then there is no way to\n"
+"distinguish them."
+msgstr ""
+
+msgid "The order in which access checks are performed is:"
+msgstr ""
+
+msgid ""
+"1) Deny  list for branches (section ``acl.deny.branches``)\n"
+"2) Allow list for branches (section ``acl.allow.branches``)\n"
+"3) Deny  list for paths    (section ``acl.deny``)\n"
+"4) Allow list for paths    (section ``acl.allow``)"
+msgstr ""
+
+msgid "The allow and deny sections take key-value pairs."
+msgstr ""
+
+msgid ""
+"Branch-based Access Control\n"
+"..........................."
+msgstr ""
+
+msgid ""
+"Use the ``acl.deny.branches`` and ``acl.allow.branches`` sections to\n"
+"have branch-based access control. Keys in these sections can be\n"
+"either:"
+msgstr ""
+
+msgid ""
+"- a branch name, or\n"
+"- an asterisk, to match any branch;"
+msgstr ""
+
+msgid "The corresponding values can be either:"
+msgstr ""
+
+msgid ""
+"- a comma-separated list containing users and groups, or\n"
+"- an asterisk, to match anyone;"
+msgstr ""
+
+msgid ""
+"Path-based Access Control\n"
+"........................."
+msgstr ""
+
+msgid ""
+"Use the ``acl.deny`` and ``acl.allow`` sections to have path-based\n"
+"access control. Keys in these sections accept a subtree pattern (with\n"
+"a glob syntax by default). The corresponding values follow the same\n"
+"syntax as the other sections above."
+msgstr ""
+
+msgid ""
+"Groups\n"
+"......"
+msgstr ""
+
+msgid ""
+"Group names must be prefixed with an ``@`` symbol. Specifying a group\n"
+"name has the same effect as specifying all the users in that group."
+msgstr ""
+
+msgid ""
+"You can define group members in the ``acl.groups`` section.\n"
+"If a group name is not defined there, and Mercurial is running under\n"
+"a Unix-like system, the list of users will be taken from the OS.\n"
+"Otherwise, an exception will be raised."
+msgstr ""
+
+msgid ""
+"Example Configuration\n"
+"....................."
+msgstr ""
+
+msgid "::"
+msgstr ""
+
+msgid "  [hooks]"
+msgstr ""
+
+msgid ""
+"  # Use this if you want to check access restrictions at commit time\n"
+"  pretxncommit.acl = python:hgext.acl.hook"
+msgstr ""
+
+msgid ""
+"  # Use this if you want to check access restrictions for pull, push,\n"
+"  # bundle and serve.\n"
+"  pretxnchangegroup.acl = python:hgext.acl.hook"
+msgstr ""
+
+msgid ""
+"  [acl]\n"
+"  # Allow or deny access for incoming changes only if their source is\n"
+"  # listed here, let them pass otherwise. Source is \"serve\" for all\n"
+"  # remote access (http or ssh), \"push\", \"pull\" or \"bundle\" when the\n"
+"  # related commands are run locally.\n"
+"  # Default: serve\n"
+"  sources = serve"
+msgstr ""
+
+msgid "  [acl.deny.branches]"
+msgstr ""
+
+msgid ""
+"  # Everyone is denied to the frozen branch:\n"
+"  frozen-branch = *"
+msgstr ""
+
+msgid ""
+"  # A bad user is denied on all branches:\n"
+"  * = bad-user"
+msgstr ""
+
+msgid "  [acl.allow.branches]"
+msgstr ""
+
+msgid ""
+"  # A few users are allowed on branch-a:\n"
+"  branch-a = user-1, user-2, user-3"
+msgstr ""
+
+msgid ""
+"  # Only one user is allowed on branch-b:\n"
+"  branch-b = user-1"
+msgstr ""
+
+msgid ""
+"  # The super user is allowed on any branch:\n"
+"  * = super-user"
+msgstr ""
+
+msgid ""
+"  # Everyone is allowed on branch-for-tests:\n"
+"  branch-for-tests = *"
+msgstr ""
+
+msgid ""
+"  [acl.deny]\n"
+"  # This list is checked first. If a match is found, acl.allow is not\n"
+"  # checked. All users are granted access if acl.deny is not present.\n"
+"  # Format for both lists: glob pattern = user, ..., @group, ..."
+msgstr ""
+
+msgid ""
+"  # To match everyone, use an asterisk for the user:\n"
+"  # my/glob/pattern = *"
+msgstr ""
+
+msgid ""
+"  # user6 will not have write access to any file:\n"
+"  ** = user6"
+msgstr ""
+
+msgid ""
+"  # Group \"hg-denied\" will not have write access to any file:\n"
+"  ** = @hg-denied"
+msgstr ""
+
+msgid ""
+"  # Nobody will be able to change \"DONT-TOUCH-THIS.txt\", despite\n"
+"  # everyone being able to change all other files. See below.\n"
+"  src/main/resources/DONT-TOUCH-THIS.txt = *"
+msgstr ""
+
+msgid ""
+"  [acl.allow]\n"
+"  # if acl.allow is not present, all users are allowed by default\n"
+"  # empty acl.allow = no users allowed"
+msgstr ""
+
+msgid ""
+"  # User \"doc_writer\" has write access to any file under the \"docs\"\n"
+"  # folder:\n"
+"  docs/** = doc_writer"
+msgstr ""
+
+msgid ""
+"  # User \"jack\" and group \"designers\" have write access to any file\n"
+"  # under the \"images\" folder:\n"
+"  images/** = jack, @designers"
+msgstr ""
+
+msgid ""
+"  # Everyone (except for \"user6\" - see acl.deny above) will have write\n"
+"  # access to any file under the \"resources\" folder (except for 1\n"
+"  # file. See acl.deny):\n"
+"  src/main/resources/** = *"
+msgstr ""
+
+msgid "  .hgtags = release_engineer"
+msgstr ""
+
+#, python-format
+msgid "group '%s' is undefined"
+msgstr ""
+
+#, python-format
+msgid ""
+"config error - hook type \"%s\" cannot stop incoming changesets nor commits"
+msgstr ""
+
+#, python-format
+msgid "acl: user \"%s\" denied on branch \"%s\" (changeset \"%s\")"
+msgstr ""
+
+#, python-format
+msgid "acl: user \"%s\" not allowed on branch \"%s\" (changeset \"%s\")"
+msgstr ""
+
+#, python-format
+msgid "acl: access denied for changeset %s"
+msgstr ""
+
+msgid "hooks for integrating with the Bugzilla bug tracker"
+msgstr ""
+
+msgid ""
+"This hook extension adds comments on bugs in Bugzilla when changesets\n"
+"that refer to bugs by Bugzilla ID are seen. The comment is formatted using\n"
+"the Mercurial template mechanism."
+msgstr ""
+
+msgid "The hook does not change bug status."
+msgstr ""
+
+msgid "Three basic modes of access to Bugzilla are provided:"
+msgstr ""
+
+msgid ""
+"1. Access via the Bugzilla XMLRPC interface. Requires Bugzilla 3.4 or later."
+msgstr ""
+
+msgid ""
+"2. Check data via the Bugzilla XMLRPC interface and submit bug change\n"
+"   via email to Bugzilla email interface. Requires Bugzilla 3.4 or later."
+msgstr ""
+
+msgid ""
+"3. Writing directly to the Bugzilla database. Only Bugzilla installations\n"
+"   using MySQL are supported. Requires Python MySQLdb."
+msgstr ""
+
+msgid ""
+"Writing directly to the database is susceptible to schema changes, and\n"
+"relies on a Bugzilla contrib script to send out bug change\n"
+"notification emails. This script runs as the user running Mercurial,\n"
+"must be run on the host with the Bugzilla install, and requires\n"
+"permission to read Bugzilla configuration details and the necessary\n"
+"MySQL user and password to have full access rights to the Bugzilla\n"
+"database. For these reasons this access mode is now considered\n"
+"deprecated, and will not be updated for new Bugzilla versions going\n"
+"forward."
+msgstr ""
+
+msgid ""
+"Access via XMLRPC needs a Bugzilla username and password to be specified\n"
+"in the configuration. Comments are added under that username. Since the\n"
+"configuration must be readable by all Mercurial users, it is recommended\n"
+"that the rights of that user are restricted in Bugzilla to the minimum\n"
+"necessary to add comments."
+msgstr ""
+
+msgid ""
+"Access via XMLRPC/email uses XMLRPC to query Bugzilla, but sends\n"
+"email to the Bugzilla email interface to submit comments to bugs.\n"
+"The From: address in the email is set to the email address of the Mercurial\n"
+"user, so the comment appears to come from the Mercurial user. In the event\n"
+"that the Mercurial user email is not recognised by Bugzilla as a Bugzilla\n"
+"user, the email associated with the Bugzilla username used to log into\n"
+"Bugzilla is used instead as the source of the comment."
+msgstr ""
+
+msgid "Configuration items common to all access modes:"
+msgstr ""
+
+msgid ""
+"bugzilla.version\n"
+"  This access type to use. Values recognised are:"
+msgstr ""
+
+msgid ""
+"  :``xmlrpc``:       Bugzilla XMLRPC interface.\n"
+"  :``xmlrpc+email``: Bugzilla XMLRPC and email interfaces.\n"
+"  :``3.0``:          MySQL access, Bugzilla 3.0 and later.\n"
+"  :``2.18``:         MySQL access, Bugzilla 2.18 and up to but not\n"
+"                     including 3.0.\n"
+"  :``2.16``:         MySQL access, Bugzilla 2.16 and up to but not\n"
+"                     including 2.18."
+msgstr ""
+
+msgid ""
+"bugzilla.regexp\n"
+"  Regular expression to match bug IDs in changeset commit message.\n"
+"  Must contain one \"()\" group. The default expression matches ``Bug\n"
+"  1234``, ``Bug no. 1234``, ``Bug number 1234``, ``Bugs 1234,5678``,\n"
+"  ``Bug 1234 and 5678`` and variations thereof. Matching is case\n"
+"  insensitive."
+msgstr ""
+
+msgid ""
+"bugzilla.style\n"
+"  The style file to use when formatting comments."
+msgstr ""
+
+msgid ""
+"bugzilla.template\n"
+"  Template to use when formatting comments. Overrides style if\n"
+"  specified. In addition to the usual Mercurial keywords, the\n"
+"  extension specifies:"
+msgstr ""
+
+msgid ""
+"  :``{bug}``:     The Bugzilla bug ID.\n"
+"  :``{root}``:    The full pathname of the Mercurial repository.\n"
+"  :``{webroot}``: Stripped pathname of the Mercurial repository.\n"
+"  :``{hgweb}``:   Base URL for browsing Mercurial repositories."
+msgstr ""
+
+msgid ""
+"  Default ``changeset {node|short} in repo {root} refers to bug\n"
+"  {bug}.\\ndetails:\\n\\t{desc|tabindent}``"
+msgstr ""
+
+msgid ""
+"bugzilla.strip\n"
+"  The number of path separator characters to strip from the front of\n"
+"  the Mercurial repository path (``{root}`` in templates) to produce\n"
+"  ``{webroot}``. For example, a repository with ``{root}``\n"
+"  ``/var/local/my-project`` with a strip of 2 gives a value for\n"
+"  ``{webroot}`` of ``my-project``. Default 0."
+msgstr ""
+
+msgid ""
+"web.baseurl\n"
+"  Base URL for browsing Mercurial repositories. Referenced from\n"
+"  templates as ``{hgweb}``."
+msgstr ""
+
+msgid "Configuration items common to XMLRPC+email and MySQL access modes:"
+msgstr ""
+
+msgid ""
+"bugzilla.usermap\n"
+"  Path of file containing Mercurial committer email to Bugzilla user email\n"
+"  mappings. If specified, the file should contain one mapping per\n"
+"  line::"
+msgstr ""
+
+msgid "    committer = Bugzilla user"
+msgstr ""
+
+msgid "  See also the ``[usermap]`` section."
+msgstr ""
+
+msgid ""
+"The ``[usermap]`` section is used to specify mappings of Mercurial\n"
+"committer email to Bugzilla user email. See also ``bugzilla.usermap``.\n"
+"Contains entries of the form ``committer = Bugzilla user``."
+msgstr ""
+
+msgid "XMLRPC access mode configuration:"
+msgstr ""
+
+msgid ""
+"bugzilla.bzurl\n"
+"  The base URL for the Bugzilla installation.\n"
+"  Default ``http://localhost/bugzilla``."
+msgstr ""
+
+msgid ""
+"bugzilla.user\n"
+"  The username to use to log into Bugzilla via XMLRPC. Default\n"
+"  ``bugs``."
+msgstr ""
+
+msgid ""
+"bugzilla.password\n"
+"  The password for Bugzilla login."
+msgstr ""
+
+msgid ""
+"XMLRPC+email access mode uses the XMLRPC access mode configuration items,\n"
+"and also:"
+msgstr ""
+
+msgid ""
+"bugzilla.bzemail\n"
+"  The Bugzilla email address."
+msgstr ""
+
+msgid ""
+"In addition, the Mercurial email settings must be configured. See the\n"
+"documentation in hgrc(5), sections ``[email]`` and ``[smtp]``."
+msgstr ""
+
+msgid "MySQL access mode configuration:"
+msgstr ""
+
+msgid ""
+"bugzilla.host\n"
+"  Hostname of the MySQL server holding the Bugzilla database.\n"
+"  Default ``localhost``."
+msgstr ""
+
+msgid ""
+"bugzilla.db\n"
+"  Name of the Bugzilla database in MySQL. Default ``bugs``."
+msgstr ""
+
+msgid ""
+"bugzilla.user\n"
+"  Username to use to access MySQL server. Default ``bugs``."
+msgstr ""
+
+msgid ""
+"bugzilla.password\n"
+"  Password to use to access MySQL server."
+msgstr ""
+
+msgid ""
+"bugzilla.timeout\n"
+"  Database connection timeout (seconds). Default 5."
+msgstr ""
+
+msgid ""
+"bugzilla.bzuser\n"
+"  Fallback Bugzilla user name to record comments with, if changeset\n"
+"  committer cannot be found as a Bugzilla user."
+msgstr ""
+
+msgid ""
+"bugzilla.bzdir\n"
+"   Bugzilla install directory. Used by default notify. Default\n"
+"   ``/var/www/html/bugzilla``."
+msgstr ""
+
+msgid ""
+"bugzilla.notify\n"
+"  The command to run to get Bugzilla to send bug change notification\n"
+"  emails. Substitutes from a map with 3 keys, ``bzdir``, ``id`` (bug\n"
+"  id) and ``user`` (committer bugzilla email). Default depends on\n"
+"  version; from 2.18 it is \"cd %(bzdir)s && perl -T\n"
+"  contrib/sendbugmail.pl %(id)s %(user)s\"."
+msgstr ""
+
+msgid "Activating the extension::"
+msgstr ""
+
+msgid ""
+"    [extensions]\n"
+"    bugzilla ="
+msgstr ""
+
+msgid ""
+"    [hooks]\n"
+"    # run bugzilla hook on every change pulled or pushed in here\n"
+"    incoming.bugzilla = python:hgext.bugzilla.hook"
+msgstr ""
+
+msgid "Example configurations:"
+msgstr ""
+
+msgid ""
+"XMLRPC example configuration. This uses the Bugzilla at\n"
+"``http://my-project.org/bugzilla``, logging in as user\n"
+"``bugmail@my-project.org`` with password ``plugh``. It is used with a\n"
+"collection of Mercurial repositories in ``/var/local/hg/repos/``,\n"
+"with a web interface at ``http://my-project.org/hg``. ::"
+msgstr ""
+
+msgid ""
+"    [bugzilla]\n"
+"    bzurl=http://my-project.org/bugzilla\n"
+"    user=bugmail@my-project.org\n"
+"    password=plugh\n"
+"    version=xmlrpc\n"
+"    template=Changeset {node|short} in {root|basename}.\n"
+"             {hgweb}/{webroot}/rev/{node|short}\\n\n"
+"             {desc}\\n\n"
+"    strip=5"
+msgstr ""
+
+msgid ""
+"    [web]\n"
+"    baseurl=http://my-project.org/hg"
+msgstr ""
+
+msgid ""
+"XMLRPC+email example configuration. This uses the Bugzilla at\n"
+"``http://my-project.org/bugzilla``, logging in as user\n"
+"``bugmail@my-project.org`` wityh password ``plugh``. It is used with a\n"
+"collection of Mercurial repositories in ``/var/local/hg/repos/``,\n"
+"with a web interface at ``http://my-project.org/hg``. Bug comments\n"
+"are sent to the Bugzilla email address\n"
+"``bugzilla@my-project.org``. ::"
+msgstr ""
+
+msgid ""
+"    [bugzilla]\n"
+"    bzurl=http://my-project.org/bugzilla\n"
+"    user=bugmail@my-project.org\n"
+"    password=plugh\n"
+"    version=xmlrpc\n"
+"    bzemail=bugzilla@my-project.org\n"
+"    template=Changeset {node|short} in {root|basename}.\n"
+"             {hgweb}/{webroot}/rev/{node|short}\\n\n"
+"             {desc}\\n\n"
+"    strip=5"
+msgstr ""
+
+msgid ""
+"    [usermap]\n"
+"    user@emaildomain.com=user.name@bugzilladomain.com"
+msgstr ""
+
+msgid ""
+"MySQL example configuration. This has a local Bugzilla 3.2 installation\n"
+"in ``/opt/bugzilla-3.2``. The MySQL database is on ``localhost``,\n"
+"the Bugzilla database name is ``bugs`` and MySQL is\n"
+"accessed with MySQL username ``bugs`` password ``XYZZY``. It is used\n"
+"with a collection of Mercurial repositories in ``/var/local/hg/repos/``,\n"
+"with a web interface at ``http://my-project.org/hg``. ::"
+msgstr ""
+
+msgid ""
+"    [bugzilla]\n"
+"    host=localhost\n"
+"    password=XYZZY\n"
+"    version=3.0\n"
+"    bzuser=unknown@domain.com\n"
+"    bzdir=/opt/bugzilla-3.2\n"
+"    template=Changeset {node|short} in {root|basename}.\n"
+"             {hgweb}/{webroot}/rev/{node|short}\\n\n"
+"             {desc}\\n\n"
+"    strip=5"
+msgstr ""
+
+msgid "All the above add a comment to the Bugzilla bug record of the form::"
+msgstr ""
+
+msgid ""
+"    Changeset 3b16791d6642 in repository-name.\n"
+"    http://my-project.org/hg/repository-name/rev/3b16791d6642"
+msgstr ""
+
+msgid "    Changeset commit comment. Bug 1234.\n"
+msgstr ""
+
+#, python-format
+msgid "python mysql support not available: %s"
+msgstr ""
+
+#, python-format
+msgid "connecting to %s:%s as %s, password %s\n"
+msgstr ""
+
+#, python-format
+msgid "query: %s %s\n"
+msgstr ""
+
+#, python-format
+msgid "failed query: %s %s\n"
+msgstr ""
+
+msgid "unknown database schema"
+msgstr ""
+
+#, python-format
+msgid "bug %d already knows about changeset %s\n"
+msgstr ""
+
+msgid "telling bugzilla to send mail:\n"
+msgstr ""
+
+#, python-format
+msgid "  bug %s\n"
+msgstr ""
+
+#, python-format
+msgid "running notify command %s\n"
+msgstr ""
+
+#, python-format
+msgid "bugzilla notify command %s"
+msgstr ""
+
+msgid "done\n"
+msgstr ""
+
+#, python-format
+msgid "looking up user %s\n"
+msgstr ""
+
+#, python-format
+msgid "cannot find bugzilla user id for %s"
+msgstr ""
+
+#, python-format
+msgid "cannot find bugzilla user id for %s or %s"
+msgstr ""
+
+msgid "configuration 'bzemail' missing"
+msgstr ""
+
+#, python-format
+msgid "default bugzilla user %s email not found"
+msgstr ""
+
+#, python-format
+msgid "bugzilla version %s not supported"
+msgstr ""
+
+msgid ""
+"changeset {node|short} in repo {root} refers to bug {bug}.\n"
+"details:\n"
+"\t{desc|tabindent}"
+msgstr ""
+
+#, python-format
+msgid "hook type %s does not pass a changeset id"
+msgstr ""
+
+#, python-format
+msgid "Bugzilla error: %s"
+msgstr ""
+
+msgid "command to display child changesets"
+msgstr "Команда для отображения дочерних наборов изменений"
+
+msgid "show the children of the given or working directory revision"
+msgstr ""
+"показать дочерние ревизии для заданной текущей ревизии рабочего каталога"
+
+msgid ""
+"    Print the children of the working directory's revisions. If a\n"
+"    revision is given via -r/--rev, the children of that revision will\n"
+"    be printed. If a file argument is given, revision in which the\n"
+"    file was last changed (after the working directory revision or the\n"
+"    argument to --rev if given) is printed.\n"
+"    "
+msgstr ""
+
+msgid "REV"
+msgstr "РЕВИЗИЯ"
+
+msgid "show children of the specified revision"
+msgstr "показать дочерние наборы изменений для указанной ревизии"
+
+msgid "hg children [-r REV] [FILE]"
+msgstr ""
+
+msgid "command to display statistics about repository history"
+msgstr ""
+
+#, python-format
+msgid "Revision %d is a merge, ignoring...\n"
+msgstr ""
+
+msgid "analyzing"
+msgstr ""
+
+msgid "histogram of changes to the repository"
+msgstr ""
+
+msgid ""
+"    This command will display a histogram representing the number\n"
+"    of changed lines or revisions, grouped according to the given\n"
+"    template. The default template will group changes by author.\n"
+"    The --dateformat option may be used to group the results by\n"
+"    date instead."
+msgstr ""
+
+msgid ""
+"    Statistics are based on the number of changed lines, or\n"
+"    alternatively the number of matching revisions if the\n"
+"    --changesets option is specified."
+msgstr ""
+
+msgid "    Examples::"
+msgstr ""
+
+msgid ""
+"      # display count of changed lines for every committer\n"
+"      hg churn -t '{author|email}'"
+msgstr ""
+
+msgid ""
+"      # display daily activity graph\n"
+"      hg churn -f '%H' -s -c"
+msgstr ""
+
+msgid ""
+"      # display activity of developers by month\n"
+"      hg churn -f '%Y-%m' -s -c"
+msgstr ""
+
+msgid ""
+"      # display count of lines changed in every year\n"
+"      hg churn -f '%Y' -s"
+msgstr ""
+
+msgid ""
+"    It is possible to map alternate email addresses to a main address\n"
+"    by providing a file using the following format::"
+msgstr ""
+
+msgid "      <alias email> = <actual email>"
+msgstr ""
+
+msgid ""
+"    Such a file may be specified with the --aliases option, otherwise\n"
+"    a .hgchurn file will be looked for in the working directory root.\n"
+"    "
+msgstr ""
+
+#, python-format
+msgid "skipping malformed alias: %s\n"
+msgstr ""
+
+msgid "count rate for the specified revision or range"
+msgstr ""
+
+msgid "DATE"
+msgstr "ДАТА"
+
+msgid "count rate for revisions matching date spec"
+msgstr ""
+
+msgid "TEMPLATE"
+msgstr ""
+
+msgid "template to group changesets"
+msgstr ""
+
+msgid "FORMAT"
+msgstr "ФОРМАТ"
+
+msgid "strftime-compatible format for grouping by date"
+msgstr ""
+
+msgid "count rate by number of changesets"
+msgstr ""
+
+msgid "sort by key (default: sort by count)"
+msgstr ""
+
+msgid "display added/removed lines separately"
+msgstr ""
+
+msgid "FILE"
+msgstr "ФАЙЛ"
+
+msgid "file with email aliases"
+msgstr ""
+
+msgid "hg churn [-d DATE] [-r REV] [--aliases FILE] [FILE]"
+msgstr ""
+
+msgid "colorize output from some commands"
+msgstr "Раскрашивает вывод некоторых команд"
+
+msgid ""
+"This extension modifies the status and resolve commands to add color\n"
+"to their output to reflect file status, the qseries command to add\n"
+"color to reflect patch status (applied, unapplied, missing), and to\n"
+"diff-related commands to highlight additions, removals, diff headers,\n"
+"and trailing whitespace."
+msgstr ""
+
+msgid ""
+"Other effects in addition to color, like bold and underlined text, are\n"
+"also available. By default, the terminfo database is used to find the\n"
+"terminal codes used to change color and effect.  If terminfo is not\n"
+"available, then effects are rendered with the ECMA-48 SGR control\n"
+"function (aka ANSI escape codes)."
+msgstr ""
+
+msgid "Default effects may be overridden from your configuration file::"
+msgstr ""
+
+msgid ""
+"  [color]\n"
+"  status.modified = blue bold underline red_background\n"
+"  status.added = green bold\n"
+"  status.removed = red bold blue_background\n"
+"  status.deleted = cyan bold underline\n"
+"  status.unknown = magenta bold underline\n"
+"  status.ignored = black bold"
+msgstr ""
+
+msgid ""
+"  # 'none' turns off all effects\n"
+"  status.clean = none\n"
+"  status.copied = none"
+msgstr ""
+
+msgid ""
+"  qseries.applied = blue bold underline\n"
+"  qseries.unapplied = black bold\n"
+"  qseries.missing = red bold"
+msgstr ""
+
+msgid ""
+"  diff.diffline = bold\n"
+"  diff.extended = cyan bold\n"
+"  diff.file_a = red bold\n"
+"  diff.file_b = green bold\n"
+"  diff.hunk = magenta\n"
+"  diff.deleted = red\n"
+"  diff.inserted = green\n"
+"  diff.changed = white\n"
+"  diff.trailingwhitespace = bold red_background"
+msgstr ""
+
+msgid ""
+"  resolve.unresolved = red bold\n"
+"  resolve.resolved = green bold"
+msgstr ""
+
+msgid "  bookmarks.current = green"
+msgstr ""
+
+msgid ""
+"  branches.active = none\n"
+"  branches.closed = black bold\n"
+"  branches.current = green\n"
+"  branches.inactive = none"
+msgstr ""
+
+msgid ""
+"The available effects in terminfo mode are 'blink', 'bold', 'dim',\n"
+"'inverse', 'invisible', 'italic', 'standout', and 'underline'; in\n"
+"ECMA-48 mode, the options are 'bold', 'inverse', 'italic', and\n"
+"'underline'.  How each is rendered depends on the terminal emulator.\n"
+"Some may not be available for a given terminal type, and will be\n"
+"silently ignored."
+msgstr ""
+
+msgid ""
+"Because there are only eight standard colors, this module allows you\n"
+"to define color names for other color slots which might be available\n"
+"for your terminal type, assuming terminfo mode.  For instance::"
+msgstr ""
+
+msgid ""
+"  color.brightblue = 12\n"
+"  color.pink = 207\n"
+"  color.orange = 202"
+msgstr ""
+
+msgid ""
+"to set 'brightblue' to color slot 12 (useful for 16 color terminals\n"
+"that have brighter colors defined in the upper eight) and, 'pink' and\n"
+"'orange' to colors in 256-color xterm's default color cube.  These\n"
+"defined colors may then be used as any of the pre-defined eight,\n"
+"including appending '_background' to set the background to that color."
+msgstr ""
+
+msgid ""
+"The color extension will try to detect whether to use terminfo, ANSI\n"
+"codes or Win32 console APIs, unless it is made explicit; e.g.::"
+msgstr ""
+
+msgid ""
+"  [color]\n"
+"  mode = ansi"
+msgstr ""
+
+msgid ""
+"Any value other than 'ansi', 'win32', 'terminfo', or 'auto' will\n"
+"disable color."
+msgstr ""
+
+msgid "no terminfo entry for setab/setaf: reverting to ECMA-48 color\n"
+msgstr ""
+
+#, python-format
+msgid "ignoring unknown color/effect %r (configured in color.%s)\n"
+msgstr ""
+
+#, python-format
+msgid "warning: failed to set color mode to %s\n"
+msgstr ""
+
+#. i18n: 'always', 'auto', and 'never' are keywords and should
+#. not be translated
+msgid "when to colorize (boolean, always, auto, or never)"
+msgstr ""
+
+msgid "TYPE"
+msgstr "ТИП"
+
+msgid "import revisions from foreign VCS repositories into Mercurial"
+msgstr ""
+"импортирует ревизии из репозиториев других систем контроля версий в Mercurial"
+
+msgid "convert a foreign SCM repository to a Mercurial one."
+msgstr "Преобразовать репозиторий другой SCM в репозиторий Mercurial"
+
+msgid "    Accepted source formats [identifiers]:"
+msgstr "    Возможные входные форматы [идентификаторы]:"
+
+msgid ""
+"    - Mercurial [hg]\n"
+"    - CVS [cvs]\n"
+"    - Darcs [darcs]\n"
+"    - git [git]\n"
+"    - Subversion [svn]\n"
+"    - Monotone [mtn]\n"
+"    - GNU Arch [gnuarch]\n"
+"    - Bazaar [bzr]\n"
+"    - Perforce [p4]"
+msgstr ""
+
+msgid "    Accepted destination formats [identifiers]:"
+msgstr "    Возможные выходные форматы [идентификаторы]:"
+
+msgid ""
+"    - Mercurial [hg]\n"
+"    - Subversion [svn] (history on branches is not preserved)"
+msgstr ""
+"    - Mercurial [hg]\n"
+"    - Subversion [svn] (история на ветках не сохраняется)"
+
+msgid ""
+"    If no revision is given, all revisions will be converted.\n"
+"    Otherwise, convert will only import up to the named revision\n"
+"    (given in a format understood by the source)."
+msgstr ""
+"    Если номер ревизии не указан, преобразуются все ревизии.\n"
+"    В противном случае будут преобразованы только ревизии,\n"
+"    предшествующие указанной. Номер ревизии указывается в формате\n"
+"    источника."
+
+# BAIK
+msgid ""
+"    If no destination directory name is specified, it defaults to the\n"
+"    basename of the source with ``-hg`` appended. If the destination\n"
+"    repository doesn't exist, it will be created."
+msgstr ""
+"    Если не указан каталог назначения, то будет использовано имя\n"
+"    каталога источника с добавленным окончанием ``-hg``. Если каталог\n"
+"    назначения не существует, он будет создан."
+
+msgid ""
+"    By default, all sources except Mercurial will use --branchsort.\n"
+"    Mercurial uses --sourcesort to preserve original revision numbers\n"
+"    order. Sort modes have the following effects:"
+msgstr ""
+"    По умолчанию все источники кроме Mercurial преобразуются с\n"
+"    параметром --branchsort. Для репозитория Mercurial используется\n"
+"    --sourcesort, чтобы сохранить исходный порядок номеров ревизий.\n"
+"    Режимы сортировки имеют следующий смысл:"
+
+msgid ""
+"    --branchsort  convert from parent to child revision when possible,\n"
+"                  which means branches are usually converted one after\n"
+"                  the other. It generates more compact repositories."
+msgstr ""
+"    --branchsort  по возможности преобразует от родительской к\n"
+"                  дочерней ревизии, т.е. ветви обычно ковертируются\n"
+"                  одна за другой. Позволяет генерировать более\n"
+"                  компактные репозитории."
+
+msgid ""
+"    --datesort    sort revisions by date. Converted repositories have\n"
+"                  good-looking changelogs but are often an order of\n"
+"                  magnitude larger than the same ones generated by\n"
+"                  --branchsort."
+msgstr ""
+"    -datesort    сортирует ревизии по дате. Сконвертированные\n"
+"                 репозитории имеют правильно выглядящую историю,\n"
+"                 но часто получаются на порядок больше по сравнению\n"
+"                 c --branchsort."
+
+msgid ""
+"    --sourcesort  try to preserve source revisions order, only\n"
+"                  supported by Mercurial sources."
+msgstr ""
+"    --sourcesort  пытается сохранить исходный порядок ревизий.\n"
+"                  Только для исходных репозиториев Mercurial"
+
+#, fuzzy
+msgid ""
+"    If ``REVMAP`` isn't given, it will be put in a default location\n"
+"    (``<dest>/.hg/shamap`` by default). The ``REVMAP`` is a simple\n"
+"    text file that maps each source commit ID to the destination ID\n"
+"    for that revision, like so::"
+msgstr ""
+"    Если файл ``REVMAP`` не задан, он будет создан по умолчанию\n"
+"    как ``<dest>/.hg/shamap``. ``REVMAP`` - это простой текстовый\n"
+"    файл который устанавливает соответсвие входных и выходных\n"
+"    идентификаторов для каждой ревизии в формате:"
+
+msgid "      <source ID> <destination ID>"
+msgstr "      <входной идентификатор> <выходной идентификатор>"
+
+msgid ""
+"    If the file doesn't exist, it's automatically created. It's\n"
+"    updated on each commit copied, so :hg:`convert` can be interrupted\n"
+"    and can be run repeatedly to copy new commits."
+msgstr ""
+"    Если файл не существует, он создается автоматически. Он\n"
+"    обновляется на каждом копируемом коммите, так что :hg: `convert`\n"
+"    может быть прервано и повторно запущено для копирования новых\n"
+"    коммитов"
+
+msgid ""
+"    The authormap is a simple text file that maps each source commit\n"
+"    author to a destination commit author. It is handy for source SCMs\n"
+"    that use unix logins to identify authors (eg: CVS). One line per\n"
+"    author mapping and the line format is::"
+msgstr ""
+"    authormap - это обычный текстовый файл, который позволяет \n"
+"    заменить в конечном репозитории имена авторов коммитов из \n"
+"    исходного. Это удобно в случае исходной SCM, которая использует \n"
+"    unix-логины в качестве имен авторов (например, CVS). Каждая \n"
+"    строка соответсвует одному имени. Формат строки::"
+
+msgid "      source author = destination author"
+msgstr "      автор в источнике = автор на выходе"
+
+#, fuzzy
+msgid "    Empty lines and lines starting with a ``#`` are ignored."
+msgstr "    Пустые строки и строки, начинающиеся с ``#`` игнорируются\n"
+
+msgid ""
+"    The filemap is a file that allows filtering and remapping of files\n"
+"    and directories. Each line can contain one of the following\n"
+"    directives::"
+msgstr ""
+"    Файл filemap позволяет фильтровать и переименовывать\n"
+"    файлы и каталоги. Каждая строка может содержать одну из следующих\n"
+"    директив::"
+
+msgid "      include path/to/file-or-dir"
+msgstr "      include путь/к/файлу-или-каталогу"
+
+msgid "      exclude path/to/file-or-dir"
+msgstr "      exclude путь/к/файлу-или-каталогу/"
+
+msgid "      rename path/to/source path/to/destination"
+msgstr "      rename путь/к/источнику путь/к/назначению"
+
+msgid ""
+"    Comment lines start with ``#``. A specified path matches if it\n"
+"    equals the full relative name of a file or one of its parent\n"
+"    directories. The ``include`` or ``exclude`` directive with the\n"
+"    longest matching path applies, so line order does not matter."
+msgstr ""
+"    Строки, начинающиеся с ``#`` являются комментариями. Заданный\n"
+"    путь используется, если он совпадает с полным относительным путем\n"
+"    к файлу или одним из его родительских каталогов. Директивы\n"
+"    ``include`` и ``exclude`` применяются для самого длинного из\n"
+"    указанных путей, так что порядок строк не важен."
+
+msgid ""
+"    The ``include`` directive causes a file, or all files under a\n"
+"    directory, to be included in the destination repository, and the\n"
+"    exclusion of all other files and directories not explicitly\n"
+"    included. The ``exclude`` directive causes files or directories to\n"
+"    be omitted. The ``rename`` directive renames a file or directory if\n"
+"    it is converted. To rename from a subdirectory into the root of\n"
+"    the repository, use ``.`` as the path to rename to."
+msgstr ""
+"    Директива ``include`` означает, что в выходной репозиторий\n"
+"    попадет указанный файл или каталог со всеми его файлами и\n"
+"    подкаталогами, а также что остальные файлы, не указанные явно,\n"
+"    будут проигнорированы. Директива ``exclude`` позволяет\n"
+"    игнорировать указанный файл или каталог. Директива ``rename``\n"
+"    переименовывает файл или каталог при конвертации. Чтобы\n"
+"    переместить файл из подкаталога в корень репозитория,\n"
+"    используйте ``.`` в качестве пути назначения."
+
+msgid ""
+"    The splicemap is a file that allows insertion of synthetic\n"
+"    history, letting you specify the parents of a revision. This is\n"
+"    useful if you want to e.g. give a Subversion merge two parents, or\n"
+"    graft two disconnected series of history together. Each entry\n"
+"    contains a key, followed by a space, followed by one or two\n"
+"    comma-separated values::"
+msgstr ""
+"    Файл slicemap позволяет добавлять искуственные части в историю,\n"
+"    позволяя указать родителя для ревизии. Это полезно, например,\n"
+"    если вы хотите привязать две родительские ревизии (parent)\n"
+"    к результату слияния в SVN, или связать две несвязанные части\n"
+"    истории. Каждая запись содержит ключ, отделенный пробелом от\n"
+"    одного или двух параметров, разделяемых запятой::"
+
+msgid "      key parent1, parent2"
+msgstr "      ключ родитель1, родитель2"
+
+msgid ""
+"    The key is the revision ID in the source\n"
+"    revision control system whose parents should be modified (same\n"
+"    format as a key in .hg/shamap). The values are the revision IDs\n"
+"    (in either the source or destination revision control system) that\n"
+"    should be used as the new parents for that node. For example, if\n"
+"    you have merged \"release-1.0\" into \"trunk\", then you should\n"
+"    specify the revision on \"trunk\" as the first parent and the one on\n"
+"    the \"release-1.0\" branch as the second."
+msgstr ""
+"    Ключ - это идентификатор ревизии в исходном репозитории, чьи\n"
+"    родители должны быть изменены (тот же формат, что и в файле\n"
+"    .hg/shamap). Параметры являются номерами ревизий (во входном\n"
+"    или выходном репозитории), которые используются в качестве\n"
+"    новых родителей для данного узла. Например, если были слиты\n"
+"    ветви \"release-1.0\" и \"trunc\", то нужно указать номер\n"
+"    ревизии в ветви \"trunc\" в качестве родитель1, и номер ревизии\n"
+"    в ветви \"release-1.0\" в качестве родитель2."
+
+msgid ""
+"    The branchmap is a file that allows you to rename a branch when it is\n"
+"    being brought in from whatever external repository. When used in\n"
+"    conjunction with a splicemap, it allows for a powerful combination\n"
+"    to help fix even the most badly mismanaged repositories and turn them\n"
+"    into nicely structured Mercurial repositories. The branchmap contains\n"
+"    lines of the form::"
+msgstr ""
+"    Файл branchmap позволяет переименовать ветвь из любого внешнего\n"
+"    репозитория. При использовании вместе с splicemap, предоставляет\n"
+"    хорошие возможности упорядочить даже самые запутанные\n"
+"    репозитории и преобразовать их в хорошо структурированный\n"
+"    репозиторий Mercurial. Содержит строки в формате:"
+
+msgid "      original_branch_name new_branch_name"
+msgstr "      исходное_имя_ветви новое_имя_ветви"
+
+msgid ""
+"    where \"original_branch_name\" is the name of the branch in the\n"
+"    source repository, and \"new_branch_name\" is the name of the branch\n"
+"    is the destination repository. No whitespace is allowed in the\n"
+"    branch names. This can be used to (for instance) move code in one\n"
+"    repository from \"default\" to a named branch."
+msgstr ""
+"    где \"исходное_имя_ветви\" - это имя ветви в исходном репозитории\n"
+"    \"новое_имя_ветви\" - имя ветви в выходном репозитории. Пробелы\n"
+"    в именах ветвей не допускаются. Этим можно пользоваться,\n"
+"    например, чтобы переместить код с ветви \"default\" на именованную\n"
+"    ветвь."
+
+msgid ""
+"    Mercurial Source\n"
+"    ''''''''''''''''"
+msgstr ""
+"    Источник - Mercurial\n"
+"    ''''''''''''''''''''''''''''''''"
+
+msgid ""
+"    The Mercurial source recognizes the following configuration\n"
+"    options, which you can set on the command line with ``--config``:"
+msgstr ""
+"    При конвертации из репозитория Mercurial возможны следующие\n"
+"    параметры, которые можно указать в командной строке с помощью\n"
+"    ``--config``:"
+
+msgid ""
+"    :convert.hg.ignoreerrors: ignore integrity errors when reading.\n"
+"        Use it to fix Mercurial repositories with missing revlogs, by\n"
+"        converting from and to Mercurial. Default is False."
+msgstr ""
+"    :convert.hg.ignoreerrors: игнорировать ошибки целостности при\n"
+"        чтении. Используется для восстановления репозиториев Mercurial\n"
+"        c недостающими revlog'ами путем ковертации из репозитория\n"
+"        Mercurial и обратно. По умолчанию False."
+
+msgid ""
+"    :convert.hg.saverev: store original revision ID in changeset\n"
+"        (forces target IDs to change). It takes and boolean argument\n"
+"        and defaults to False."
+msgstr ""
+"    :convert.hg.saverev: созранять исходный номер ревизии в наборе\n"
+"        изменений (изменяет выходные номера ревизий).\n"
+"        True или False, по умолчанию False."
+
+msgid ""
+"    :convert.hg.startrev: convert start revision and its descendants.\n"
+"        It takes a hg revision identifier and defaults to 0."
+msgstr ""
+"    :convert.hg.startrev: конвертировать указанную ревизию и все ее\n"
+"        дочерние ревизии. Принимает номер ревизии Mercurial,\n"
+"        по умолчанию 0."
+
+msgid ""
+"    CVS Source\n"
+"    ''''''''''"
+msgstr ""
+"    Источник - CVS\n"
+"    ''''''''''''''''''''''''''"
+
+msgid ""
+"    CVS source will use a sandbox (i.e. a checked-out copy) from CVS\n"
+"    to indicate the starting point of what will be converted. Direct\n"
+"    access to the repository files is not needed, unless of course the\n"
+"    repository is ``:local:``. The conversion uses the top level\n"
+"    directory in the sandbox to find the CVS repository, and then uses\n"
+"    CVS rlog commands to find files to convert. This means that unless\n"
+"    a filemap is given, all files under the starting directory will be\n"
+"    converted, and that any directory reorganization in the CVS\n"
+"    sandbox is ignored."
+msgstr ""
+"    При конвертировании из CVS используется песочница (т.е. копия,\n"
+"    полученная с помощью cvs checkout), которая нужна в качестве\n"
+"    отправной точки для конвертации. Прямой доступ к файлам\n"
+"    репозитория CVS не требутся, если, конечно, не используется\n"
+"    метод доступа ``:local:``. Репозиторий CVS ищется по каталогу\n"
+"    верхнего уровня песочницы, после чего используется команда\n"
+"    CVS rlog для поиска конвертирумых файлов. Это означает, что\n"
+"    если не задан файл filemap, будут конвертироваться все файлы\n"
+"    из верхнего каталога, и все изменения структуры каталогов в\n"
+"    песочнице будут проигнорированы."
+
+msgid "    The following options can be used with ``--config``:"
+msgstr "    Следующие параметры могут использоваться с ``--config``:"
+
+msgid ""
+"    :convert.cvsps.cache: Set to False to disable remote log caching,\n"
+"        for testing and debugging purposes. Default is True."
+msgstr ""
+"    :convert.cvsps.cache: Установите в False чтобы отключить\n"
+"        кеширование удаленного лога, нужно для тестирования и\n"
+"        отладки. По умолчанию True."
+
+msgid ""
+"    :convert.cvsps.fuzz: Specify the maximum time (in seconds) that is\n"
+"        allowed between commits with identical user and log message in\n"
+"        a single changeset. When very large files were checked in as\n"
+"        part of a changeset then the default may not be long enough.\n"
+"        The default is 60."
+msgstr ""
+"    :convert.cvsps.fuzz: задает максимально допустимое время \n"
+"        (в секундах) между коммитами с одинаковыми пользователем \n"
+"        и журнальным сообщением в рамках одного набора изменений.        "
+"Значения по умолчанию может не хватить, если очень большие файлы были\n"
+"        сохранены в наборе изменений. По умолчанию 60 сек."
+
+msgid ""
+"    :convert.cvsps.mergeto: Specify a regular expression to which\n"
+"        commit log messages are matched. If a match occurs, then the\n"
+"        conversion process will insert a dummy revision merging the\n"
+"        branch on which this log message occurs to the branch\n"
+"        indicated in the regex. Default is ``{{mergetobranch\n"
+"        ([-\\w]+)}}``"
+msgstr ""
+"    :convert.cvsps.mergeto: задает регулярное выражение, на\n"
+"        совпадение с которым проверяются журнальные сообщения. При\n"
+"        совпадении будет вставлена фиктивная ревизия, сливающая\n"
+"        ветвь с этим сообщением с указанной в регулярном выражении\n"
+"        веткой. Значение по умолчанию: ``{{mergetobranch ([-\\w]+)}}``"
+
+msgid ""
+"    :convert.cvsps.mergefrom: Specify a regular expression to which\n"
+"        commit log messages are matched. If a match occurs, then the\n"
+"        conversion process will add the most recent revision on the\n"
+"        branch indicated in the regex as the second parent of the\n"
+"        changeset. Default is ``{{mergefrombranch ([-\\w]+)}}``"
+msgstr ""
+
+msgid ""
+"    :hook.cvslog: Specify a Python function to be called at the end of\n"
+"        gathering the CVS log. The function is passed a list with the\n"
+"        log entries, and can modify the entries in-place, or add or\n"
+"        delete them."
+msgstr ""
+"    :hook.cvslog: задает функцию на Питоне, которая вызывается после\n"
+"        получения журнала CVS. Функции передается список с журнальными\n"
+"        записями, она может изменять их, удалять или добавлять новые."
+
+msgid ""
+"    :hook.cvschangesets: Specify a Python function to be called after\n"
+"        the changesets are calculated from the the CVS log. The\n"
+"        function is passed a list with the changeset entries, and can\n"
+"        modify the changesets in-place, or add or delete them."
+msgstr ""
+"    :hook.cvschangesets: Задает функцию на Питоне, которая вызывается\n"
+"        после того, как будут расчитаны наборы изменений из журнала\n"
+"        CVS. Функции передается список с элементами набора изменений,\n"
+"        она может изменять их, удалять или добавлять новые."
+
+#, fuzzy
+msgid ""
+"    An additional \"debugcvsps\" Mercurial command allows the builtin\n"
+"    changeset merging code to be run without doing a conversion. Its\n"
+"    parameters and output are similar to that of cvsps 2.1. Please see\n"
+"    the command help for more details."
+msgstr ""
+"    Дополнительная команда Mercurial \"debugcvsps\" позволяет\n"
+"    запустить встроенный код слияния набора изменений без проведения\n"
+"    конвертации. Ее параметры и вывод похожи на cvsps 2.1. Подробней\n"
+"    см. справку по cvsps."
+
+msgid ""
+"    Subversion Source\n"
+"    '''''''''''''''''"
+msgstr ""
+"    Источник - Subversion\n"
+"    '''''''''''''''''''''"
+
+msgid ""
+"    Subversion source detects classical trunk/branches/tags layouts.\n"
+"    By default, the supplied ``svn://repo/path/`` source URL is\n"
+"    converted as a single branch. If ``svn://repo/path/trunk`` exists\n"
+"    it replaces the default branch. If ``svn://repo/path/branches``\n"
+"    exists, its subdirectories are listed as possible branches. If\n"
+"    ``svn://repo/path/tags`` exists, it is looked for tags referencing\n"
+"    converted branches. Default ``trunk``, ``branches`` and ``tags``\n"
+"    values can be overridden with following options. Set them to paths\n"
+"    relative to the source URL, or leave them blank to disable auto\n"
+"    detection."
+msgstr ""
+"    В случае Subversion анализируется классическая структура\n"
+"    репозитория trunk/branches/tags. По умолчанию заданный URL\n"
+"    ``svn://репозиторий/путь`` преобразуется в одну ветку. Если\n"
+"    ``svn://репозиторий/путь/trunc`` существует, он заменяет ветку\n"
+"    ``default``. Если ``svn://репозиторий/путь/branches`` существует,\n"
+"     его подкаталоги перечисляются как возможные ветви. Если\n"
+"     ``svn://репозиторий/путь/tags`` существует, в нем ищутся\n"
+"     метки, ссылающиеся на конвертируемые ветви. Значения по умолчанию\n"
+"     для ``trunc``, ``branches`` и ``tags`` могут быть изменены\n"
+"     нижеперечисленными параметрами. Установите их в пути относительно\n"
+"     URL источника или оставьте пустыми чтобы отключить автоматическое\n"
+"     определение."
+
+msgid "    The following options can be set with ``--config``:"
+msgstr "    Следующие параметры могут быть заданы в ``--config``:"
+
+msgid ""
+"    :convert.svn.branches: specify the directory containing branches.\n"
+"        The default is ``branches``."
+msgstr ""
+"    :convert.svn.branches: задает каталог, содержащий ветви.\n"
+"        По умолчанию ``branches``."
+
+msgid ""
+"    :convert.svn.tags: specify the directory containing tags. The\n"
+"        default is ``tags``."
+msgstr ""
+"    :convert.svn.tags: задает каталог, содержащий метки.\n"
+"        По умолчанию``tags``."
+
+msgid ""
+"    :convert.svn.trunk: specify the name of the trunk branch. The\n"
+"        default is ``trunk``."
+msgstr ""
+"    :convert.svn.trunk: задает имя главной ветви (trunc)\n"
+"        По умолчанию ``trunk``."
+
+msgid ""
+"    Source history can be retrieved starting at a specific revision,\n"
+"    instead of being integrally converted. Only single branch\n"
+"    conversions are supported."
+msgstr ""
+"    История может извлекаться начиная с указанной ревизии, а не\n"
+"    обязательно полностью. Поддерживается только преобразования\n"
+"    для одной ветви."
+
+msgid ""
+"    :convert.svn.startrev: specify start Subversion revision number.\n"
+"        The default is 0."
+msgstr ""
+"    :convert.svn.startrev: задает начальный номер ревизии Subversion.\n"
+"        По умолчанию 0."
+
+msgid ""
+"    Perforce Source\n"
+"    '''''''''''''''"
+msgstr ""
+"    Источник - Perforce\n"
+"    '''''''''''''''''''"
+
+msgid ""
+"    The Perforce (P4) importer can be given a p4 depot path or a\n"
+"    client specification as source. It will convert all files in the\n"
+"    source to a flat Mercurial repository, ignoring labels, branches\n"
+"    and integrations. Note that when a depot path is given you then\n"
+"    usually should specify a target directory, because otherwise the\n"
+"    target may be named ``...-hg``."
+msgstr ""
+"    При импорте из Perforce (P4) в качестве источника можно задать    путь к "
+"хранилищу или спецификацию клиента. Все файлы источика\n"
+"    будут преобразованы в простой репозиторий Mercurial, метки,\n"
+"    ветви и точки интеграции игнорируются. Обратите внимание, что при\n"
+"    задании пути к хранилищу обычно надо указать также каталог \n"
+"    назначения, потому что иначе он может быть назван ``...-hg``."
+
+msgid ""
+"    It is possible to limit the amount of source history to be\n"
+"    converted by specifying an initial Perforce revision:"
+msgstr ""
+"    Можно ограничить количество конвертируемых записей, указав\n"
+"    начальную ревизию Perforce:"
+
+msgid ""
+"    :convert.p4.startrev: specify initial Perforce revision (a\n"
+"        Perforce changelist number)."
+msgstr ""
+"    :convert.p4.startrev: задает начальную ревизию Perforce\n"
+"        (номер списка изменений Perforce)."
+
+msgid ""
+"    Mercurial Destination\n"
+"    '''''''''''''''''''''"
+msgstr ""
+"    Выходной репозиторий Mercurial\n"
+"    ''''''''''''''''''''''''''''''"
+
+msgid "    The following options are supported:"
+msgstr "    Поддерживаются следующие параметры:"
+
+#, fuzzy
+msgid ""
+"    :convert.hg.clonebranches: dispatch source branches in separate\n"
+"        clones. The default is False."
+msgstr ""
+"    :convert.hg.clonebranches: создавать отдельные репозитории на\n"
+"        каждую ветвь источника. По умолчанию False."
+
+#, fuzzy
+msgid ""
+"    :convert.hg.tagsbranch: branch name for tag revisions, defaults to\n"
+"        ``default``."
+msgstr ""
+"    :convert.hg.tagsbranch: имя ветви для помеченных ревизий,\n"
+"         по умолчанию ``default``\n"
+
+msgid ""
+"    :convert.hg.usebranchnames: preserve branch names. The default is\n"
+"        True.\n"
+"    "
+msgstr ""
+"    :convert.hg.usebranchnames: сохранять имена ветвей. По умолчанию\n"
+"        True.\n"
+"    "
+
+msgid "create changeset information from CVS"
+msgstr "получить информацию о наборе изменений из CVS"
+
+msgid ""
+"    This command is intended as a debugging tool for the CVS to\n"
+"    Mercurial converter, and can be used as a direct replacement for\n"
+"    cvsps."
+msgstr ""
+"    Эта команда используется в качестве отладочного инструмента для \n"
+"    конвертера CVS->Mercurial и может быть использована в качестве \n"
+"    замены для cvsps"
+
+msgid ""
+"    Hg debugcvsps reads the CVS rlog for current directory (or any\n"
+"    named directory) in the CVS repository, and converts the log to a\n"
+"    series of changesets based on matching commit log entries and\n"
+"    dates."
+msgstr ""
+"    Команда Mercurial debugcvsps читает журнал CVS через rlog для\n"
+"    текущего каталога (или другого указанного каталога) в репозитории\n"
+"    CVS и преобразует ее журнал в поледовательность наборов изменений\n"
+"    основанных на соответсвующих журнальных записях и датах."
+
+msgid "username mapping filename (DEPRECATED, use --authormap instead)"
+msgstr ""
+"файл переназначения имен пользователей (УСТАРЕЛО, используйте --authormap)"
+
+msgid "source repository type"
+msgstr "тип репозитория источника"
+
+msgid "destination repository type"
+msgstr "тип репозитория назначения"
+
+msgid "import up to target revision REV"
+msgstr "импортировать до ревизии РЕВИЗИЯ"
+
+msgid "remap usernames using this file"
+msgstr "переназначить имена пользователей используя этот файл"
+
+msgid "remap file names using contents of file"
+msgstr "переназначить имена файлов согласно файлу"
+
+msgid "splice synthesized history into place"
+msgstr ""
+
+msgid "change branch names while converting"
+msgstr "изменить имена ветвей при конвертации"
+
+msgid "try to sort changesets by branches"
+msgstr "попытаться отсортировать наборы изменений по ветвям"
+
+msgid "try to sort changesets by date"
+msgstr "попытаться отсортировать наборы изменений по дате"
+
+msgid "preserve source changesets order"
+msgstr "сохранять порядок ревизий источника"
+
+msgid "hg convert [OPTION]... SOURCE [DEST [REVMAP]]"
+msgstr "hg convert [ПАРАМЕТР]... ИСТОЧНИК [НАЗН [REVMAP]]"
+
+msgid "only return changes on specified branches"
+msgstr "возвращать только изменения на указанных ветвях"
+
+msgid "prefix to remove from file names"
+msgstr "удалить этот префикс из имен файлов"
+
+msgid "only return changes after or between specified tags"
+msgstr "возвращать только изменения после или между указанными метками"
+
+msgid "update cvs log cache"
+msgstr "обновить кэш жирнала cvs"
+
+msgid "create new cvs log cache"
+msgstr "создать новый кэш лога cvs"
+
+msgid "set commit time fuzz in seconds"
+msgstr ""
+
+msgid "specify cvsroot"
+msgstr "задать cvsroot"
+
+msgid "show parent changesets"
+msgstr "указать родительские ревизии"
+
+msgid "show current changeset in ancestor branches"
+msgstr "показывать текущий набор изменений на родительских ветвях"
+
+msgid "ignored for compatibility"
+msgstr "игнорировать для совместимости"
+
+msgid "hg debugcvsps [OPTION]... [PATH]..."
+msgstr "hg debugcvsps [ПАРАМЕТР]... [ПУТЬ]..."
+
+msgid ":svnrev: String. Converted subversion revision number."
+msgstr ""
+
+msgid ":svnpath: String. Converted subversion revision project path."
+msgstr ""
+
+msgid ":svnuuid: String. Converted subversion revision repository identifier."
+msgstr ""
+
+#, python-format
+msgid "%s does not look like a Bazaar repository"
+msgstr ""
+
+msgid "Bazaar modules could not be loaded"
+msgstr ""
+
+msgid ""
+"warning: lightweight checkouts may cause conversion failures, try with a "
+"regular branch instead.\n"
+msgstr ""
+
+msgid "bzr source type could not be determined\n"
+msgstr ""
+
+#, python-format
+msgid "%s is not a valid revision in current branch"
+msgstr ""
+
+#, python-format
+msgid "%s is not available in %s anymore"
+msgstr ""
+
+#, python-format
+msgid "%s.%s symlink has no target"
+msgstr ""
+
+#, python-format
+msgid "cannot find required \"%s\" tool"
+msgstr ""
+
+#, python-format
+msgid "%s error:\n"
+msgstr ""
+
+#, python-format
+msgid "syntax error in %s(%d): key/value pair expected"
+msgstr ""
+
+#, python-format
+msgid "could not open map file %r: %s"
+msgstr ""
+
+#, python-format
+msgid "%s: invalid source repository type"
+msgstr ""
+
+#, python-format
+msgid "%s: missing or unsupported repository"
+msgstr ""
+
+#, python-format
+msgid "%s: invalid destination repository type"
+msgstr ""
+
+#, python-format
+msgid "convert: %s\n"
+msgstr ""
+
+#, python-format
+msgid "%s: unknown repository type"
+msgstr ""
+
+msgid "getting files"
+msgstr ""
+
+msgid "revisions"
+msgstr ""
+
+msgid "scanning"
+msgstr ""
+
+#, python-format
+msgid "unknown sort mode: %s"
+msgstr ""
+
+#, python-format
+msgid "cycle detected between %s and %s"
+msgstr ""
+
+msgid "not all revisions were sorted"
+msgstr ""
+
+#, python-format
+msgid "Writing author map file %s\n"
+msgstr ""
+
+#, python-format
+msgid "Ignoring bad line in author map file %s: %s\n"
+msgstr ""
+
+#, python-format
+msgid "mapping author %s to %s\n"
+msgstr ""
+
+#, python-format
+msgid "overriding mapping for author %s, was %s, will be %s\n"
+msgstr ""
+
+#, python-format
+msgid "spliced in %s as parents of %s\n"
+msgstr ""
+
+msgid "scanning source...\n"
+msgstr ""
+
+msgid "sorting...\n"
+msgstr ""
+
+msgid "converting...\n"
+msgstr ""
+
+#, python-format
+msgid "source: %s\n"
+msgstr ""
+
+msgid "converting"
+msgstr ""
+
+#, python-format
+msgid "assuming destination %s\n"
+msgstr ""
+
+msgid "more than one sort mode specified"
+msgstr ""
+
+msgid "--sourcesort is not supported by this data source"
+msgstr ""
+
+#, python-format
+msgid "%s does not look like a CVS checkout"
+msgstr ""
+
+#, python-format
+msgid "revision %s is not a patchset number"
+msgstr ""
+
+#, python-format
+msgid "connecting to %s\n"
+msgstr ""
+
+msgid "CVS pserver authentication failed"
+msgstr ""
+
+#, python-format
+msgid ""
+"unexpected response from CVS server (expected \"Valid-requests\", but got %r)"
+msgstr ""
+
+#, python-format
+msgid "%d bytes missing from remote file"
+msgstr ""
+
+msgid "malformed response from CVS"
+msgstr ""
+
+#, python-format
+msgid "cvs server: %s\n"
+msgstr ""
+
+#, python-format
+msgid "unknown CVS response: %s"
+msgstr ""
+
+msgid "collecting CVS rlog\n"
+msgstr ""
+
+msgid "not a CVS sandbox"
+msgstr ""
+
+#, python-format
+msgid "reading cvs log cache %s\n"
+msgstr ""
+
+#, python-format
+msgid "cache has %d log entries\n"
+msgstr ""
+
+#, python-format
+msgid "error reading cache: %r\n"
+msgstr ""
+
+#, python-format
+msgid "running %s\n"
+msgstr ""
+
+msgid "RCS file must be followed by working file"
+msgstr ""
+
+msgid "must have at least some revisions"
+msgstr ""
+
+msgid "expected revision number"
+msgstr ""
+
+msgid "revision must be followed by date line"
+msgstr ""
+
+msgid "log cache overlaps with new log entries, re-run without cache."
+msgstr ""
+
+#, python-format
+msgid "writing cvs log cache %s\n"
+msgstr ""
+
+#, python-format
+msgid "%d log entries\n"
+msgstr ""
+
+msgid "creating changesets\n"
+msgstr ""
+
+msgid "synthetic changeset cannot have multiple parents"
+msgstr ""
+
+#, python-format
+msgid ""
+"warning: CVS commit message references non-existent branch %r:\n"
+"%s\n"
+msgstr ""
+
+#, python-format
+msgid "%d changeset entries\n"
+msgstr ""
+
+#, python-format
+msgid "%s does not look like a darcs repository"
+msgstr ""
+
+#, python-format
+msgid "darcs version 2.1 or newer needed (found %r)"
+msgstr ""
+
+msgid "Python ElementTree module is not available"
+msgstr ""
+
+#, python-format
+msgid "%s repository format is unsupported, please upgrade"
+msgstr ""
+
+msgid "failed to detect repository format!"
+msgstr ""
+
+msgid "internal calling inconsistency"
+msgstr ""
+
+msgid "errors in filemap"
+msgstr ""
+
+#, python-format
+msgid "%s:%d: path to %s is missing\n"
+msgstr ""
+
+#, python-format
+msgid "%s:%d: %r already in %s list\n"
+msgstr ""
+
+#, python-format
+msgid "%s:%d: superfluous / in %s %r\n"
+msgstr ""
+
+#, python-format
+msgid "%s:%d: unknown directive %r\n"
+msgstr ""
+
+msgid "source repository doesn't support --filemap"
+msgstr ""
+
+#, python-format
+msgid "%s does not look like a Git repository"
+msgstr ""
+
+msgid "cannot retrieve git heads"
+msgstr ""
+
+#, python-format
+msgid "cannot read %r object at %s"
+msgstr ""
+
+#, python-format
+msgid "cannot read changes in %s"
+msgstr ""
+
+#, python-format
+msgid "cannot read tags from %s"
+msgstr ""
+
+#, python-format
+msgid "%s does not look like a GNU Arch repository"
+msgstr ""
+
+msgid "cannot find a GNU Arch tool"
+msgstr ""
+
+#, python-format
+msgid "analyzing tree version %s...\n"
+msgstr ""
+
+#, python-format
+msgid ""
+"tree analysis stopped because it points to an unregistered archive %s...\n"
+msgstr ""
+
+#, python-format
+msgid "could not parse cat-log of %s"
+msgstr ""
+
+#, python-format
+msgid "%s is not a local Mercurial repository"
+msgstr ""
+
+#, python-format
+msgid "initializing destination %s repository\n"
+msgstr ""
+
+#, python-format
+msgid "could not create hg repository %s as sink"
+msgstr ""
+
+#, python-format
+msgid "pulling from %s into %s\n"
+msgstr ""
+
+msgid "filtering out empty revision\n"
+msgstr ""
+
+msgid "updating tags\n"
+msgstr ""
+
+msgid "updating bookmarks\n"
+msgstr ""
+
+#, python-format
+msgid "%s is not a valid start revision"
+msgstr ""
+
+#, python-format
+msgid "ignoring: %s\n"
+msgstr ""
+
+#, python-format
+msgid "%s does not look like a monotone repository"
+msgstr ""
+
+msgid "bad mtn packet - no end of commandnbr"
+msgstr ""
+
+#, python-format
+msgid "bad mtn packet - bad stream type %s"
+msgstr ""
+
+msgid "bad mtn packet - no divider before size"
+msgstr ""
+
+msgid "bad mtn packet - no end of packet size"
+msgstr ""
+
+#, python-format
+msgid "bad mtn packet - bad packet size %s"
+msgstr ""
+
+#, python-format
+msgid "bad mtn packet - unable to read full packet read %s of %s"
+msgstr ""
+
+#, python-format
+msgid "mtn command '%s' returned %s"
+msgstr ""
+
+#, python-format
+msgid "copying file in renamed directory from '%s' to '%s'"
+msgstr ""
+
+msgid "unable to determine mtn automate interface version"
+msgstr ""
+
+#, python-format
+msgid "mtn automate stdio header unexpected: %s"
+msgstr ""
+
+msgid "failed to reach end of mtn automate stdio headers"
+msgstr ""
+
+#, python-format
+msgid "%s does not look like a P4 repository"
+msgstr ""
+
+msgid "reading p4 views\n"
+msgstr ""
+
+msgid "collecting p4 changelists\n"
+msgstr ""
+
+msgid "Mercurial failed to run itself, check hg executable is in PATH"
+msgstr ""
+
+msgid ""
+"svn: cannot probe remote repository, assume it could be a subversion "
+"repository. Use --source-type if you know better.\n"
+msgstr ""
+
+#, python-format
+msgid "%s does not look like a Subversion repository"
+msgstr ""
+
+msgid "Could not load Subversion python bindings"
+msgstr ""
+
+#, python-format
+msgid "Subversion python bindings %d.%d found, 1.4 or later required"
+msgstr ""
+
+msgid "Subversion python bindings are too old, 1.4 or later required"
+msgstr ""
+
+#, python-format
+msgid "svn: revision %s is not an integer"
+msgstr ""
+
+#, python-format
+msgid "svn: start revision %s is not an integer"
+msgstr ""
+
+#, python-format
+msgid "no revision found in module %s"
+msgstr ""
+
+#, python-format
+msgid "expected %s to be at %r, but not found"
+msgstr ""
+
+#, python-format
+msgid "found %s at %r\n"
+msgstr ""
+
+#, python-format
+msgid "ignoring empty branch %s\n"
+msgstr ""
+
+#, python-format
+msgid "found branch %s at %d\n"
+msgstr ""
+
+msgid "svn: start revision is not supported with more than one branch"
+msgstr ""
+
+#, python-format
+msgid "svn: no revision found after start revision %d"
+msgstr ""
+
+#, python-format
+msgid "%s not found up to revision %d"
+msgstr ""
+
+msgid "scanning paths"
+msgstr ""
+
+#, python-format
+msgid "found parent of branch %s at %d: %s\n"
+msgstr ""
+
+#, python-format
+msgid "fetching revision log for \"%s\" from %d to %d\n"
+msgstr ""
+
+#, python-format
+msgid "svn: branch has no revision %s"
+msgstr ""
+
+#, python-format
+msgid "initializing svn repository %r\n"
+msgstr ""
+
+#, python-format
+msgid "initializing svn working copy %r\n"
+msgstr ""
+
+msgid "unexpected svn output:\n"
+msgstr ""
+
+msgid "unable to cope with svn output"
+msgstr ""
+
+msgid "writing Subversion tags is not yet implemented\n"
+msgstr ""
+
+msgid "automatically manage newlines in repository files"
+msgstr ""
+
+msgid ""
+"This extension allows you to manage the type of line endings (CRLF or\n"
+"LF) that are used in the repository and in the local working\n"
+"directory. That way you can get CRLF line endings on Windows and LF on\n"
+"Unix/Mac, thereby letting everybody use their OS native line endings."
+msgstr ""
+
+msgid ""
+"The extension reads its configuration from a versioned ``.hgeol``\n"
+"configuration file found in the root of the working copy. The\n"
+"``.hgeol`` file use the same syntax as all other Mercurial\n"
+"configuration files. It uses two sections, ``[patterns]`` and\n"
+"``[repository]``."
+msgstr ""
+
+msgid ""
+"The ``[patterns]`` section specifies how line endings should be\n"
+"converted between the working copy and the repository. The format is\n"
+"specified by a file pattern. The first match is used, so put more\n"
+"specific patterns first. The available line endings are ``LF``,\n"
+"``CRLF``, and ``BIN``."
+msgstr ""
+
+msgid ""
+"Files with the declared format of ``CRLF`` or ``LF`` are always\n"
+"checked out and stored in the repository in that format and files\n"
+"declared to be binary (``BIN``) are left unchanged. Additionally,\n"
+"``native`` is an alias for checking out in the platform's default line\n"
+"ending: ``LF`` on Unix (including Mac OS X) and ``CRLF`` on\n"
+"Windows. Note that ``BIN`` (do nothing to line endings) is Mercurial's\n"
+"default behaviour; it is only needed if you need to override a later,\n"
+"more general pattern."
+msgstr ""
+
+msgid ""
+"The optional ``[repository]`` section specifies the line endings to\n"
+"use for files stored in the repository. It has a single setting,\n"
+"``native``, which determines the storage line endings for files\n"
+"declared as ``native`` in the ``[patterns]`` section. It can be set to\n"
+"``LF`` or ``CRLF``. The default is ``LF``. For example, this means\n"
+"that on Windows, files configured as ``native`` (``CRLF`` by default)\n"
+"will be converted to ``LF`` when stored in the repository. Files\n"
+"declared as ``LF``, ``CRLF``, or ``BIN`` in the ``[patterns]`` section\n"
+"are always stored as-is in the repository."
+msgstr ""
+
+msgid "Example versioned ``.hgeol`` file::"
+msgstr ""
+
+msgid ""
+"  [patterns]\n"
+"  **.py = native\n"
+"  **.vcproj = CRLF\n"
+"  **.txt = native\n"
+"  Makefile = LF\n"
+"  **.jpg = BIN"
+msgstr ""
+
+msgid ""
+"  [repository]\n"
+"  native = LF"
+msgstr ""
+
+msgid ""
+".. note::\n"
+"   The rules will first apply when files are touched in the working\n"
+"   copy, e.g. by updating to null and back to tip to touch all files."
+msgstr ""
+
+msgid ""
+"The extension uses an optional ``[eol]`` section in your hgrc file\n"
+"(not the ``.hgeol`` file) for settings that control the overall\n"
+"behavior. There are two settings:"
+msgstr ""
+
+msgid ""
+"- ``eol.native`` (default ``os.linesep``) can be set to ``LF`` or\n"
+"  ``CRLF`` to override the default interpretation of ``native`` for\n"
+"  checkout. This can be used with :hg:`archive` on Unix, say, to\n"
+"  generate an archive where files have line endings for Windows."
+msgstr ""
+
+msgid ""
+"- ``eol.only-consistent`` (default True) can be set to False to make\n"
+"  the extension convert files with inconsistent EOLs. Inconsistent\n"
+"  means that there is both ``CRLF`` and ``LF`` present in the file.\n"
+"  Such files are normally not touched under the assumption that they\n"
+"  have mixed EOLs on purpose."
+msgstr ""
+
+msgid ""
+"The extension provides ``cleverencode:`` and ``cleverdecode:`` filters\n"
+"like the deprecated win32text extension does. This means that you can\n"
+"disable win32text and enable eol and your filters will still work. You\n"
+"only need to these filters until you have prepared a ``.hgeol`` file."
+msgstr ""
+
+msgid ""
+"The ``win32text.forbid*`` hooks provided by the win32text extension\n"
+"have been unified into a single hook named ``eol.checkheadshook``. The\n"
+"hook will lookup the expected line endings from the ``.hgeol`` file,\n"
+"which means you must migrate to a ``.hgeol`` file first before using\n"
+"the hook. ``eol.checkheadshook`` only checks heads, intermediate\n"
+"invalid revisions will be pushed. To forbid them completely, use the\n"
+"``eol.checkallhook`` hook. These hooks are best used as\n"
+"``pretxnchangegroup`` hooks."
+msgstr ""
+
+msgid ""
+"See :hg:`help patterns` for more information about the glob patterns\n"
+"used.\n"
+msgstr ""
+
+#, python-format
+msgid "ignoring unknown EOL style '%s' from %s\n"
+msgstr ""
+
+#, python-format
+msgid "warning: ignoring .hgeol file due to parse error at %s: %s\n"
+msgstr ""
+
+#, python-format
+msgid "  %s in %s should not have %s line endings"
+msgstr ""
+
+msgid "end-of-line check failed:\n"
+msgstr ""
+
+msgid "the eol extension is incompatible with the win32text extension\n"
+msgstr ""
+
+#, python-format
+msgid "inconsistent newline style in %s\n"
+msgstr ""
+
+msgid "command to allow external programs to compare revisions"
+msgstr ""
+
+msgid ""
+"The extdiff Mercurial extension allows you to use external programs\n"
+"to compare revisions, or revision with working directory. The external\n"
+"diff programs are called with a configurable set of options and two\n"
+"non-option arguments: paths to directories containing snapshots of\n"
+"files to compare."
+msgstr ""
+
+msgid ""
+"The extdiff extension also allows you to configure new diff commands, so\n"
+"you do not need to type :hg:`extdiff -p kdiff3` always. ::"
+msgstr ""
+
+msgid ""
+"  [extdiff]\n"
+"  # add new command that runs GNU diff(1) in 'context diff' mode\n"
+"  cdiff = gdiff -Nprc5\n"
+"  ## or the old way:\n"
+"  #cmd.cdiff = gdiff\n"
+"  #opts.cdiff = -Nprc5"
+msgstr ""
+
+msgid ""
+"  # add new command called vdiff, runs kdiff3\n"
+"  vdiff = kdiff3"
+msgstr ""
+
+msgid ""
+"  # add new command called meld, runs meld (no need to name twice)\n"
+"  meld ="
+msgstr ""
+
+msgid ""
+"  # add new command called vimdiff, runs gvimdiff with DirDiff plugin\n"
+"  # (see http://www.vim.org/scripts/script.php?script_id=102) Non\n"
+"  # English user, be sure to put \"let g:DirDiffDynamicDiffText = 1\" in\n"
+"  # your .vimrc\n"
+"  vimdiff = gvim -f '+next' '+execute \"DirDiff\" argv(0) argv(1)'"
+msgstr ""
+
+msgid "Tool arguments can include variables that are expanded at runtime::"
+msgstr ""
+
+msgid ""
+"  $parent1, $plabel1 - filename, descriptive label of first parent\n"
+"  $child,   $clabel  - filename, descriptive label of child revision\n"
+"  $parent2, $plabel2 - filename, descriptive label of second parent\n"
+"  $root              - repository root\n"
+"  $parent is an alias for $parent1."
+msgstr ""
+
+msgid ""
+"The extdiff extension will look in your [diff-tools] and [merge-tools]\n"
+"sections for diff tool arguments, when none are specified in [extdiff]."
+msgstr ""
+
+msgid ""
+"  [extdiff]\n"
+"  kdiff3 ="
+msgstr ""
+
+msgid ""
+"  [diff-tools]\n"
+"  kdiff3.diffargs=--L1 '$plabel1' --L2 '$clabel' $parent $child"
+msgstr ""
+
+msgid ""
+"You can use -I/-X and list of file or directory names like normal\n"
+":hg:`diff` command. The extdiff extension makes snapshots of only\n"
+"needed files, so running the external diff program will actually be\n"
+"pretty fast (at least faster than having to compare the entire tree).\n"
+msgstr ""
+
+#, python-format
+msgid "making snapshot of %d files from rev %s\n"
+msgstr "создается снимок %d файлов для ревизии %s\n"
+
+#, python-format
+msgid "making snapshot of %d files from working directory\n"
+msgstr ""
+
+msgid "cannot specify --rev and --change at the same time"
+msgstr ""
+
+msgid "cleaning up temp directory\n"
+msgstr "очистка временного каталога\n"
+
+msgid "use external program to diff repository (or selected files)"
+msgstr "Использовать внешнюю программу поиска отличий между ревизиями"
+
+msgid ""
+"    Show differences between revisions for the specified files, using\n"
+"    an external program. The default program used is diff, with\n"
+"    default options \"-Npru\"."
+msgstr ""
+"    Показывает различия между ревизиями для указанных файлов, используя\n"
+"    внешнюю программу. По умолчанию используется diff с параметрами\n"
+"    \"-Npru\"."
+
+msgid ""
+"    To select a different program, use the -p/--program option. The\n"
+"    program will be passed the names of two directories to compare. To\n"
+"    pass additional options to the program, use -o/--option. These\n"
+"    will be passed before the names of the directories to compare."
+msgstr ""
+"    Чтобы выбрать другую программу, используйте параметр -p/--program.\n"
+"    Программе будут переданы имена двух директорий для сравнения.\n"
+"    Чтобы передать дополнительные параметры, используйте -o/--option.\n"
+"    Они будут переданы перед именами сравниваемых директорий."
+
+msgid ""
+"    When two revision arguments are given, then changes are shown\n"
+"    between those revisions. If only one revision is specified then\n"
+"    that revision is compared to the working directory, and, when no\n"
+"    revisions are specified, the working directory files are compared\n"
+"    to its parent."
+msgstr ""
+"    Если указаны две ревизии, показываются отличия между этими\n"
+"    ревизиями. Если указана только одна ревизия, то эта ревизия\n"
+"    сравнивается с рабочей копией, а если не указано ни одной\n"
+"    ревизии, рабочая копия сравнивается с родительской ревизией\n"
+"    репозитория."
+
+msgid "CMD"
+msgstr "КОМАНДА"
+
+msgid "comparison program to run"
+msgstr ""
+
+msgid "OPT"
+msgstr "ОПЦИЯ"
+
+msgid "pass option to comparison program"
+msgstr "передать ОПЦИЮ программе сравнения"
+
+msgid "revision"
+msgstr "ревизия"
+
+msgid "change made by revision"
+msgstr "изменения, сделанные в ревизии"
+
+msgid "hg extdiff [OPT]... [FILE]..."
+msgstr "hg extdiff [ПАРАМЕТР]... [ФАЙЛ]..."
+
+#, python-format
+msgid "use %(path)s to diff repository (or selected files)"
+msgstr "использовать %(path)s для сравнения репозитория (или выбранных файлов)"
+
+#, python-format
+msgid ""
+"    Show differences between revisions for the specified files, using\n"
+"    the %(path)s program."
+msgstr ""
+"    Показать различия между ревизиями для указанных файлов, используя\n"
+"    программу %(path)s."
+
+#, python-format
+msgid "hg %s [OPTION]... [FILE]..."
+msgstr "hg %s [ПАРАМЕТР]... [ФАЙЛ]..."
+
+msgid "pull, update and merge in one command"
+msgstr ""
+
+msgid "pull changes from a remote repository, merge new changes if needed."
+msgstr ""
+
+msgid ""
+"    This finds all changes from the repository at the specified path\n"
+"    or URL and adds them to the local repository."
+msgstr ""
+
+msgid ""
+"    If the pulled changes add a new branch head, the head is\n"
+"    automatically merged, and the result of the merge is committed.\n"
+"    Otherwise, the working directory is updated to include the new\n"
+"    changes."
+msgstr ""
+
+msgid ""
+"    When a merge occurs, the newly pulled changes are assumed to be\n"
+"    \"authoritative\". The head of the new changes is used as the first\n"
+"    parent, with local changes as the second. To switch the merge\n"
+"    order, use --switch-parent."
+msgstr ""
+
+msgid "    See :hg:`help dates` for a list of formats valid for -d/--date."
+msgstr "    Список возможных форматов для --d/--dates см. :hg:`help dates`"
+
+msgid ""
+"    Returns 0 on success.\n"
+"    "
+msgstr ""
+"    В случае успеха возвращает 0.\n"
+"    "
+
+msgid ""
+"working dir not at branch tip (use \"hg update\" to check out branch tip)"
+msgstr ""
+
+msgid "outstanding uncommitted merge"
+msgstr ""
+
+msgid "outstanding uncommitted changes"
+msgstr ""
+
+msgid "working directory is missing some files"
+msgstr ""
+
+msgid ""
+"multiple heads in this branch (use \"hg heads .\" and \"hg merge\" to merge)"
+msgstr ""
+
+#, python-format
+msgid "pulling from %s\n"
+msgstr ""
+
+msgid ""
+"Other repository doesn't support revision lookup, so a rev cannot be "
+"specified."
+msgstr ""
+
+#, python-format
+msgid ""
+"not merging with %d other new branch heads (use \"hg heads .\" and \"hg merge"
+"\" to merge them)\n"
+msgstr ""
+
+#, python-format
+msgid "updating to %d:%s\n"
+msgstr ""
+
+#, python-format
+msgid "merging with %d:%s\n"
+msgstr ""
+
+#, python-format
+msgid "new changeset %d:%s merges remote changes with local\n"
+msgstr ""
+
+msgid "a specific revision you would like to pull"
+msgstr ""
+
+msgid "edit commit message"
+msgstr ""
+
+msgid "edit commit message (DEPRECATED)"
+msgstr ""
+
+msgid "switch parents when merging"
+msgstr ""
+
+msgid "hg fetch [SOURCE]"
+msgstr ""
+
+msgid "commands to sign and verify changesets"
+msgstr ""
+
+msgid "error while verifying signature"
+msgstr ""
+
+#, python-format
+msgid "%s Bad signature from \"%s\"\n"
+msgstr ""
+
+#, python-format
+msgid "%s Note: Signature has expired (signed by: \"%s\")\n"
+msgstr ""
+
+#, python-format
+msgid "%s Note: This key has expired (signed by: \"%s\")\n"
+msgstr ""
+
+msgid "hg sigs"
+msgstr ""
+
+msgid "list signed changesets"
+msgstr ""
+
+#, python-format
+msgid "%s:%d node does not exist\n"
+msgstr ""
+
+msgid "hg sigcheck REVISION"
+msgstr ""
+
+msgid "verify all the signatures there may be for a particular revision"
+msgstr ""
+
+#, python-format
+msgid "No valid signature for %s\n"
+msgstr ""
+
+msgid "make the signature local"
+msgstr ""
+
+msgid "sign even if the sigfile is modified"
+msgstr ""
+
+msgid "do not commit the sigfile after signing"
+msgstr ""
+
+msgid "ID"
+msgstr "ID"
+
+msgid "the key id to sign with"
+msgstr ""
+
+msgid "TEXT"
+msgstr "ТЕКСТ"
+
+msgid "commit message"
+msgstr ""
+
+msgid "hg sign [OPTION]... [REVISION]..."
+msgstr ""
+
+msgid "add a signature for the current or given revision"
+msgstr ""
+
+msgid ""
+"    If no revision is given, the parent of the working directory is used,\n"
+"    or tip if no revision is checked out."
+msgstr ""
+
+msgid ""
+"    See :hg:`help dates` for a list of formats valid for -d/--date.\n"
+"    "
+msgstr ""
+
+msgid "uncommitted merge - please provide a specific revision"
+msgstr ""
+
+#, python-format
+msgid "Signing %d:%s\n"
+msgstr ""
+
+msgid "error while signing"
+msgstr ""
+
+msgid ""
+"working copy of .hgsigs is changed (please commit .hgsigs manually or use --"
+"force)"
+msgstr ""
+
+msgid "unknown signature version"
+msgstr ""
+
+msgid "command to view revision graphs from a shell"
+msgstr ""
+
+msgid ""
+"This extension adds a --graph option to the incoming, outgoing and log\n"
+"commands. When this options is given, an ASCII representation of the\n"
+"revision graph is also shown.\n"
+msgstr ""
+
+#, python-format
+msgid "-G/--graph option is incompatible with --%s"
+msgstr ""
+
+msgid "-G/--graph option is incompatible with --follow with file argument"
+msgstr ""
+
+msgid "NUM"
+msgstr ""
+
+msgid "limit number of changes displayed"
+msgstr "ограничивать количество отображаемых изменений"
+
+msgid "show patch"
+msgstr ""
+
+msgid "show the specified revision or range"
+msgstr ""
+
+msgid "hg glog [OPTION]... [FILE]"
+msgstr ""
+
+msgid "show revision history alongside an ASCII revision graph"
+msgstr ""
+
+msgid ""
+"    Print a revision history alongside a revision graph drawn with\n"
+"    ASCII characters."
+msgstr ""
+
+msgid ""
+"    Nodes printed as an @ character are parents of the working\n"
+"    directory.\n"
+"    "
+msgstr ""
+
+msgid "show the revision DAG"
+msgstr ""
+
+msgid "hooks for integrating with the CIA.vc notification service"
+msgstr ""
+
+msgid ""
+"This is meant to be run as a changegroup or incoming hook. To\n"
+"configure it, set the following options in your hgrc::"
+msgstr ""
+
+msgid ""
+"  [cia]\n"
+"  # your registered CIA user name\n"
+"  user = foo\n"
+"  # the name of the project in CIA\n"
+"  project = foo\n"
+"  # the module (subproject) (optional)\n"
+"  #module = foo\n"
+"  # Append a diffstat to the log message (optional)\n"
+"  #diffstat = False\n"
+"  # Template to use for log messages (optional)\n"
+"  #template = {desc}\\n{baseurl}{webroot}/rev/{node}-- {diffstat}\n"
+"  # Style to use (optional)\n"
+"  #style = foo\n"
+"  # The URL of the CIA notification service (optional)\n"
+"  # You can use mailto: URLs to send by email, eg\n"
+"  # mailto:cia@cia.vc\n"
+"  # Make sure to set email.from if you do this.\n"
+"  #url = http://cia.vc/\n"
+"  # print message instead of sending it (optional)\n"
+"  #test = False\n"
+"  # number of slashes to strip for url paths\n"
+"  #strip = 0"
+msgstr ""
+
+msgid ""
+"  [hooks]\n"
+"  # one of these:\n"
+"  changegroup.cia = python:hgcia.hook\n"
+"  #incoming.cia = python:hgcia.hook"
+msgstr ""
+
+msgid ""
+"  [web]\n"
+"  # If you want hyperlinks (optional)\n"
+"  baseurl = http://server/path/to/repo\n"
+msgstr ""
+
+#, python-format
+msgid "%s returned an error: %s"
+msgstr ""
+
+#, python-format
+msgid "hgcia: sending update to %s\n"
+msgstr ""
+
+msgid "email.from must be defined when sending by email"
+msgstr ""
+
+msgid "browse the repository in a graphical way"
+msgstr ""
+
+msgid ""
+"The hgk extension allows browsing the history of a repository in a\n"
+"graphical way. It requires Tcl/Tk version 8.4 or later. (Tcl/Tk is not\n"
+"distributed with Mercurial.)"
+msgstr ""
+
+msgid ""
+"hgk consists of two parts: a Tcl script that does the displaying and\n"
+"querying of information, and an extension to Mercurial named hgk.py,\n"
+"which provides hooks for hgk to get information. hgk can be found in\n"
+"the contrib directory, and the extension is shipped in the hgext\n"
+"repository, and needs to be enabled."
+msgstr ""
+
+msgid ""
+"The :hg:`view` command will launch the hgk Tcl script. For this command\n"
+"to work, hgk must be in your search path. Alternately, you can specify\n"
+"the path to hgk in your configuration file::"
+msgstr ""
+
+msgid ""
+"  [hgk]\n"
+"  path=/location/of/hgk"
+msgstr ""
+
+msgid ""
+"hgk can make use of the extdiff extension to visualize revisions.\n"
+"Assuming you had already configured extdiff vdiff command, just add::"
+msgstr ""
+
+msgid ""
+"  [hgk]\n"
+"  vdiff=vdiff"
+msgstr ""
+
+msgid ""
+"Revisions context menu will now display additional entries to fire\n"
+"vdiff on hovered and selected revisions.\n"
+msgstr ""
+
+msgid "diff trees from two commits"
+msgstr ""
+
+msgid "output common ancestor information"
+msgstr ""
+
+msgid "cat a specific revision"
+msgstr ""
+
+msgid "cat-file: type or revision not supplied\n"
+msgstr ""
+
+msgid "aborting hg cat-file only understands commits\n"
+msgstr ""
+
+msgid "parse given revisions"
+msgstr ""
+
+msgid "print revisions"
+msgstr ""
+
+msgid "print extension options"
+msgstr ""
+
+msgid "start interactive history viewer"
+msgstr ""
+
+msgid "hg view [-l LIMIT] [REVRANGE]"
+msgstr ""
+
+msgid "generate patch"
+msgstr ""
+
+msgid "recursive"
+msgstr ""
+
+msgid "pretty"
+msgstr ""
+
+msgid "stdin"
+msgstr ""
+
+msgid "detect copies"
+msgstr ""
+
+msgid "search"
+msgstr ""
+
+msgid "hg git-diff-tree [OPTION]... NODE1 NODE2 [FILE]..."
+msgstr ""
+
+msgid "hg debug-cat-file [OPTION]... TYPE FILE"
+msgstr ""
+
+msgid "hg debug-config"
+msgstr ""
+
+msgid "hg debug-merge-base REV REV"
+msgstr ""
+
+msgid "ignored"
+msgstr "игнорируемые"
+
+msgid "hg debug-rev-parse REV"
+msgstr ""
+
+msgid "header"
+msgstr ""
+
+msgid "topo-order"
+msgstr ""
+
+msgid "parents"
+msgstr ""
+
+msgid "max-count"
+msgstr ""
+
+msgid "hg debug-rev-list [OPTION]... REV..."
+msgstr ""
+
+msgid "syntax highlighting for hgweb (requires Pygments)"
+msgstr ""
+
+msgid ""
+"It depends on the Pygments syntax highlighting library:\n"
+"http://pygments.org/"
+msgstr ""
+
+msgid "There is a single configuration option::"
+msgstr ""
+
+msgid ""
+"  [web]\n"
+"  pygments_style = <style>"
+msgstr ""
+
+msgid "The default is 'colorful'.\n"
+msgstr ""
+
+msgid "accelerate status report using Linux's inotify service"
+msgstr ""
+
+msgid "start an inotify server for this repository"
+msgstr ""
+
+msgid "debugging information for inotify extension"
+msgstr ""
+
+msgid ""
+"    Prints the list of directories being watched by the inotify server.\n"
+"    "
+msgstr ""
+
+msgid "directories being watched:\n"
+msgstr ""
+
+msgid "run server in background"
+msgstr "запустить сервер в фоновом режиме"
+
+msgid "used internally by daemon mode"
+msgstr "внутренне используется в режиме сервиса"
+
+msgid "minutes to sit idle before exiting"
+msgstr ""
+
+msgid "name of file to write process ID to"
+msgstr "имя файла для записи ID процесса"
+
+msgid "hg inserve [OPTION]..."
+msgstr ""
+
+msgid "inotify-client: found dead inotify server socket; removing it\n"
+msgstr ""
+
+#, python-format
+msgid "inotify-client: could not start inotify server: %s\n"
+msgstr ""
+
+#, python-format
+msgid "inotify-client: could not talk to new inotify server: %s\n"
+msgstr ""
+
+#, python-format
+msgid "inotify-client: failed to contact inotify server: %s\n"
+msgstr ""
+
+msgid "inotify-client: received empty answer from inotify server"
+msgstr ""
+
+#, python-format
+msgid "(inotify: received response from incompatible server version %d)\n"
+msgstr ""
+
+#, python-format
+msgid "(inotify: received '%s' response when expecting '%s')\n"
+msgstr ""
+
+msgid "this system does not seem to support inotify"
+msgstr ""
+
+#, python-format
+msgid "*** the current per-user limit on the number of inotify watches is %s\n"
+msgstr ""
+
+msgid "*** this limit is too low to watch every directory in this repository\n"
+msgstr ""
+
+msgid "*** counting directories: "
+msgstr ""
+
+#, python-format
+msgid "found %d\n"
+msgstr ""
+
+#, python-format
+msgid "*** to raise the limit from %d to %d (run as root):\n"
+msgstr ""
+
+#, python-format
+msgid "***  echo %d > %s\n"
+msgstr ""
+
+#, python-format
+msgid "cannot watch %s until inotify watch limit is raised"
+msgstr ""
+
+#, python-format
+msgid "inotify service not available: %s"
+msgstr ""
+
+#, python-format
+msgid "watching %r\n"
+msgstr ""
+
+#, python-format
+msgid "watching directories under %r\n"
+msgstr ""
+
+#, python-format
+msgid "%s event: created %s\n"
+msgstr ""
+
+#, python-format
+msgid "%s event: deleted %s\n"
+msgstr ""
+
+#, python-format
+msgid "%s event: modified %s\n"
+msgstr ""
+
+#, python-format
+msgid "filesystem containing %s was unmounted\n"
+msgstr ""
+
+#, python-format
+msgid "%s readable: %d bytes\n"
+msgstr ""
+
+#, python-format
+msgid "%s below threshold - unhooking\n"
+msgstr ""
+
+#, python-format
+msgid "%s reading %d events\n"
+msgstr ""
+
+#, python-format
+msgid "%s hooking back up with %d bytes readable\n"
+msgstr ""
+
+msgid "finished setup\n"
+msgstr ""
+
+#, python-format
+msgid "status: %r %s -> %s\n"
+msgstr ""
+
+msgid "rescanning due to .hgignore change\n"
+msgstr ""
+
+msgid "cannot start: socket is already bound"
+msgstr ""
+
+msgid ""
+"cannot start: tried linking .hg/inotify.sock to a temporary socket but .hg/"
+"inotify.sock already exists"
+msgstr ""
+
+#, python-format
+msgid "answering query for %r\n"
+msgstr ""
+
+#, python-format
+msgid "received query from incompatible client version %d\n"
+msgstr ""
+
+#, python-format
+msgid "unrecognized query type: %s\n"
+msgstr ""
+
+msgid "expand expressions into changelog and summaries"
+msgstr ""
+
+msgid ""
+"This extension allows the use of a special syntax in summaries, which\n"
+"will be automatically expanded into links or any other arbitrary\n"
+"expression, much like InterWiki does."
+msgstr ""
+
+msgid ""
+"A few example patterns (link to bug tracking, etc.) that may be used\n"
+"in your hgrc::"
+msgstr ""
+
+msgid ""
+"  [interhg]\n"
+"  issues = s!issue(\\d+)!<a href=\"http://bts/issue\\1\">issue\\1</a>!\n"
+"  bugzilla = s!((?:bug|b=|(?=#?\\d{4,}))(?:\\s*#?)(\\d+))!<a..=\\2\">\\1</a>!"
+"i\n"
+"  boldify = s!(^|\\s)#(\\d+)\\b! <b>#\\2</b>!\n"
+msgstr ""
+
+#, python-format
+msgid "interhg: invalid pattern for %s: %s\n"
+msgstr ""
+
+#, python-format
+msgid "interhg: invalid regexp for %s: %s\n"
+msgstr ""
+
+msgid "expand keywords in tracked files"
+msgstr ""
+
+msgid ""
+"This extension expands RCS/CVS-like or self-customized $Keywords$ in\n"
+"tracked text files selected by your configuration."
+msgstr ""
+
+msgid ""
+"Keywords are only expanded in local repositories and not stored in the\n"
+"change history. The mechanism can be regarded as a convenience for the\n"
+"current user or for archive distribution."
+msgstr ""
+
+msgid ""
+"Keywords expand to the changeset data pertaining to the latest change\n"
+"relative to the working directory parent of each file."
+msgstr ""
+
+msgid ""
+"Configuration is done in the [keyword], [keywordset] and [keywordmaps]\n"
+"sections of hgrc files."
+msgstr ""
+
+msgid "Example::"
+msgstr ""
+
+msgid ""
+"    [keyword]\n"
+"    # expand keywords in every python file except those matching \"x*\"\n"
+"    **.py =\n"
+"    x*    = ignore"
+msgstr ""
+
+msgid ""
+"    [keywordset]\n"
+"    # prefer svn- over cvs-like default keywordmaps\n"
+"    svn = True"
+msgstr ""
+
+msgid ""
+".. note::\n"
+"   The more specific you are in your filename patterns the less you\n"
+"   lose speed in huge repositories."
+msgstr ""
+
+msgid ""
+"For [keywordmaps] template mapping and expansion demonstration and\n"
+"control run :hg:`kwdemo`. See :hg:`help templates` for a list of\n"
+"available templates and filters."
+msgstr ""
+
+msgid "Three additional date template filters are provided:"
+msgstr ""
+
+msgid ""
+":``utcdate``:    \"2006/09/18 15:13:13\"\n"
+":``svnutcdate``: \"2006-09-18 15:13:13Z\"\n"
+":``svnisodate``: \"2006-09-18 08:13:13 -700 (Mon, 18 Sep 2006)\""
+msgstr ""
+
+msgid ""
+"The default template mappings (view with :hg:`kwdemo -d`) can be\n"
+"replaced with customized keywords and templates. Again, run\n"
+":hg:`kwdemo` to control the results of your configuration changes."
+msgstr ""
+
+msgid ""
+"Before changing/disabling active keywords, you must run :hg:`kwshrink`\n"
+"to avoid storing expanded keywords in the change history."
+msgstr ""
+
+msgid ""
+"To force expansion after enabling it, or a configuration change, run\n"
+":hg:`kwexpand`."
+msgstr ""
+
+msgid ""
+"Expansions spanning more than one line and incremental expansions,\n"
+"like CVS' $Log$, are not supported. A keyword template map \"Log =\n"
+"{desc}\" expands to the first line of the changeset description.\n"
+msgstr ""
+
+#, python-format
+msgid "overwriting %s expanding keywords\n"
+msgstr ""
+
+#, python-format
+msgid "overwriting %s shrinking keywords\n"
+msgstr ""
+
+msgid "[keyword] patterns cannot match"
+msgstr ""
+
+msgid "no [keyword] patterns configured"
+msgstr ""
+
+msgid "show default keyword template maps"
+msgstr ""
+
+msgid "read maps from rcfile"
+msgstr ""
+
+msgid "hg kwdemo [-d] [-f RCFILE] [TEMPLATEMAP]..."
+msgstr ""
+
+msgid "print [keywordmaps] configuration and an expansion example"
+msgstr ""
+
+msgid ""
+"    Show current, custom, or default keyword template maps and their\n"
+"    expansions."
+msgstr ""
+
+msgid ""
+"    Extend the current configuration by specifying maps as arguments\n"
+"    and using -f/--rcfile to source an external hgrc file."
+msgstr ""
+
+msgid "    Use -d/--default to disable current configuration."
+msgstr ""
+
+msgid ""
+"    See :hg:`help templates` for information on templates and filters.\n"
+"    "
+msgstr ""
+
+#, python-format
+msgid "creating temporary repository at %s\n"
+msgstr ""
+
+msgid ""
+"\n"
+"\tconfiguration using custom keyword template maps\n"
+msgstr ""
+
+msgid "\textending current template maps\n"
+msgstr ""
+
+msgid "\toverriding default svn keywordset\n"
+msgstr ""
+
+msgid "\toverriding default cvs keywordset\n"
+msgstr ""
+
+msgid ""
+"\n"
+"\tconfiguration using default svn keywordset\n"
+msgstr ""
+
+msgid ""
+"\n"
+"\tconfiguration using default cvs keywordset\n"
+msgstr ""
+
+msgid "\tdisabling current template maps\n"
+msgstr ""
+
+msgid ""
+"\n"
+"\tconfiguration using current keyword template maps\n"
+msgstr ""
+
+#, python-format
+msgid ""
+"\n"
+"keywords written to %s:\n"
+msgstr ""
+
+msgid "hg keyword configuration and expansion example"
+msgstr ""
+
+msgid ""
+"\n"
+"\tkeywords expanded\n"
+msgstr ""
+
+msgid "hg kwexpand [OPTION]... [FILE]..."
+msgstr ""
+
+msgid "expand keywords in the working directory"
+msgstr ""
+
+msgid "    Run after (re)enabling keyword expansion."
+msgstr ""
+
+msgid ""
+"    kwexpand refuses to run if given files contain local changes.\n"
+"    "
+msgstr ""
+
+msgid "show keyword status flags of all files"
+msgstr ""
+
+msgid "show files excluded from expansion"
+msgstr ""
+
+msgid "only show unknown (not tracked) files"
+msgstr ""
+
+msgid "hg kwfiles [OPTION]... [FILE]..."
+msgstr ""
+
+msgid "show files configured for keyword expansion"
+msgstr ""
+
+msgid ""
+"    List which files in the working directory are matched by the\n"
+"    [keyword] configuration patterns."
+msgstr ""
+
+msgid ""
+"    Useful to prevent inadvertent keyword expansion and to speed up\n"
+"    execution by including only files that are actual candidates for\n"
+"    expansion."
+msgstr ""
+
+msgid ""
+"    See :hg:`help keyword` on how to construct patterns both for\n"
+"    inclusion and exclusion of files."
+msgstr ""
+
+msgid ""
+"    With -A/--all and -v/--verbose the codes used to show the status\n"
+"    of files are::"
+msgstr ""
+
+msgid ""
+"      K = keyword expansion candidate\n"
+"      k = keyword expansion candidate (not tracked)\n"
+"      I = ignored\n"
+"      i = ignored (not tracked)\n"
+"    "
+msgstr ""
+
+msgid "hg kwshrink [OPTION]... [FILE]..."
+msgstr ""
+
+msgid "revert expanded keywords in the working directory"
+msgstr ""
+
+msgid "    Must be run before changing/disabling active keywords."
+msgstr ""
+
+msgid ""
+"    kwshrink refuses to run if given files contain local changes.\n"
+"    "
+msgstr ""
+
+msgid "manage a stack of patches"
+msgstr ""
+
+msgid ""
+"This extension lets you work with a stack of patches in a Mercurial\n"
+"repository. It manages two stacks of patches - all known patches, and\n"
+"applied patches (subset of known patches)."
+msgstr ""
+
+msgid ""
+"Known patches are represented as patch files in the .hg/patches\n"
+"directory. Applied patches are both patch files and changesets."
+msgstr ""
+
+msgid "Common tasks (use :hg:`help command` for more details)::"
+msgstr ""
+
+msgid ""
+"  create new patch                          qnew\n"
+"  import existing patch                     qimport"
+msgstr ""
+
+msgid ""
+"  print patch series                        qseries\n"
+"  print applied patches                     qapplied"
+msgstr ""
+
+msgid ""
+"  add known patch to applied stack          qpush\n"
+"  remove patch from applied stack           qpop\n"
+"  refresh contents of top applied patch     qrefresh"
+msgstr ""
+
+msgid ""
+"By default, mq will automatically use git patches when required to\n"
+"avoid losing file mode changes, copy records, binary files or empty\n"
+"files creations or deletions. This behaviour can be configured with::"
+msgstr ""
+
+msgid ""
+"  [mq]\n"
+"  git = auto/keep/yes/no"
+msgstr ""
+
+msgid ""
+"If set to 'keep', mq will obey the [diff] section configuration while\n"
+"preserving existing git patches upon qrefresh. If set to 'yes' or\n"
+"'no', mq will override the [diff] section and always generate git or\n"
+"regular patches, possibly losing data in the second case."
+msgstr ""
+
+msgid ""
+"You will by default be managing a patch queue named \"patches\". You can\n"
+"create other, independent patch queues with the :hg:`qqueue` command.\n"
+msgstr ""
+
+msgid "print first line of patch header"
+msgstr ""
+
+#, python-format
+msgid "malformated mq status line: %s\n"
+msgstr ""
+
+#, python-format
+msgid "mq.git option can be auto/keep/yes/no got %s"
+msgstr ""
+
+#, python-format
+msgid "%s appears more than once in %s"
+msgstr ""
+
+msgid "guard cannot be an empty string"
+msgstr ""
+
+#, python-format
+msgid "guard %r starts with invalid character: %r"
+msgstr ""
+
+#, python-format
+msgid "invalid character in guard %r: %r"
+msgstr ""
+
+#, python-format
+msgid "guard %r too short"
+msgstr ""
+
+#, python-format
+msgid "guard %r starts with invalid char"
+msgstr ""
+
+#, python-format
+msgid "allowing %s - no guards in effect\n"
+msgstr ""
+
+#, python-format
+msgid "allowing %s - no matching negative guards\n"
+msgstr ""
+
+#, python-format
+msgid "allowing %s - guarded by %r\n"
+msgstr ""
+
+#, python-format
+msgid "skipping %s - guarded by %r\n"
+msgstr ""
+
+#, python-format
+msgid "skipping %s - no matching guards\n"
+msgstr ""
+
+#, python-format
+msgid "error removing undo: %s\n"
+msgstr ""
+
+#, python-format
+msgid "apply failed for patch %s"
+msgstr ""
+
+#, python-format
+msgid "patch didn't work out, merging %s\n"
+msgstr ""
+
+#, python-format
+msgid "update returned %d"
+msgstr ""
+
+msgid "repo commit failed"
+msgstr ""
+
+#, python-format
+msgid "unable to read %s"
+msgstr ""
+
+#, python-format
+msgid "patch %s does not exist\n"
+msgstr ""
+
+#, python-format
+msgid "patch %s is not applied\n"
+msgstr ""
+
+msgid "patch failed, unable to continue (try -v)\n"
+msgstr ""
+
+#, python-format
+msgid "applying %s\n"
+msgstr ""
+
+#, python-format
+msgid "unable to read %s\n"
+msgstr ""
+
+#, python-format
+msgid "patch %s is empty\n"
+msgstr ""
+
+msgid "repository commit failed"
+msgstr ""
+
+msgid "patch failed, rejects left in working dir\n"
+msgstr ""
+
+msgid "fuzz found when applying patch, stopping\n"
+msgstr ""
+
+#, python-format
+msgid "revision %s refers to unknown patches: %s\n"
+msgstr ""
+
+#, python-format
+msgid "unknown patches: %s\n"
+msgstr ""
+
+#, python-format
+msgid "revision %d is not managed"
+msgstr ""
+
+#, python-format
+msgid "cannot delete revision %d above applied patches"
+msgstr ""
+
+#, python-format
+msgid "patch %s finalized without changeset message\n"
+msgstr ""
+
+msgid "qdelete requires at least one revision or patch name"
+msgstr ""
+
+#, python-format
+msgid "cannot delete applied patch %s"
+msgstr ""
+
+#, python-format
+msgid "patch %s not in series file"
+msgstr ""
+
+msgid "no patches applied"
+msgstr ""
+
+msgid "working directory revision is not qtip"
+msgstr ""
+
+#, python-format
+msgid "uncommitted changes in subrepository %s"
+msgstr ""
+
+msgid "local changes found, refresh first"
+msgstr ""
+
+msgid "local changes found"
+msgstr ""
+
+#, python-format
+msgid "\"%s\" cannot be used as the name of a patch"
+msgstr ""
+
+#, python-format
+msgid "patch name cannot begin with \"%s\""
+msgstr ""
+
+#, python-format
+msgid "\"%s\" cannot be used in the name of a patch"
+msgstr ""
+
+#, python-format
+msgid "\"%s\" already exists as a directory"
+msgstr ""
+
+#, python-format
+msgid "patch \"%s\" already exists"
+msgstr ""
+
+msgid "cannot manage merge changesets"
+msgstr ""
+
+#, python-format
+msgid "cannot write patch \"%s\": %s"
+msgstr ""
+
+#, python-format
+msgid "error unlinking %s\n"
+msgstr ""
+
+#, python-format
+msgid "patch name \"%s\" is ambiguous:\n"
+msgstr ""
+
+#, python-format
+msgid "patch %s not in series"
+msgstr ""
+
+msgid "(working directory not at a head)\n"
+msgstr ""
+
+msgid "no patches in series\n"
+msgstr ""
+
+#, python-format
+msgid "qpush: %s is already at the top\n"
+msgstr ""
+
+#, python-format
+msgid "cannot push to a previous patch: %s"
+msgstr ""
+
+#, python-format
+msgid "guarded by %r"
+msgstr ""
+
+msgid "no matching guards"
+msgstr ""
+
+#, python-format
+msgid "cannot push '%s' - %s\n"
+msgstr ""
+
+msgid "all patches are currently applied\n"
+msgstr ""
+
+msgid "patch series already fully applied\n"
+msgstr ""
+
+msgid "cannot use --exact and --move together"
+msgstr ""
+
+msgid "cannot push --exact with applied patches"
+msgstr ""
+
+#, python-format
+msgid "%s does not have a parent recorded"
+msgstr ""
+
+msgid "please specify the patch to move"
+msgstr ""
+
+msgid "cleaning up working directory..."
+msgstr ""
+
+#, python-format
+msgid "errors during apply, please fix and refresh %s\n"
+msgstr ""
+
+#, python-format
+msgid "now at: %s\n"
+msgstr ""
+
+#, python-format
+msgid "patch %s is not applied"
+msgstr ""
+
+msgid "no patches applied\n"
+msgstr ""
+
+#, python-format
+msgid "qpop: %s is already at the top\n"
+msgstr ""
+
+msgid "qpop: forcing dirstate update\n"
+msgstr ""
+
+#, python-format
+msgid "trying to pop unknown node %s"
+msgstr ""
+
+msgid "popping would remove a revision not managed by this patch queue"
+msgstr ""
+
+msgid "deletions found between repo revs"
+msgstr ""
+
+#, python-format
+msgid "popping %s\n"
+msgstr ""
+
+msgid "patch queue now empty\n"
+msgstr ""
+
+msgid "cannot refresh a revision with children"
+msgstr ""
+
+msgid ""
+"refresh interrupted while patch was popped! (revert --all, qpush to "
+"recover)\n"
+msgstr ""
+
+msgid "patch queue directory already exists"
+msgstr ""
+
+#, python-format
+msgid "patch %s is not in series file"
+msgstr ""
+
+msgid "No saved patch data found\n"
+msgstr ""
+
+#, python-format
+msgid "restoring status: %s\n"
+msgstr ""
+
+msgid "save entry has children, leaving it alone\n"
+msgstr ""
+
+#, python-format
+msgid "removing save entry %s\n"
+msgstr ""
+
+#, python-format
+msgid "saved queue repository parents: %s %s\n"
+msgstr ""
+
+msgid "updating queue directory\n"
+msgstr ""
+
+msgid "Unable to load queue repository\n"
+msgstr ""
+
+msgid "save: no patches applied, exiting\n"
+msgstr ""
+
+msgid "status is already saved\n"
+msgstr ""
+
+msgid "hg patches saved state"
+msgstr ""
+
+msgid "repo commit failed\n"
+msgstr ""
+
+#, python-format
+msgid "patch %s is already in the series file"
+msgstr ""
+
+msgid "option \"-r\" not valid when importing files"
+msgstr ""
+
+msgid "option \"-n\" not valid when importing multiple patches"
+msgstr ""
+
+#, python-format
+msgid "revision %d is the root of more than one branch"
+msgstr ""
+
+#, python-format
+msgid "revision %d is already managed"
+msgstr ""
+
+#, python-format
+msgid "revision %d is not the parent of the queue"
+msgstr ""
+
+#, python-format
+msgid "revision %d has unmanaged children"
+msgstr ""
+
+#, python-format
+msgid "cannot import merge revision %d"
+msgstr ""
+
+#, python-format
+msgid "revision %d is not the parent of %d"
+msgstr ""
+
+msgid "-e is incompatible with import from -"
+msgstr ""
+
+#, python-format
+msgid "patch %s does not exist"
+msgstr ""
+
+#, python-format
+msgid "renaming %s to %s\n"
+msgstr ""
+
+msgid "need --name to import a patch from -"
+msgstr ""
+
+#, python-format
+msgid "unable to read file %s"
+msgstr ""
+
+#, python-format
+msgid "adding %s to series file\n"
+msgstr ""
+
+msgid "keep patch file"
+msgstr ""
+
+msgid "stop managing a revision (DEPRECATED)"
+msgstr ""
+
+msgid "hg qdelete [-k] [PATCH]..."
+msgstr ""
+
+msgid "remove patches from queue"
+msgstr ""
+
+msgid ""
+"    The patches must not be applied, and at least one patch is required. "
+"With\n"
+"    -k/--keep, the patch files are preserved in the patch directory."
+msgstr ""
+
+msgid ""
+"    To stop managing a patch and move it into permanent history,\n"
+"    use the :hg:`qfinish` command."
+msgstr ""
+
+msgid "show only the last patch"
+msgstr ""
+
+msgid "hg qapplied [-1] [-s] [PATCH]"
+msgstr ""
+
+msgid "print the patches already applied"
+msgstr ""
+
+msgid "    Returns 0 on success."
+msgstr ""
+
+msgid "only one patch applied\n"
+msgstr ""
+
+msgid "show only the first patch"
+msgstr ""
+
+msgid "hg qunapplied [-1] [-s] [PATCH]"
+msgstr ""
+
+msgid "print the patches not yet applied"
+msgstr ""
+
+msgid "all patches applied\n"
+msgstr ""
+
+msgid "import file in patch directory"
+msgstr ""
+
+msgid "NAME"
+msgstr ""
+
+msgid "name of patch file"
+msgstr ""
+
+msgid "overwrite existing files"
+msgstr ""
+
+msgid "place existing revisions under mq control"
+msgstr ""
+
+msgid "use git extended diff format"
+msgstr "использовать расширенный формат git для diff'ов"
+
+msgid "qpush after importing"
+msgstr ""
+
+msgid "hg qimport [-e] [-n NAME] [-f] [-g] [-P] [-r REV]... FILE..."
+msgstr ""
+
+msgid "import a patch"
+msgstr ""
+
+msgid ""
+"    The patch is inserted into the series after the last applied\n"
+"    patch. If no patches have been applied, qimport prepends the patch\n"
+"    to the series."
+msgstr ""
+
+msgid ""
+"    The patch will have the same name as its source file unless you\n"
+"    give it a new one with -n/--name."
+msgstr ""
+
+msgid ""
+"    You can register an existing patch inside the patch directory with\n"
+"    the -e/--existing flag."
+msgstr ""
+
+msgid ""
+"    With -f/--force, an existing patch of the same name will be\n"
+"    overwritten."
+msgstr ""
+
+msgid ""
+"    An existing changeset may be placed under mq control with -r/--rev\n"
+"    (e.g. qimport --rev tip -n patch will place tip under mq control).\n"
+"    With -g/--git, patches imported with --rev will use the git diff\n"
+"    format. See the diffs help topic for information on why this is\n"
+"    important for preserving rename/copy information and permission\n"
+"    changes. Use :hg:`qfinish` to remove changesets from mq control."
+msgstr ""
+
+msgid ""
+"    To import a patch from standard input, pass - as the patch file.\n"
+"    When importing from standard input, a patch name must be specified\n"
+"    using the --name flag."
+msgstr ""
+
+msgid "    To import an existing patch while renaming it::"
+msgstr ""
+
+msgid "      hg qimport -e existing-patch -n new-name"
+msgstr ""
+
+msgid ""
+"    Returns 0 if import succeeded.\n"
+"    "
+msgstr ""
+
+msgid "create queue repository"
+msgstr ""
+
+msgid "hg qinit [-c]"
+msgstr ""
+
+msgid "init a new queue repository (DEPRECATED)"
+msgstr ""
+
+msgid ""
+"    The queue repository is unversioned by default. If\n"
+"    -c/--create-repo is specified, qinit will create a separate nested\n"
+"    repository for patches (qinit -c may also be run later to convert\n"
+"    an unversioned patch repository into a versioned one). You can use\n"
+"    qcommit to commit changes to this queue repository."
+msgstr ""
+
+msgid ""
+"    This command is deprecated. Without -c, it's implied by other relevant\n"
+"    commands. With -c, use :hg:`init --mq` instead."
+msgstr ""
+
+msgid "use pull protocol to copy metadata"
+msgstr "использовать протокол затягивания для копирования метаданных"
+
+msgid "do not update the new working directories"
+msgstr ""
+
+msgid "use uncompressed transfer (fast over LAN)"
+msgstr "не использовать сжатие при передачи (быстрее в локальной сети)"
+
+msgid "REPO"
+msgstr ""
+
+msgid "location of source patch repository"
+msgstr ""
+
+msgid "hg qclone [OPTION]... SOURCE [DEST]"
+msgstr ""
+
+msgid "clone main and patch repository at same time"
+msgstr ""
+
+msgid ""
+"    If source is local, destination will have no patches applied. If\n"
+"    source is remote, this command can not check if patches are\n"
+"    applied in source, so cannot guarantee that patches are not\n"
+"    applied in destination. If you clone remote repository, be sure\n"
+"    before that it has no patches applied."
+msgstr ""
+
+msgid ""
+"    Source patch repository is looked for in <src>/.hg/patches by\n"
+"    default. Use -p <url> to change."
+msgstr ""
+
+msgid ""
+"    The patch directory must be a nested Mercurial repository, as\n"
+"    would be created by :hg:`init --mq`."
+msgstr ""
+
+msgid ""
+"    Return 0 on success.\n"
+"    "
+msgstr ""
+
+msgid "versioned patch repository not found (see init --mq)"
+msgstr ""
+
+msgid "cloning main repository\n"
+msgstr ""
+
+msgid "cloning patch repository\n"
+msgstr ""
+
+msgid "stripping applied patches from destination repository\n"
+msgstr ""
+
+msgid "updating destination repository\n"
+msgstr ""
+
+msgid "hg qcommit [OPTION]... [FILE]..."
+msgstr ""
+
+msgid "commit changes in the queue repository (DEPRECATED)"
+msgstr ""
+
+msgid "    This command is deprecated; use :hg:`commit --mq` instead."
+msgstr ""
+
+msgid "print patches not in series"
+msgstr ""
+
+msgid "hg qseries [-ms]"
+msgstr ""
+
+msgid "print the entire series file"
+msgstr ""
+
+msgid "hg qtop [-s]"
+msgstr ""
+
+msgid "print the name of the current patch"
+msgstr ""
+
+msgid "hg qnext [-s]"
+msgstr ""
+
+msgid "print the name of the next patch"
+msgstr ""
+
+msgid "hg qprev [-s]"
+msgstr ""
+
+msgid "print the name of the previous patch"
+msgstr ""
+
+msgid "import uncommitted changes (DEPRECATED)"
+msgstr ""
+
+msgid "add \"From: <current user>\" to patch"
+msgstr ""
+
+msgid "USER"
+msgstr "ПОЛЬЗОВАТЕЛЬ"
+
+msgid "add \"From: <USER>\" to patch"
+msgstr ""
+
+msgid "add \"Date: <current date>\" to patch"
+msgstr ""
+
+msgid "add \"Date: <DATE>\" to patch"
+msgstr ""
+
+msgid "hg qnew [-e] [-m TEXT] [-l FILE] PATCH [FILE]..."
+msgstr ""
+
+msgid "create a new patch"
+msgstr ""
+
+msgid ""
+"    qnew creates a new patch on top of the currently-applied patch (if\n"
+"    any). The patch will be initialized with any outstanding changes\n"
+"    in the working directory. You may also use -I/--include,\n"
+"    -X/--exclude, and/or a list of files after the patch name to add\n"
+"    only changes to matching files to the new patch, leaving the rest\n"
+"    as uncommitted modifications."
+msgstr ""
+
+msgid ""
+"    -u/--user and -d/--date can be used to set the (given) user and\n"
+"    date, respectively. -U/--currentuser and -D/--currentdate set user\n"
+"    to current user and date to current date."
+msgstr ""
+
+msgid ""
+"    -e/--edit, -m/--message or -l/--logfile set the patch header as\n"
+"    well as the commit message. If none is specified, the header is\n"
+"    empty and the commit message is '[mq]: PATCH'."
+msgstr ""
+
+msgid ""
+"    Use the -g/--git option to keep the patch in the git extended diff\n"
+"    format. Read the diffs help topic for more information on why this\n"
+"    is important for preserving permission changes and copy/rename\n"
+"    information."
+msgstr ""
+
+msgid ""
+"    Returns 0 on successful creation of a new patch.\n"
+"    "
+msgstr ""
+
+msgid "refresh only files already in the patch and specified files"
+msgstr ""
+
+msgid "add/update author field in patch with current user"
+msgstr ""
+
+msgid "add/update author field in patch with given user"
+msgstr ""
+
+msgid "add/update date field in patch with current date"
+msgstr ""
+
+msgid "add/update date field in patch with given date"
+msgstr ""
+
+msgid "hg qrefresh [-I] [-X] [-e] [-m TEXT] [-l FILE] [-s] [FILE]..."
+msgstr ""
+
+msgid "update the current patch"
+msgstr ""
+
+msgid ""
+"    If any file patterns are provided, the refreshed patch will\n"
+"    contain only the modifications that match those patterns; the\n"
+"    remaining modifications will remain in the working directory."
+msgstr ""
+
+msgid ""
+"    If -s/--short is specified, files currently included in the patch\n"
+"    will be refreshed just like matched files and remain in the patch."
+msgstr ""
+
+msgid ""
+"    If -e/--edit is specified, Mercurial will start your configured editor "
+"for\n"
+"    you to enter a message. In case qrefresh fails, you will find a backup "
+"of\n"
+"    your message in ``.hg/last-message.txt``."
+msgstr ""
+
+msgid ""
+"    hg add/remove/copy/rename work as usual, though you might want to\n"
+"    use git-style patches (-g/--git or [diff] git=1) to track copies\n"
+"    and renames. See the diffs help topic for more information on the\n"
+"    git diff format."
+msgstr ""
+
+msgid "option \"-e\" incompatible with \"-m\" or \"-l\""
+msgstr ""
+
+msgid "hg qdiff [OPTION]... [FILE]..."
+msgstr ""
+
+msgid "diff of the current patch and subsequent modifications"
+msgstr ""
+
+msgid ""
+"    Shows a diff which includes the current patch as well as any\n"
+"    changes which have been made in the working directory since the\n"
+"    last refresh (thus showing what the current patch would become\n"
+"    after a qrefresh)."
+msgstr ""
+
+msgid ""
+"    Use :hg:`diff` if you only want to see the changes made since the\n"
+"    last qrefresh, or :hg:`export qtip` if you want to see changes\n"
+"    made by the current patch without including changes made since the\n"
+"    qrefresh."
+msgstr ""
+
+msgid "edit patch header"
+msgstr ""
+
+msgid "keep folded patch files"
+msgstr ""
+
+msgid "hg qfold [-e] [-k] [-m TEXT] [-l FILE] PATCH..."
+msgstr ""
+
+msgid "fold the named patches into the current patch"
+msgstr ""
+
+msgid ""
+"    Patches must not yet be applied. Each patch will be successively\n"
+"    applied to the current patch in the order given. If all the\n"
+"    patches apply successfully, the current patch will be refreshed\n"
+"    with the new cumulative patch, and the folded patches will be\n"
+"    deleted. With -k/--keep, the folded patch files will not be\n"
+"    removed afterwards."
+msgstr ""
+
+msgid ""
+"    The header for each folded patch will be concatenated with the\n"
+"    current patch header, separated by a line of ``* * *``."
+msgstr ""
+
+msgid "qfold requires at least one patch name"
+msgstr ""
+
+#, python-format
+msgid "Skipping already folded patch %s\n"
+msgstr ""
+
+#, python-format
+msgid "qfold cannot fold already applied patch %s"
+msgstr ""
+
+#, python-format
+msgid "error folding patch %s"
+msgstr ""
+
+msgid "overwrite any local changes"
+msgstr ""
+
+msgid "hg qgoto [OPTION]... PATCH"
+msgstr ""
+
+msgid "push or pop patches until named patch is at top of stack"
+msgstr ""
+
+msgid "list all patches and guards"
+msgstr ""
+
+msgid "drop all guards"
+msgstr ""
+
+msgid "hg qguard [-l] [-n] [PATCH] [-- [+GUARD]... [-GUARD]...]"
+msgstr ""
+
+msgid "set or print guards for a patch"
+msgstr ""
+
+msgid ""
+"    Guards control whether a patch can be pushed. A patch with no\n"
+"    guards is always pushed. A patch with a positive guard (\"+foo\") is\n"
+"    pushed only if the :hg:`qselect` command has activated it. A patch with\n"
+"    a negative guard (\"-foo\") is never pushed if the :hg:`qselect` "
+"command\n"
+"    has activated it."
+msgstr ""
+
+msgid ""
+"    With no arguments, print the currently active guards.\n"
+"    With arguments, set guards for the named patch."
+msgstr ""
+
+msgid ""
+"    .. note::\n"
+"       Specifying negative guards now requires '--'."
+msgstr ""
+
+msgid "    To set guards on another patch::"
+msgstr ""
+
+msgid "      hg qguard other.patch -- +2.6.17 -stable"
+msgstr ""
+
+msgid "cannot mix -l/--list with options or arguments"
+msgstr ""
+
+msgid "no patch to work with"
+msgstr ""
+
+#, python-format
+msgid "no patch named %s"
+msgstr ""
+
+msgid "hg qheader [PATCH]"
+msgstr ""
+
+msgid "print the header of the topmost or specified patch"
+msgstr ""
+
+msgid "apply on top of local changes"
+msgstr ""
+
+msgid "apply the target patch to its recorded parent"
+msgstr ""
+
+msgid "list patch name in commit text"
+msgstr ""
+
+msgid "apply all patches"
+msgstr ""
+
+msgid "merge from another queue (DEPRECATED)"
+msgstr ""
+
+msgid "merge queue name (DEPRECATED)"
+msgstr ""
+
+msgid "reorder patch series and apply only the patch"
+msgstr ""
+
+msgid "hg qpush [-f] [-l] [-a] [--move] [PATCH | INDEX]"
+msgstr ""
+
+msgid "push the next patch onto the stack"
+msgstr ""
+
+msgid ""
+"    When -f/--force is applied, all local changes in patched files\n"
+"    will be lost."
+msgstr ""
+
+msgid "no saved queues found, please use -n\n"
+msgstr ""
+
+#, python-format
+msgid "merging with queue at: %s\n"
+msgstr ""
+
+msgid "pop all patches"
+msgstr ""
+
+msgid "queue name to pop (DEPRECATED)"
+msgstr ""
+
+msgid "forget any local changes to patched files"
+msgstr ""
+
+msgid "hg qpop [-a] [-f] [PATCH | INDEX]"
+msgstr ""
+
+msgid "pop the current patch off the stack"
+msgstr ""
+
+msgid ""
+"    By default, pops off the top of the patch stack. If given a patch\n"
+"    name, keeps popping off patches until the named patch is at the\n"
+"    top of the stack."
+msgstr ""
+
+#, python-format
+msgid "using patch queue: %s\n"
+msgstr ""
+
+msgid "hg qrename PATCH1 [PATCH2]"
+msgstr ""
+
+msgid "rename a patch"
+msgstr ""
+
+msgid ""
+"    With one argument, renames the current patch to PATCH1.\n"
+"    With two arguments, renames PATCH1 to PATCH2."
+msgstr ""
+
+#, fuzzy, python-format
+msgid "%s already exists"
+msgstr "файл %s уже существует\n"
+
+#, python-format
+msgid "A patch named %s already exists in the series file"
+msgstr ""
+
+msgid "delete save entry"
+msgstr ""
+
+msgid "update queue working directory"
+msgstr ""
+
+msgid "hg qrestore [-d] [-u] REV"
+msgstr ""
+
+msgid "restore the queue state saved by a revision (DEPRECATED)"
+msgstr ""
+
+msgid "    This command is deprecated, use :hg:`rebase` instead."
+msgstr ""
+
+msgid "copy patch directory"
+msgstr ""
+
+msgid "copy directory name"
+msgstr ""
+
+msgid "clear queue status file"
+msgstr ""
+
+msgid "force copy"
+msgstr ""
+
+msgid "hg qsave [-m TEXT] [-l FILE] [-c] [-n NAME] [-e] [-f]"
+msgstr ""
+
+msgid "save current queue state (DEPRECATED)"
+msgstr ""
+
+#, python-format
+msgid "destination %s exists and is not a directory"
+msgstr ""
+
+#, python-format
+msgid "destination %s exists, use -f to force"
+msgstr ""
+
+#, python-format
+msgid "copy %s to %s\n"
+msgstr ""
+
+msgid "force removal of changesets, discard uncommitted changes (no backup)"
+msgstr ""
+
+msgid ""
+"bundle only changesets with local revision number greater than REV which are "
+"not descendants of REV (DEPRECATED)"
+msgstr ""
+
+msgid "no backups"
+msgstr ""
+
+msgid "no backups (DEPRECATED)"
+msgstr ""
+
+msgid "do not modify working copy during strip"
+msgstr ""
+
+msgid "hg strip [-k] [-f] [-n] REV..."
+msgstr ""
+
+msgid "strip changesets and all their descendants from the repository"
+msgstr ""
+
+msgid ""
+"    The strip command removes the specified changesets and all their\n"
+"    descendants. If the working directory has uncommitted changes, the\n"
+"    operation is aborted unless the --force flag is supplied, in which\n"
+"    case changes will be discarded."
+msgstr ""
+
+msgid ""
+"    If a parent of the working directory is stripped, then the working\n"
+"    directory will automatically be updated to the most recent\n"
+"    available ancestor of the stripped parent after the operation\n"
+"    completes."
+msgstr ""
+
+msgid ""
+"    Any stripped changesets are stored in ``.hg/strip-backup`` as a\n"
+"    bundle (see :hg:`help bundle` and :hg:`help unbundle`). They can\n"
+"    be restored by running :hg:`unbundle .hg/strip-backup/BUNDLE`,\n"
+"    where BUNDLE is the bundle file created by the strip. Note that\n"
+"    the local revision numbers will in general be different after the\n"
+"    restore."
+msgstr ""
+
+msgid ""
+"    Use the --no-backup option to discard the backup bundle once the\n"
+"    operation completes."
+msgstr ""
+
+msgid "empty revision set"
+msgstr ""
+
+msgid "disable all guards"
+msgstr ""
+
+msgid "list all guards in series file"
+msgstr ""
+
+msgid "pop to before first guarded applied patch"
+msgstr ""
+
+msgid "pop, then reapply patches"
+msgstr ""
+
+msgid "hg qselect [OPTION]... [GUARD]..."
+msgstr ""
+
+msgid "set or print guarded patches to push"
+msgstr ""
+
+msgid ""
+"    Use the :hg:`qguard` command to set or print guards on patch, then use\n"
+"    qselect to tell mq which guards to use. A patch will be pushed if\n"
+"    it has no guards or any positive guards match the currently\n"
+"    selected guard, but will not be pushed if any negative guards\n"
+"    match the current guard. For example::"
+msgstr ""
+
+msgid ""
+"        qguard foo.patch -- -stable    (negative guard)\n"
+"        qguard bar.patch    +stable    (positive guard)\n"
+"        qselect stable"
+msgstr ""
+
+msgid ""
+"    This activates the \"stable\" guard. mq will skip foo.patch (because\n"
+"    it has a negative match) but push bar.patch (because it has a\n"
+"    positive match)."
+msgstr ""
+
+msgid ""
+"    With no arguments, prints the currently active guards.\n"
+"    With one argument, sets the active guard."
+msgstr ""
+
+msgid ""
+"    Use -n/--none to deactivate guards (no other arguments needed).\n"
+"    When no guards are active, patches with positive guards are\n"
+"    skipped and patches with negative guards are pushed."
+msgstr ""
+
+msgid ""
+"    qselect can change the guards on applied patches. It does not pop\n"
+"    guarded patches by default. Use --pop to pop back to the last\n"
+"    applied patch that is not guarded. Use --reapply (which implies\n"
+"    --pop) to push back to the current patch afterwards, but skip\n"
+"    guarded patches."
+msgstr ""
+
+msgid ""
+"    Use -s/--series to print a list of all guards in the series file\n"
+"    (no other arguments needed). Use -v for more information."
+msgstr ""
+
+msgid "guards deactivated\n"
+msgstr ""
+
+#, python-format
+msgid "number of unguarded, unapplied patches has changed from %d to %d\n"
+msgstr ""
+
+#, python-format
+msgid "number of guarded, applied patches has changed from %d to %d\n"
+msgstr ""
+
+msgid "guards in series file:\n"
+msgstr ""
+
+msgid "no guards in series file\n"
+msgstr ""
+
+msgid "active guards:\n"
+msgstr ""
+
+msgid "no active guards\n"
+msgstr ""
+
+msgid "popping guarded patches\n"
+msgstr ""
+
+msgid "reapplying unguarded patches\n"
+msgstr ""
+
+msgid "finish all applied changesets"
+msgstr ""
+
+msgid "hg qfinish [-a] [REV]..."
+msgstr ""
+
+msgid "move applied patches into repository history"
+msgstr ""
+
+msgid ""
+"    Finishes the specified revisions (corresponding to applied\n"
+"    patches) by moving them out of mq control into regular repository\n"
+"    history."
+msgstr ""
+
+msgid ""
+"    Accepts a revision range or the -a/--applied option. If --applied\n"
+"    is specified, all applied mq revisions are removed from mq\n"
+"    control. Otherwise, the given revisions must be at the base of the\n"
+"    stack of applied patches."
+msgstr ""
+
+msgid ""
+"    This can be especially useful if your changes have been applied to\n"
+"    an upstream repository, or if you are about to push your changes\n"
+"    to upstream."
+msgstr ""
+
+msgid "no revisions specified"
+msgstr ""
+
+msgid "list all available queues"
+msgstr ""
+
+msgid "create new queue"
+msgstr ""
+
+msgid "rename active queue"
+msgstr ""
+
+msgid "delete reference to queue"
+msgstr ""
+
+msgid "delete queue, and remove patch dir"
+msgstr ""
+
+msgid "[OPTION] [QUEUE]"
+msgstr ""
+
+msgid "manage multiple patch queues"
+msgstr ""
+
+msgid ""
+"    Supports switching between different patch queues, as well as creating\n"
+"    new patch queues and deleting existing ones."
+msgstr ""
+
+msgid ""
+"    Omitting a queue name or specifying -l/--list will show you the "
+"registered\n"
+"    queues - by default the \"normal\" patches queue is registered. The "
+"currently\n"
+"    active queue will be marked with \"(active)\"."
+msgstr ""
+
+msgid ""
+"    To create a new queue, use -c/--create. The queue is automatically made\n"
+"    active, except in the case where there are applied patches from the\n"
+"    currently active queue in the repository. Then the queue will only be\n"
+"    created and switching will fail."
+msgstr ""
+
+msgid ""
+"    To delete an existing queue, use --delete. You cannot delete the "
+"currently\n"
+"    active queue."
+msgstr ""
+
+msgid "patches applied - cannot set new queue active"
+msgstr ""
+
+msgid "cannot delete queue that does not exist"
+msgstr ""
+
+msgid "cannot delete currently active queue"
+msgstr ""
+
+msgid " (active)\n"
+msgstr ""
+
+msgid "invalid queue name, may not contain the characters \":\\/.\""
+msgstr ""
+
+#, python-format
+msgid "queue \"%s\" already exists"
+msgstr ""
+
+#, python-format
+msgid "can't rename \"%s\" to its current name"
+msgstr ""
+
+#, python-format
+msgid "non-queue directory \"%s\" already exists"
+msgstr ""
+
+msgid "use --create to create a new queue"
+msgstr ""
+
+msgid "cannot commit over an applied mq patch"
+msgstr ""
+
+msgid "source has mq patches applied"
+msgstr ""
+
+#, python-format
+msgid "mq status file refers to unknown node %s\n"
+msgstr ""
+
+#, python-format
+msgid "Tag %s overrides mq patch of the same name\n"
+msgstr ""
+
+msgid "cannot import over an applied patch"
+msgstr ""
+
+msgid "only a local queue repository may be initialized"
+msgstr ""
+
+msgid "there is no Mercurial repository here (.hg not found)"
+msgstr ""
+
+msgid "no queue repository"
+msgstr ""
+
+#, python-format
+msgid "%d applied"
+msgstr ""
+
+#, python-format
+msgid "%d unapplied"
+msgstr ""
+
+msgid "mq:     (empty queue)\n"
+msgstr ""
+
+msgid ""
+"``mq()``\n"
+"    Changesets managed by MQ."
+msgstr ""
+
+#, fuzzy
+msgid "mq takes no arguments"
+msgstr "несовместимые аргументы"
+
+msgid "operate on patch repository"
+msgstr "работать с репозиторием патчей mq"
+
+msgid "hooks for sending email notifications at commit/push time"
+msgstr ""
+
+msgid ""
+"Subscriptions can be managed through a hgrc file. Default mode is to\n"
+"print messages to stdout, for testing and configuring."
+msgstr ""
+
+msgid ""
+"To use, configure the notify extension and enable it in hgrc like\n"
+"this::"
+msgstr ""
+
+msgid ""
+"  [extensions]\n"
+"  notify ="
+msgstr ""
+
+msgid ""
+"  [hooks]\n"
+"  # one email for each incoming changeset\n"
+"  incoming.notify = python:hgext.notify.hook\n"
+"  # batch emails when many changesets incoming at one time\n"
+"  changegroup.notify = python:hgext.notify.hook"
+msgstr ""
+
+msgid ""
+"  [notify]\n"
+"  # config items go here"
+msgstr ""
+
+msgid "Required configuration items::"
+msgstr ""
+
+msgid "  config = /path/to/file # file containing subscriptions"
+msgstr ""
+
+msgid "Optional configuration items::"
+msgstr ""
+
+msgid ""
+"  test = True            # print messages to stdout for testing\n"
+"  strip = 3              # number of slashes to strip for url paths\n"
+"  domain = example.com   # domain to use if committer missing domain\n"
+"  style = ...            # style file to use when formatting email\n"
+"  template = ...         # template to use when formatting email\n"
+"  incoming = ...         # template to use when run as incoming hook\n"
+"  changegroup = ...      # template when run as changegroup hook\n"
+"  maxdiff = 300          # max lines of diffs to include (0=none, -1=all)\n"
+"  maxsubject = 67        # truncate subject line longer than this\n"
+"  diffstat = True        # add a diffstat before the diff content\n"
+"  sources = serve        # notify if source of incoming changes in this "
+"list\n"
+"                         # (serve == ssh or http, push, pull, bundle)\n"
+"  merge = False          # send notification for merges (default True)\n"
+"  [email]\n"
+"  from = user@host.com   # email address to send as if none given\n"
+"  [web]\n"
+"  baseurl = http://hgserver/... # root of hg web site for browsing commits"
+msgstr ""
+
+msgid ""
+"The notify config file has same format as a regular hgrc file. It has\n"
+"two sections so you can express subscriptions in whatever way is\n"
+"handier for you."
+msgstr ""
+
+msgid ""
+"  [usersubs]\n"
+"  # key is subscriber email, value is \",\"-separated list of glob patterns\n"
+"  user@host = pattern"
+msgstr ""
+
+msgid ""
+"  [reposubs]\n"
+"  # key is glob pattern, value is \",\"-separated list of subscriber emails\n"
+"  pattern = user@host"
+msgstr ""
+
+msgid "Glob patterns are matched against path to repository root."
+msgstr ""
+
+msgid ""
+"If you like, you can put notify config file in repository that users\n"
+"can push changes to, they can manage their own subscriptions.\n"
+msgstr ""
+
+#, python-format
+msgid "%s: %d new changesets"
+msgstr ""
+
+#, python-format
+msgid "notify: sending %d subscribers %d changes\n"
+msgstr ""
+
+#, python-format
+msgid ""
+"\n"
+"diffs (truncated from %d to %d lines):"
+msgstr ""
+
+#, python-format
+msgid ""
+"\n"
+"diffs (%d lines):"
+msgstr ""
+
+#, python-format
+msgid "notify: suppressing notification for merge %d:%s\n"
+msgstr ""
+
+msgid "browse command output with an external pager"
+msgstr ""
+
+msgid "To set the pager that should be used, set the application variable::"
+msgstr ""
+
+msgid ""
+"  [pager]\n"
+"  pager = less -FRSX"
+msgstr ""
+
+msgid ""
+"If no pager is set, the pager extensions uses the environment variable\n"
+"$PAGER. If neither pager.pager, nor $PAGER is set, no pager is used."
+msgstr ""
+
+msgid ""
+"If you notice \"BROKEN PIPE\" error messages, you can disable them by\n"
+"setting::"
+msgstr ""
+
+msgid ""
+"  [pager]\n"
+"  quiet = True"
+msgstr ""
+
+msgid ""
+"You can disable the pager for certain commands by adding them to the\n"
+"pager.ignore list::"
+msgstr ""
+
+msgid ""
+"  [pager]\n"
+"  ignore = version, help, update"
+msgstr ""
+
+msgid ""
+"You can also enable the pager only for certain commands using\n"
+"pager.attend. Below is the default list of commands to be paged::"
+msgstr ""
+
+msgid ""
+"  [pager]\n"
+"  attend = annotate, cat, diff, export, glog, log, qdiff"
+msgstr ""
+
+msgid ""
+"Setting pager.attend to an empty value will cause all commands to be\n"
+"paged."
+msgstr ""
+
+msgid "If pager.attend is present, pager.ignore will be ignored."
+msgstr ""
+
+msgid ""
+"To ignore global commands like :hg:`version` or :hg:`help`, you have\n"
+"to specify them in your user configuration file."
+msgstr ""
+
+msgid ""
+"The --pager=... option can also be used to control when the pager is\n"
+"used. Use a boolean value like yes, no, on, off, or use auto for\n"
+"normal behavior.\n"
+msgstr ""
+
+msgid "when to paginate (boolean, always, auto, or never)"
+msgstr ""
+
+msgid "command to send changesets as (a series of) patch emails"
+msgstr ""
+
+msgid ""
+"The series is started off with a \"[PATCH 0 of N]\" introduction, which\n"
+"describes the series as a whole."
+msgstr ""
+
+msgid ""
+"Each patch email has a Subject line of \"[PATCH M of N] ...\", using the\n"
+"first line of the changeset description as the subject text. The\n"
+"message contains two or three body parts:"
+msgstr ""
+
+msgid ""
+"- The changeset description.\n"
+"- [Optional] The result of running diffstat on the patch.\n"
+"- The patch itself, as generated by :hg:`export`."
+msgstr ""
+
+msgid ""
+"Each message refers to the first in the series using the In-Reply-To\n"
+"and References headers, so they will show up as a sequence in threaded\n"
+"mail and news readers, and in mail archives."
+msgstr ""
+
+msgid ""
+"To configure other defaults, add a section like this to your\n"
+"configuration file::"
+msgstr ""
+
+msgid ""
+"  [email]\n"
+"  from = My Name <my@email>\n"
+"  to = recipient1, recipient2, ...\n"
+"  cc = cc1, cc2, ...\n"
+"  bcc = bcc1, bcc2, ...\n"
+"  reply-to = address1, address2, ..."
+msgstr ""
+
+msgid ""
+"Use ``[patchbomb]`` as configuration section name if you need to\n"
+"override global ``[email]`` address settings."
+msgstr ""
+
+msgid ""
+"Then you can use the :hg:`email` command to mail a series of\n"
+"changesets as a patchbomb."
+msgstr ""
+
+msgid ""
+"You can also either configure the method option in the email section\n"
+"to be a sendmail compatible mailer or fill out the [smtp] section so\n"
+"that the patchbomb extension can automatically send patchbombs\n"
+"directly from the commandline. See the [email] and [smtp] sections in\n"
+"hgrc(5) for details.\n"
+msgstr ""
+
+#, python-format
+msgid "%s Please enter a valid value"
+msgstr ""
+
+msgid "Please enter a valid value.\n"
+msgstr ""
+
+msgid "send patches as attachments"
+msgstr "отправить патчи как вложения"
+
+msgid "send patches as inline attachments"
+msgstr "отправить патчи как вложения в тексте"
+
+msgid "email addresses of blind carbon copy recipients"
+msgstr ""
+
+msgid "email addresses of copy recipients"
+msgstr ""
+
+msgid "ask for confirmation before sending"
+msgstr ""
+
+msgid "add diffstat output to messages"
+msgstr "добавить статистику различий к сообщениям"
+
+msgid "use the given date as the sending date"
+msgstr ""
+
+msgid "use the given file as the series description"
+msgstr ""
+
+msgid "email address of sender"
+msgstr ""
+
+msgid "print messages that would be sent"
+msgstr ""
+
+msgid "write messages to mbox file instead of sending them"
+msgstr ""
+
+msgid "email addresses replies should be sent to"
+msgstr ""
+
+msgid "subject of first message (intro or single patch)"
+msgstr ""
+
+msgid "message identifier to reply to"
+msgstr ""
+
+msgid "flags to add in subject prefixes"
+msgstr ""
+
+msgid "email addresses of recipients"
+msgstr ""
+
+msgid "omit hg patch header"
+msgstr ""
+
+msgid "send changes not found in the target repository"
+msgstr ""
+
+msgid "send changes not in target as a binary bundle"
+msgstr ""
+
+msgid "name of the bundle attachment file"
+msgstr ""
+
+msgid "a revision to send"
+msgstr ""
+
+msgid "run even when remote repository is unrelated (with -b/--bundle)"
+msgstr ""
+
+msgid "a base changeset to specify instead of a destination (with -b/--bundle)"
+msgstr ""
+
+msgid "send an introduction email for a single patch"
+msgstr ""
+
+msgid "hg email [OPTION]... [DEST]..."
+msgstr ""
+
+msgid "send changesets by email"
+msgstr ""
+
+msgid ""
+"    By default, diffs are sent in the format generated by\n"
+"    :hg:`export`, one per message. The series starts with a \"[PATCH 0\n"
+"    of N]\" introduction, which describes the series as a whole."
+msgstr ""
+
+msgid ""
+"    Each patch email has a Subject line of \"[PATCH M of N] ...\", using\n"
+"    the first line of the changeset description as the subject text.\n"
+"    The message contains two or three parts. First, the changeset\n"
+"    description."
+msgstr ""
+
+msgid ""
+"    With the -d/--diffstat option, if the diffstat program is\n"
+"    installed, the result of running diffstat on the patch is inserted."
+msgstr ""
+
+msgid "    Finally, the patch itself, as generated by :hg:`export`."
+msgstr ""
+
+msgid ""
+"    With the -d/--diffstat or -c/--confirm options, you will be presented\n"
+"    with a final summary of all messages and asked for confirmation before\n"
+"    the messages are sent."
+msgstr ""
+
+msgid ""
+"    By default the patch is included as text in the email body for\n"
+"    easy reviewing. Using the -a/--attach option will instead create\n"
+"    an attachment for the patch. With -i/--inline an inline attachment\n"
+"    will be created."
+msgstr ""
+
+msgid ""
+"    With -o/--outgoing, emails will be generated for patches not found\n"
+"    in the destination repository (or only those which are ancestors\n"
+"    of the specified revisions if any are provided)"
+msgstr ""
+
+msgid ""
+"    With -b/--bundle, changesets are selected as for --outgoing, but a\n"
+"    single email containing a binary Mercurial bundle as an attachment\n"
+"    will be sent."
+msgstr ""
+
+msgid ""
+"    With -m/--mbox, instead of previewing each patchbomb message in a\n"
+"    pager or sending the messages directly, it will create a UNIX\n"
+"    mailbox file with the patch emails. This mailbox file can be\n"
+"    previewed with any mail user agent which supports UNIX mbox\n"
+"    files."
+msgstr ""
+
+msgid ""
+"    With -n/--test, all steps will run, but mail will not be sent.\n"
+"    You will be prompted for an email recipient address, a subject and\n"
+"    an introductory message describing the patches of your patchbomb.\n"
+"    Then when all is done, patchbomb messages are displayed. If the\n"
+"    PAGER environment variable is set, your pager will be fired up once\n"
+"    for each patchbomb message, so you can verify everything is alright."
+msgstr ""
+
+msgid ""
+"    In case email sending fails, you will find a backup of your series\n"
+"    introductory message in ``.hg/last-email.txt``."
+msgstr ""
+
+msgid ""
+"      hg email -r 3000          # send patch 3000 only\n"
+"      hg email -r 3000 -r 3001  # send patches 3000 and 3001\n"
+"      hg email -r 3000:3005     # send patches 3000 through 3005\n"
+"      hg email 3000             # send patch 3000 (deprecated)"
+msgstr ""
+
+msgid ""
+"      hg email -o               # send all patches not in default\n"
+"      hg email -o DEST          # send all patches not in DEST\n"
+"      hg email -o -r 3000       # send all ancestors of 3000 not in default\n"
+"      hg email -o -r 3000 DEST  # send all ancestors of 3000 not in DEST"
+msgstr ""
+
+msgid ""
+"      hg email -b               # send bundle of all patches not in default\n"
+"      hg email -b DEST          # send bundle of all patches not in DEST\n"
+"      hg email -b -r 3000       # bundle of all ancestors of 3000 not in "
+"default\n"
+"      hg email -b -r 3000 DEST  # bundle of all ancestors of 3000 not in DEST"
+msgstr ""
+
+msgid ""
+"      hg email -o -m mbox &&    # generate an mbox file...\n"
+"        mutt -R -f mbox         # ... and view it with mutt\n"
+"      hg email -o -m mbox &&    # generate an mbox file ...\n"
+"        formail -s sendmail \\   # ... and use formail to send from the "
+"mbox\n"
+"          -bm -t < mbox         # ... using sendmail"
+msgstr ""
+
+msgid ""
+"    Before using this command, you will need to enable email in your\n"
+"    hgrc. See the [email] section in hgrc(5) for details.\n"
+"    "
+msgstr ""
+
+#, python-format
+msgid "comparing with %s\n"
+msgstr ""
+
+msgid "no changes found\n"
+msgstr ""
+
+msgid "specify at least one changeset with -r or -o"
+msgstr ""
+
+msgid "--outgoing mode always on with --bundle; do not re-specify --outgoing"
+msgstr ""
+
+msgid "too many destinations"
+msgstr ""
+
+msgid "use only one form to specify the revision"
+msgstr ""
+
+msgid ""
+"\n"
+"Write the introductory message for the patch series."
+msgstr ""
+
+#, python-format
+msgid "This patch series consists of %d patches."
+msgstr ""
+
+msgid ""
+"\n"
+"Final summary:"
+msgstr ""
+
+msgid "are you sure you want to send (yn)?"
+msgstr ""
+
+msgid "&No"
+msgstr "&Нет"
+
+msgid "&Yes"
+msgstr "&Да"
+
+msgid "patchbomb canceled"
+msgstr ""
+
+msgid "Displaying "
+msgstr ""
+
+msgid "Writing "
+msgstr ""
+
+msgid "writing"
+msgstr ""
+
+msgid "Sending "
+msgstr ""
+
+msgid "sending"
+msgstr ""
+
+msgid "show progress bars for some actions"
+msgstr ""
+
+msgid ""
+"This extension uses the progress information logged by hg commands\n"
+"to draw progress bars that are as informative as possible. Some progress\n"
+"bars only offer indeterminate information, while others have a definite\n"
+"end point."
+msgstr ""
+
+msgid "The following settings are available::"
+msgstr ""
+
+msgid ""
+"  [progress]\n"
+"  delay = 3 # number of seconds (float) before showing the progress bar\n"
+"  refresh = 0.1 # time in seconds between refreshes of the progress bar\n"
+"  format = topic bar number estimate # format of the progress bar\n"
+"  width = <none> # if set, the maximum width of the progress information\n"
+"                 # (that is, min(width, term width) will be used)\n"
+"  clear-complete = True # clear the progress bar after it's done\n"
+"  disable = False # if true, don't show a progress bar\n"
+"  assume-tty = False # if true, ALWAYS show a progress bar, unless\n"
+"                     # disable is given"
+msgstr ""
+
+msgid ""
+"Valid entries for the format field are topic, bar, number, unit,\n"
+"estimate, speed, and item. item defaults to the last 20 characters of\n"
+"the item, but this can be changed by adding either ``-<num>`` which\n"
+"would take the last num characters, or ``+<num>`` for the first num\n"
+"characters.\n"
+msgstr ""
+
+#. i18n: format XX seconds as "XXs"
+#, python-format
+msgid "%02ds"
+msgstr ""
+
+#. i18n: format X minutes and YY seconds as "XmYYs"
+#, python-format
+msgid "%dm%02ds"
+msgstr ""
+
+#. i18n: format X hours and YY minutes as "XhYYm"
+#, python-format
+msgid "%dh%02dm"
+msgstr ""
+
+#. i18n: format X days and YY hours as "XdYYh"
+#, python-format
+msgid "%dd%02dh"
+msgstr ""
+
+#. i18n: format X weeks and YY days as "XwYYd"
+#, python-format
+msgid "%dw%02dd"
+msgstr ""
+
+#. i18n: format X years and YY weeks as "XyYYw"
+#, python-format
+msgid "%dy%02dw"
+msgstr ""
+
+#, python-format
+msgid "%d %s/sec"
+msgstr ""
+
+msgid "command to delete untracked files from the working directory"
+msgstr ""
+
+msgid "abort if an error occurs"
+msgstr ""
+
+msgid "purge ignored files too"
+msgstr ""
+
+msgid "print filenames instead of deleting them"
+msgstr ""
+
+msgid "end filenames with NUL, for use with xargs (implies -p/--print)"
+msgstr ""
+
+msgid "hg purge [OPTION]... [DIR]..."
+msgstr ""
+
+msgid "removes files not tracked by Mercurial"
+msgstr ""
+
+msgid ""
+"    Delete files not known to Mercurial. This is useful to test local\n"
+"    and uncommitted changes in an otherwise-clean source tree."
+msgstr ""
+
+msgid "    This means that purge will delete:"
+msgstr ""
+
+msgid ""
+"    - Unknown files: files marked with \"?\" by :hg:`status`\n"
+"    - Empty directories: in fact Mercurial ignores directories unless\n"
+"      they contain files under source control management"
+msgstr ""
+
+msgid "    But it will leave untouched:"
+msgstr ""
+
+msgid ""
+"    - Modified and unmodified tracked files\n"
+"    - Ignored files (unless --all is specified)\n"
+"    - New files added to the repository (with :hg:`add`)"
+msgstr ""
+
+msgid ""
+"    If directories are given on the command line, only files in these\n"
+"    directories are considered."
+msgstr ""
+
+msgid ""
+"    Be careful with purge, as you could irreversibly delete some files\n"
+"    you forgot to add to the repository. If you only want to print the\n"
+"    list of files that this program would delete, use the --print\n"
+"    option.\n"
+"    "
+msgstr ""
+
+#, python-format
+msgid "%s cannot be removed"
+msgstr ""
+
+#, python-format
+msgid "warning: %s\n"
+msgstr ""
+
+#, python-format
+msgid "Removing file %s\n"
+msgstr ""
+
+#, python-format
+msgid "Removing directory %s\n"
+msgstr ""
+
+msgid "command to move sets of revisions to a different ancestor"
+msgstr ""
+
+msgid ""
+"This extension lets you rebase changesets in an existing Mercurial\n"
+"repository."
+msgstr ""
+
+msgid ""
+"For more information:\n"
+"http://mercurial.selenic.com/wiki/RebaseExtension\n"
+msgstr ""
+
+msgid "rebase from the specified changeset"
+msgstr ""
+
+msgid ""
+"rebase from the base of the specified changeset (up to greatest common "
+"ancestor of base and dest)"
+msgstr ""
+
+msgid "rebase onto the specified changeset"
+msgstr ""
+
+msgid "collapse the rebased changesets"
+msgstr ""
+
+msgid "use text as collapse commit message"
+msgstr ""
+
+msgid "read collapse commit message from file"
+msgstr ""
+
+msgid "keep original changesets"
+msgstr ""
+
+msgid "keep original branch names"
+msgstr ""
+
+msgid "force detaching of source from its original branch"
+msgstr ""
+
+msgid "specify merge tool"
+msgstr ""
+
+msgid "continue an interrupted rebase"
+msgstr ""
+
+msgid "abort an interrupted rebase"
+msgstr ""
+
+msgid ""
+"hg rebase [-s REV | -b REV] [-d REV] [options]\n"
+"hg rebase {-a|-c}"
+msgstr ""
+
+msgid "move changeset (and descendants) to a different branch"
+msgstr ""
+
+msgid ""
+"    Rebase uses repeated merging to graft changesets from one part of\n"
+"    history (the source) onto another (the destination). This can be\n"
+"    useful for linearizing *local* changes relative to a master\n"
+"    development tree."
+msgstr ""
+
+msgid ""
+"    You should not rebase changesets that have already been shared\n"
+"    with others. Doing so will force everybody else to perform the\n"
+"    same rebase or they will end up with duplicated changesets after\n"
+"    pulling in your rebased changesets."
+msgstr ""
+
+msgid ""
+"    If you don't specify a destination changeset (``-d/--dest``),\n"
+"    rebase uses the tipmost head of the current named branch as the\n"
+"    destination. (The destination changeset is not modified by\n"
+"    rebasing, but new changesets are added as its descendants.)"
+msgstr ""
+
+msgid ""
+"    You can specify which changesets to rebase in two ways: as a\n"
+"    \"source\" changeset or as a \"base\" changeset. Both are shorthand\n"
+"    for a topologically related set of changesets (the \"source\n"
+"    branch\"). If you specify source (``-s/--source``), rebase will\n"
+"    rebase that changeset and all of its descendants onto dest. If you\n"
+"    specify base (``-b/--base``), rebase will select ancestors of base\n"
+"    back to but not including the common ancestor with dest. Thus,\n"
+"    ``-b`` is less precise but more convenient than ``-s``: you can\n"
+"    specify any changeset in the source branch, and rebase will select\n"
+"    the whole branch. If you specify neither ``-s`` nor ``-b``, rebase\n"
+"    uses the parent of the working directory as the base."
+msgstr ""
+
+msgid ""
+"    By default, rebase recreates the changesets in the source branch\n"
+"    as descendants of dest and then destroys the originals. Use\n"
+"    ``--keep`` to preserve the original source changesets. Some\n"
+"    changesets in the source branch (e.g. merges from the destination\n"
+"    branch) may be dropped if they no longer contribute any change."
+msgstr ""
+
+msgid ""
+"    One result of the rules for selecting the destination changeset\n"
+"    and source branch is that, unlike ``merge``, rebase will do\n"
+"    nothing if you are at the latest (tipmost) head of a named branch\n"
+"    with two heads. You need to explicitly specify source and/or\n"
+"    destination (or ``update`` to the other head, if it's the head of\n"
+"    the intended source branch)."
+msgstr ""
+
+msgid ""
+"    If a rebase is interrupted to manually resolve a merge, it can be\n"
+"    continued with --continue/-c or aborted with --abort/-a."
+msgstr ""
+
+msgid ""
+"    Returns 0 on success, 1 if nothing to rebase.\n"
+"    "
+msgstr ""
+
+msgid "message can only be specified with collapse"
+msgstr ""
+
+msgid "cannot use both abort and continue"
+msgstr ""
+
+msgid "cannot use collapse with continue or abort"
+msgstr ""
+
+msgid "cannot use detach with continue or abort"
+msgstr ""
+
+msgid "abort and continue do not allow specifying revisions"
+msgstr ""
+
+msgid "tool option will be ignored\n"
+msgstr ""
+
+msgid "cannot specify both a revision and a base"
+msgstr ""
+
+msgid "detach requires a revision to be specified"
+msgstr ""
+
+msgid "cannot specify a base with detach"
+msgstr ""
+
+msgid "nothing to rebase\n"
+msgstr ""
+
+msgid "rebasing"
+msgstr ""
+
+msgid "changesets"
+msgstr ""
+
+msgid "unresolved conflicts (see hg resolve, then hg rebase --continue)"
+msgstr ""
+
+#, python-format
+msgid "no changes, revision %d skipped\n"
+msgstr ""
+
+msgid "rebase merging completed\n"
+msgstr ""
+
+msgid "warning: new changesets detected on source branch, not stripping\n"
+msgstr ""
+
+msgid "rebase completed\n"
+msgstr ""
+
+#, python-format
+msgid "%d revisions have been skipped\n"
+msgstr ""
+
+msgid "unable to collapse, there is more than one external parent"
+msgstr ""
+
+#, python-format
+msgid "cannot use revision %d as base, result would have 3 parents"
+msgstr ""
+
+msgid "no rebase in progress"
+msgstr ""
+
+msgid "warning: new changesets detected on target branch, can't abort\n"
+msgstr ""
+
+msgid "rebase aborted\n"
+msgstr ""
+
+msgid "cannot rebase onto an applied mq patch"
+msgstr ""
+
+msgid "source is ancestor of destination"
+msgstr ""
+
+msgid "source is descendant of destination"
+msgstr ""
+
+msgid "rebase working directory to branch head"
+msgstr "перебазировать рабочий каталог поверх головы ветви"
+
+msgid "commands to interactively select changes for commit/qrefresh"
+msgstr ""
+
+msgid "this modifies a binary file (all or nothing)\n"
+msgstr "это изменяет двоичный файл (всё или ничего)\n"
+
+msgid "this is a binary file\n"
+msgstr "это двоичный файл\n"
+
+#, python-format
+msgid "%d hunks, %d lines changed\n"
+msgstr "изменено полос: %d, строк: %d\n"
+
+msgid "[Ynsfdaq?]"
+msgstr ""
+
+msgid "&Yes, record this change"
+msgstr ""
+
+msgid "&No, skip this change"
+msgstr ""
+
+msgid "&Skip remaining changes to this file"
+msgstr ""
+
+msgid "Record remaining changes to this &file"
+msgstr ""
+
+msgid "&Done, skip remaining changes and files"
+msgstr ""
+
+msgid "Record &all changes to all remaining files"
+msgstr ""
+
+msgid "&Quit, recording no changes"
+msgstr ""
+
+msgid "&?"
+msgstr ""
+
+msgid "user quit"
+msgstr "пользовательский выход"
+
+#, python-format
+msgid "examine changes to %s?"
+msgstr ""
+
+msgid " and "
+msgstr " и "
+
+#, python-format
+msgid "record this change to %r?"
+msgstr ""
+
+#, python-format
+msgid "record change %d/%d to %r?"
+msgstr ""
+
+msgid "interactively select changes to commit"
+msgstr ""
+
+msgid ""
+"    If a list of files is omitted, all changes reported by :hg:`status`\n"
+"    will be candidates for recording."
+msgstr ""
+
+msgid ""
+"    You will be prompted for whether to record changes to each\n"
+"    modified file, and for files with multiple changes, for each\n"
+"    change to use. For each query, the following responses are\n"
+"    possible::"
+msgstr ""
+
+msgid ""
+"      y - record this change\n"
+"      n - skip this change"
+msgstr ""
+
+msgid ""
+"      s - skip remaining changes to this file\n"
+"      f - record remaining changes to this file"
+msgstr ""
+
+msgid ""
+"      d - done, skip remaining changes and files\n"
+"      a - record all changes to all remaining files\n"
+"      q - quit, recording no changes"
+msgstr ""
+
+msgid "      ? - display help"
+msgstr ""
+
+msgid "    This command is not available when committing a merge."
+msgstr ""
+
+msgid "interactively record a new patch"
+msgstr ""
+
+msgid ""
+"    See :hg:`help qnew` & :hg:`help record` for more information and\n"
+"    usage.\n"
+"    "
+msgstr ""
+
+msgid "'mq' extension not loaded"
+msgstr ""
+
+msgid "running non-interactively, use commit instead"
+msgstr ""
+
+msgid "cannot partially commit a merge (use \"hg commit\" instead)"
+msgstr ""
+
+msgid "no changes to record\n"
+msgstr ""
+
+msgid "hg record [OPTION]... [FILE]..."
+msgstr ""
+
+msgid "hg qrecord [OPTION]... PATCH [FILE]..."
+msgstr ""
+
+msgid "recreates hardlinks between repository clones"
+msgstr ""
+
+msgid "recreate hardlinks between two repositories"
+msgstr ""
+
+msgid ""
+"    When repositories are cloned locally, their data files will be\n"
+"    hardlinked so that they only use the space of a single repository."
+msgstr ""
+
+msgid ""
+"    Unfortunately, subsequent pulls into either repository will break\n"
+"    hardlinks for any files touched by the new changesets, even if\n"
+"    both repositories end up pulling the same changes."
+msgstr ""
+
+msgid ""
+"    Similarly, passing --rev to \"hg clone\" will fail to use any\n"
+"    hardlinks, falling back to a complete copy of the source\n"
+"    repository."
+msgstr ""
+
+msgid ""
+"    This command lets you recreate those hardlinks and reclaim that\n"
+"    wasted space."
+msgstr ""
+
+msgid ""
+"    This repository will be relinked to share space with ORIGIN, which\n"
+"    must be on the same local disk. If ORIGIN is omitted, looks for\n"
+"    \"default-relink\", then \"default\", in [paths]."
+msgstr ""
+
+msgid ""
+"    Do not attempt any read operations on this repository while the\n"
+"    command is running. (Both repositories will be locked against\n"
+"    writes.)\n"
+"    "
+msgstr ""
+
+msgid "hardlinks are not supported on this system"
+msgstr ""
+
+msgid "must specify local origin repository"
+msgstr ""
+
+#, python-format
+msgid "relinking %s to %s\n"
+msgstr ""
+
+msgid "there is nothing to relink\n"
+msgstr ""
+
+#, python-format
+msgid "tip has %d files, estimated total number of files: %s\n"
+msgstr ""
+
+msgid "collecting"
+msgstr ""
+
+msgid "files"
+msgstr ""
+
+#, python-format
+msgid "collected %d candidate storage files\n"
+msgstr ""
+
+msgid "source and destination are on different devices"
+msgstr ""
+
+#, python-format
+msgid "not linkable: %s\n"
+msgstr ""
+
+msgid "pruning"
+msgstr ""
+
+#, python-format
+msgid "pruned down to %d probably relinkable files\n"
+msgstr ""
+
+msgid "relinking"
+msgstr ""
+
+#, python-format
+msgid "relinked %d files (%s reclaimed)\n"
+msgstr ""
+
+msgid "[ORIGIN]"
+msgstr ""
+
+msgid "extend schemes with shortcuts to repository swarms"
+msgstr ""
+
+msgid ""
+"This extension allows you to specify shortcuts for parent URLs with a\n"
+"lot of repositories to act like a scheme, for example::"
+msgstr ""
+
+msgid ""
+"  [schemes]\n"
+"  py = http://code.python.org/hg/"
+msgstr ""
+
+msgid "After that you can use it like::"
+msgstr ""
+
+msgid "  hg clone py://trunk/"
+msgstr ""
+
+msgid ""
+"Additionally there is support for some more complex schemas, for\n"
+"example used by Google Code::"
+msgstr ""
+
+msgid ""
+"  [schemes]\n"
+"  gcode = http://{1}.googlecode.com/hg/"
+msgstr ""
+
+msgid ""
+"The syntax is taken from Mercurial templates, and you have unlimited\n"
+"number of variables, starting with ``{1}`` and continuing with\n"
+"``{2}``, ``{3}`` and so on. This variables will receive parts of URL\n"
+"supplied, split by ``/``. Anything not specified as ``{part}`` will be\n"
+"just appended to an URL."
+msgstr ""
+
+msgid "For convenience, the extension adds these schemes by default::"
+msgstr ""
+
+msgid ""
+"  [schemes]\n"
+"  py = http://hg.python.org/\n"
+"  bb = https://bitbucket.org/\n"
+"  bb+ssh = ssh://hg@bitbucket.org/\n"
+"  gcode = https://{1}.googlecode.com/hg/\n"
+"  kiln = https://{1}.kilnhg.com/Repo/"
+msgstr ""
+
+msgid ""
+"You can override a predefined scheme by defining a new scheme with the\n"
+"same name.\n"
+msgstr ""
+
+#, python-format
+msgid "custom scheme %s:// conflicts with drive letter %s:\\\n"
+msgstr ""
+
+msgid "share a common history between several working directories"
+msgstr ""
+
+msgid "create a new shared repository"
+msgstr ""
+
+msgid ""
+"    Initialize a new repository and working directory that shares its\n"
+"    history with another repository."
+msgstr ""
+
+msgid ""
+"    .. note::\n"
+"       using rollback or extensions that destroy/modify history (mq,\n"
+"       rebase, etc.) can cause considerable confusion with shared\n"
+"       clones. In particular, if two shared clones are both updated to\n"
+"       the same changeset, and one of them destroys that changeset\n"
+"       with rollback, the other clone will suddenly stop working: all\n"
+"       operations will fail with \"abort: working directory has unknown\n"
+"       parent\". The only known workaround is to use debugsetparents on\n"
+"       the broken clone to reset it to a changeset that still exists\n"
+"       (e.g. tip).\n"
+"    "
+msgstr ""
+
+msgid "do not create a working copy"
+msgstr ""
+
+msgid "[-U] SOURCE [DEST]"
+msgstr ""
+
+msgid "command to transplant changesets from another branch"
+msgstr ""
+
+msgid "This extension allows you to transplant patches from another branch."
+msgstr ""
+
+msgid ""
+"Transplanted patches are recorded in .hg/transplant/transplants, as a\n"
+"map from a changeset hash to its hash in the source repository.\n"
+msgstr ""
+
+#, python-format
+msgid "skipping already applied revision %s\n"
+msgstr ""
+
+#, python-format
+msgid "skipping merge changeset %s:%s\n"
+msgstr ""
+
+#, python-format
+msgid "%s merged at %s\n"
+msgstr ""
+
+#, python-format
+msgid "%s transplanted to %s\n"
+msgstr ""
+
+#, python-format
+msgid "filtering %s\n"
+msgstr ""
+
+msgid "filter failed"
+msgstr ""
+
+msgid "can only omit patchfile if merging"
+msgstr ""
+
+#, python-format
+msgid "%s: empty changeset"
+msgstr ""
+
+msgid "fix up the merge and run hg transplant --continue"
+msgstr ""
+
+#, python-format
+msgid "%s transplanted as %s\n"
+msgstr ""
+
+msgid "transplant log file is corrupt"
+msgstr ""
+
+#, python-format
+msgid "working dir not at transplant parent %s"
+msgstr ""
+
+msgid "commit failed"
+msgstr ""
+
+msgid "filter corrupted changeset (no user or date)"
+msgstr ""
+
+msgid ""
+"y: transplant this changeset\n"
+"n: skip this changeset\n"
+"m: merge at this changeset\n"
+"p: show patch\n"
+"c: commit selected changesets\n"
+"q: cancel transplant\n"
+"?: show this help\n"
+msgstr ""
+
+msgid "apply changeset? [ynmpcq?]:"
+msgstr ""
+
+msgid "no such option\n"
+msgstr ""
+
+msgid "pull patches from REPO"
+msgstr ""
+
+msgid "BRANCH"
+msgstr "ВЕТВЬ"
+
+msgid "pull patches from branch BRANCH"
+msgstr ""
+
+msgid "pull all changesets up to BRANCH"
+msgstr ""
+
+msgid "skip over REV"
+msgstr ""
+
+msgid "merge at REV"
+msgstr ""
+
+msgid "append transplant info to log message"
+msgstr ""
+
+msgid "continue last transplant session after repair"
+msgstr ""
+
+msgid "filter changesets through command"
+msgstr ""
+
+msgid "hg transplant [-s REPO] [-b BRANCH [-a]] [-p REV] [-m REV] [REV]..."
+msgstr ""
+
+msgid "transplant changesets from another branch"
+msgstr ""
+
+msgid ""
+"    Selected changesets will be applied on top of the current working\n"
+"    directory with the log of the original changeset. The changesets\n"
+"    are copied and will thus appear twice in the history. Use the\n"
+"    rebase extension instead if you want to move a whole branch of\n"
+"    unpublished changesets."
+msgstr ""
+
+msgid ""
+"    If --log is specified, log messages will have a comment appended\n"
+"    of the form::"
+msgstr ""
+
+msgid "      (transplanted from CHANGESETHASH)"
+msgstr ""
+
+msgid ""
+"    You can rewrite the changelog message with the --filter option.\n"
+"    Its argument will be invoked with the current changelog message as\n"
+"    $1 and the patch as $2."
+msgstr ""
+
+msgid ""
+"    If --source/-s is specified, selects changesets from the named\n"
+"    repository. If --branch/-b is specified, selects changesets from\n"
+"    the branch holding the named revision, up to that revision. If\n"
+"    --all/-a is specified, all changesets on the branch will be\n"
+"    transplanted, otherwise you will be prompted to select the\n"
+"    changesets you want."
+msgstr ""
+
+msgid ""
+"    :hg:`transplant --branch REVISION --all` will transplant the\n"
+"    selected branch (up to the named revision) onto your current\n"
+"    working directory."
+msgstr ""
+
+msgid ""
+"    You can optionally mark selected transplanted changesets as merge\n"
+"    changesets. You will not be prompted to transplant any ancestors\n"
+"    of a merged transplant, and you can merge descendants of them\n"
+"    normally instead of transplanting them."
+msgstr ""
+
+msgid ""
+"    If no merges or revisions are provided, :hg:`transplant` will\n"
+"    start an interactive changeset browser."
+msgstr ""
+
+msgid ""
+"    If a changeset application fails, you can fix the merge by hand\n"
+"    and then resume where you left off by calling :hg:`transplant\n"
+"    --continue/-c`.\n"
+"    "
+msgstr ""
+
+msgid "--continue is incompatible with branch, all or merge"
+msgstr ""
+
+msgid "no source URL, branch tag or revision list provided"
+msgstr ""
+
+msgid "--all requires a branch revision"
+msgstr ""
+
+msgid "--all is incompatible with a revision list"
+msgstr ""
+
+msgid "no revision checked out"
+msgstr ""
+
+msgid "outstanding uncommitted merges"
+msgstr ""
+
+msgid "outstanding local changes"
+msgstr ""
+
+msgid ""
+"``transplanted([set])``\n"
+"    Transplanted changesets in set, or all transplanted changesets."
+msgstr ""
+
+msgid ""
+":transplanted: String. The node identifier of the transplanted\n"
+"    changeset if any."
+msgstr ""
+
+msgid "allow the use of MBCS paths with problematic encodings"
+msgstr ""
+
+msgid ""
+"Some MBCS encodings are not good for some path operations (i.e.\n"
+"splitting path, case conversion, etc.) with its encoded bytes. We call\n"
+"such a encoding (i.e. shift_jis and big5) as \"problematic encoding\".\n"
+"This extension can be used to fix the issue with those encodings by\n"
+"wrapping some functions to convert to Unicode string before path\n"
+"operation."
+msgstr ""
+
+msgid "This extension is useful for:"
+msgstr ""
+
+msgid ""
+"- Japanese Windows users using shift_jis encoding.\n"
+"- Chinese Windows users using big5 encoding.\n"
+"- All users who use a repository with one of problematic encodings on\n"
+"  case-insensitive file system."
+msgstr ""
+
+msgid "This extension is not needed for:"
+msgstr ""
+
+msgid ""
+"- Any user who use only ASCII chars in path.\n"
+"- Any user who do not use any of problematic encodings."
+msgstr ""
+
+msgid "Note that there are some limitations on using this extension:"
+msgstr ""
+
+msgid ""
+"- You should use single encoding in one repository.\n"
+"- If the repository path ends with 0x5c, .hg/hgrc cannot be read.\n"
+"- win32mbcs is not compatible with fixutf8 extension."
+msgstr ""
+
+msgid ""
+"By default, win32mbcs uses encoding.encoding decided by Mercurial.\n"
+"You can specify the encoding by config option::"
+msgstr ""
+
+msgid ""
+" [win32mbcs]\n"
+" encoding = sjis"
+msgstr ""
+
+msgid "It is useful for the users who want to commit with UTF-8 log message.\n"
+msgstr ""
+
+#, python-format
+msgid "[win32mbcs] filename conversion failed with %s encoding\n"
+msgstr ""
+
+msgid "[win32mbcs] cannot activate on this platform.\n"
+msgstr ""
+
+msgid "perform automatic newline conversion"
+msgstr ""
+
+msgid ""
+"  Deprecation: The win32text extension requires each user to configure\n"
+"  the extension again and again for each clone since the configuration\n"
+"  is not copied when cloning."
+msgstr ""
+
+msgid ""
+"  We have therefore made the ``eol`` as an alternative. The ``eol``\n"
+"  uses a version controlled file for its configuration and each clone\n"
+"  will therefore use the right settings from the start."
+msgstr ""
+
+msgid "To perform automatic newline conversion, use::"
+msgstr ""
+
+msgid ""
+"  [extensions]\n"
+"  win32text =\n"
+"  [encode]\n"
+"  ** = cleverencode:\n"
+"  # or ** = macencode:"
+msgstr ""
+
+msgid ""
+"  [decode]\n"
+"  ** = cleverdecode:\n"
+"  # or ** = macdecode:"
+msgstr ""
+
+msgid ""
+"If not doing conversion, to make sure you do not commit CRLF/CR by accident::"
+msgstr ""
+
+msgid ""
+"  [hooks]\n"
+"  pretxncommit.crlf = python:hgext.win32text.forbidcrlf\n"
+"  # or pretxncommit.cr = python:hgext.win32text.forbidcr"
+msgstr ""
+
+msgid ""
+"To do the same check on a server to prevent CRLF/CR from being\n"
+"pushed or pulled::"
+msgstr ""
+
+msgid ""
+"  [hooks]\n"
+"  pretxnchangegroup.crlf = python:hgext.win32text.forbidcrlf\n"
+"  # or pretxnchangegroup.cr = python:hgext.win32text.forbidcr\n"
+msgstr ""
+
+#, python-format
+msgid ""
+"WARNING: %s already has %s line endings\n"
+"and does not need EOL conversion by the win32text plugin.\n"
+"Before your next commit, please reconsider your encode/decode settings in \n"
+"Mercurial.ini or %s.\n"
+msgstr ""
+
+#, python-format
+msgid "Attempt to commit or push text file(s) using %s line endings\n"
+msgstr ""
+
+#, python-format
+msgid "in %s: %s\n"
+msgstr ""
+
+#, python-format
+msgid ""
+"\n"
+"To prevent this mistake in your local repository,\n"
+"add to Mercurial.ini or .hg/hgrc:"
+msgstr ""
+
+#, python-format
+msgid ""
+"[hooks]\n"
+"pretxncommit.%s = python:hgext.win32text.forbid%s"
+msgstr ""
+
+#, python-format
+msgid "and also consider adding:"
+msgstr ""
+
+#, python-format
+msgid ""
+"[extensions]\n"
+"win32text =\n"
+"[encode]\n"
+"** = %sencode:\n"
+"[decode]\n"
+"** = %sdecode:\n"
+msgstr ""
+
+msgid ""
+"win32text is deprecated: http://mercurial.selenic.com/wiki/"
+"Win32TextExtension\n"
+msgstr ""
+
+msgid "discover and advertise repositories on the local network"
+msgstr ""
+
+msgid ""
+"Zeroconf-enabled repositories will be announced in a network without\n"
+"the need to configure a server or a service. They can be discovered\n"
+"without knowing their actual IP address."
+msgstr ""
+
+msgid ""
+"To allow other people to discover your repository using run\n"
+":hg:`serve` in your repository::"
+msgstr ""
+
+msgid ""
+"  $ cd test\n"
+"  $ hg serve"
+msgstr ""
+
+msgid ""
+"You can discover Zeroconf-enabled repositories by running\n"
+":hg:`paths`::"
+msgstr ""
+
+msgid ""
+"  $ hg paths\n"
+"  zc-test = http://example.com:8000/test\n"
+msgstr ""
+
+msgid "archive prefix contains illegal components"
+msgstr ""
+
+msgid "cannot give prefix when archiving to files"
+msgstr ""
+
+#, python-format
+msgid "unknown archive type '%s'"
+msgstr ""
+
+msgid "archiving"
+msgstr ""
+
+#, python-format
+msgid "bookmark '%s' contains illegal character"
+msgstr ""
+
+#, python-format
+msgid "branch %s not found"
+msgstr ""
+
+#, python-format
+msgid "updating bookmark %s\n"
+msgstr ""
+
+#, python-format
+msgid "not updating divergent bookmark %s\n"
+msgstr ""
+
+msgid "searching for changed bookmarks\n"
+msgstr ""
+
+msgid "no changed bookmarks found\n"
+msgstr ""
+
+msgid "unknown parent"
+msgstr ""
+
+#, python-format
+msgid "integrity check failed on %s:%d"
+msgstr ""
+
+msgid "cannot create new bundle repository"
+msgstr ""
+
+#, python-format
+msgid "stream ended unexpectedly (got %d bytes, expected %d)"
+msgstr ""
+
+#, python-format
+msgid "invalid chunk length %d"
+msgstr ""
+
+#, python-format
+msgid "%s: not a Mercurial bundle"
+msgstr ""
+
+#, python-format
+msgid "%s: unknown bundle version %s"
+msgstr ""
+
+msgid "empty username"
+msgstr ""
+
+#, python-format
+msgid "username %s contains a newline"
+msgstr ""
+
+#, python-format
+msgid "the name '%s' is reserved"
+msgstr ""
+
+msgid "options --message and --logfile are mutually exclusive"
+msgstr ""
+
+#, python-format
+msgid "can't read commit message '%s': %s"
+msgstr ""
+
+msgid "limit must be a positive integer"
+msgstr ""
+
+msgid "limit must be positive"
+msgstr ""
+
+#, python-format
+msgid "invalid format spec '%%%s' in output filename"
+msgstr ""
+
+msgid "cannot specify --changelog and --manifest at the same time"
+msgstr ""
+
+msgid "cannot specify filename with --changelog or --manifest"
+msgstr ""
+
+msgid "cannot specify --changelog or --manifest without a repository"
+msgstr ""
+
+msgid "invalid arguments"
+msgstr "неверные параметры"
+
+#, fuzzy, python-format
+msgid "revlog '%s' not found"
+msgstr "репозиторий %s не найден"
+
+#, python-format
+msgid "%s: not copying - file is not managed\n"
+msgstr ""
+
+#, python-format
+msgid "%s: not copying - file has been marked for remove\n"
+msgstr ""
+
+#, python-format
+msgid "%s: not overwriting - %s collides with %s\n"
+msgstr ""
+
+#, python-format
+msgid "%s: not overwriting - file exists\n"
+msgstr ""
+
+#, python-format
+msgid "%s: not recording move - %s does not exist\n"
+msgstr ""
+
+#, python-format
+msgid "%s: not recording copy - %s does not exist\n"
+msgstr ""
+
+#, python-format
+msgid "%s: deleted in working copy\n"
+msgstr ""
+
+#, python-format
+msgid "%s: cannot copy - %s\n"
+msgstr ""
+
+#, python-format
+msgid "moving %s to %s\n"
+msgstr ""
+
+#, python-format
+msgid "copying %s to %s\n"
+msgstr ""
+
+msgid "no source or destination specified"
+msgstr ""
+
+msgid "no destination specified"
+msgstr ""
+
+msgid "with multiple sources, destination must be an existing directory"
+msgstr ""
+
+#, python-format
+msgid "destination %s is not a directory"
+msgstr ""
+
+msgid "no files to copy"
+msgstr ""
+
+msgid "(consider using --after)\n"
+msgstr ""
+
+msgid "child process failed to start"
+msgstr ""
+
+#, python-format
+msgid "changeset:   %d:%s\n"
+msgstr ""
+
+#, python-format
+msgid "branch:      %s\n"
+msgstr ""
+
+#, python-format
+msgid "bookmark:    %s\n"
+msgstr ""
+
+#, python-format
+msgid "tag:         %s\n"
+msgstr ""
+
+#, python-format
+msgid "parent:      %d:%s\n"
+msgstr ""
+
+#, python-format
+msgid "manifest:    %d:%s\n"
+msgstr ""
+
+#, python-format
+msgid "user:        %s\n"
+msgstr ""
+
+#, python-format
+msgid "date:        %s\n"
+msgstr ""
+
+msgid "files+:"
+msgstr ""
+
+msgid "files-:"
+msgstr ""
+
+msgid "files:"
+msgstr ""
+
+#, python-format
+msgid "files:       %s\n"
+msgstr ""
+
+#, python-format
+msgid "copies:      %s\n"
+msgstr ""
+
+#, python-format
+msgid "extra:       %s=%s\n"
+msgstr ""
+
+msgid "description:\n"
+msgstr ""
+
+#, python-format
+msgid "summary:     %s\n"
+msgstr ""
+
+#, python-format
+msgid "%s: no key named '%s'"
+msgstr ""
+
+#, python-format
+msgid "Found revision %s from %s\n"
+msgstr ""
+
+msgid "revision matching date not found"
+msgstr ""
+
+#, python-format
+msgid "cannot follow nonexistent file: \"%s\""
+msgstr ""
+
+msgid "can only follow copies/renames for explicit filenames"
+msgstr ""
+
+#, python-format
+msgid "adding %s\n"
+msgstr ""
+
+#, python-format
+msgid "skipping missing subrepository: %s\n"
+msgstr ""
+
+msgid "HG: Enter commit message.  Lines beginning with 'HG:' are removed."
+msgstr ""
+
+msgid "HG: Leave message empty to abort commit."
+msgstr ""
+
+#, python-format
+msgid "HG: user: %s"
+msgstr ""
+
+msgid "HG: branch merge"
+msgstr ""
+
+#, python-format
+msgid "HG: branch '%s'"
+msgstr ""
+
+#, python-format
+msgid "HG: subrepo %s"
+msgstr ""
+
+#, python-format
+msgid "HG: added %s"
+msgstr ""
+
+#, python-format
+msgid "HG: changed %s"
+msgstr ""
+
+#, python-format
+msgid "HG: removed %s"
+msgstr ""
+
+msgid "HG: no files changed"
+msgstr ""
+
+msgid "empty commit message"
+msgstr ""
+
+msgid "repository root directory or name of overlay bundle file"
+msgstr "корневой каталог репозитория или файл бандла"
+
+msgid "DIR"
+msgstr "ДИР"
+
+msgid "change working directory"
+msgstr "сменить рабочий каталог"
+
+msgid "do not prompt, assume 'yes' for any required answers"
+msgstr "не спрашивать подтверждания, всегда автоматически отвечать 'да'"
+
+msgid "suppress output"
+msgstr "подавлять вывод"
+
+msgid "enable additional output"
+msgstr "включить дополнительный вывод"
+
+msgid "set/override config option (use 'section.name=value')"
+msgstr ""
+"задать/переопределить параметр конфига (в виде 'секция.параметр=значение')"
+
+msgid "CONFIG"
+msgstr "КОНФИГ"
+
+msgid "enable debugging output"
+msgstr "включить отладочный вывод"
+
+msgid "start debugger"
+msgstr "запустить отладчик"
+
+msgid "set the charset encoding"
+msgstr "установить кодировку"
+
+msgid "ENCODE"
+msgstr "КОДИРОВКА"
+
+msgid "MODE"
+msgstr "РЕЖИМ"
+
+msgid "set the charset encoding mode"
+msgstr "установить режим кодировки"
+
+msgid "always print a traceback on exception"
+msgstr "всегда печатать трассировку стека при исключении"
+
+msgid "time how long the command takes"
+msgstr "время выполнения команды"
+
+#, fuzzy
+msgid "print command execution profile"
+msgstr "профилировка выполнения команды"
+
+msgid "output version information and exit"
+msgstr "напечатать информацию о версии и выйти"
+
+msgid "display help and exit"
+msgstr "показать справку и выйти"
+
+msgid "do not perform actions, just print output"
+msgstr "ничего реально не делать, просто напечатать вывод"
+
+msgid "specify ssh command to use"
+msgstr "используемая команда для ssh"
+
+msgid "specify hg command to run on the remote side"
+msgstr "комадна Mercurial, которая будет запущена на удаленном компьютере"
+
+msgid "do not verify server certificate (ignoring web.cacerts config)"
+msgstr "не проверять сертификат сервера (игнорируя настройку web.cacerts)"
+
+msgid "PATTERN"
+msgstr "ШАБЛОН"
+
+msgid "include names matching the given patterns"
+msgstr "включить файлы, имена которых соответствуют данным шаблонам"
+
+msgid "exclude names matching the given patterns"
+msgstr "исключить файлы, имена которых соответствуют данным шаблонам"
+
+msgid "use text as commit message"
+msgstr "текст комментария к коммиту"
+
+msgid "read commit message from file"
+msgstr "читать журнальные сообщения из файла"
+
+msgid "record the specified date as commit date"
+msgstr "использовать эту дату в качестве даты коммита"
+
+msgid "record the specified user as committer"
+msgstr "использовать этого пользователя как автора коммита"
+
+msgid "STYLE"
+msgstr "СТИЛЬ"
+
+msgid "display using template map file"
+msgstr "отображать с использование файла-карты шаблонов"
+
+msgid "display with template"
+msgstr "отображать с помощью шаблона"
+
+msgid "do not show merges"
+msgstr "не показывать слияния"
+
+msgid "output diffstat-style summary of changes"
+msgstr "отображать сводку изменений в стиле diffstat"
+
+msgid "treat all files as text"
+msgstr "обрабатывать все файлы как текстовые"
+
+msgid "omit dates from diff headers"
+msgstr "опускать даты в заголовках diff'ов"
+
+msgid "show which function each change is in"
+msgstr "для каждого изменения показать, в какой оно сделано функции"
+
+msgid "produce a diff that undoes the changes"
+msgstr "сгенерировать патч, который отменяет изменения"
+
+msgid "ignore white space when comparing lines"
+msgstr "игнорировать пробельные символы при сравнении строк"
+
+msgid "ignore changes in the amount of white space"
+msgstr "игнорировать изменения в количестве пробельных символов"
+
+msgid "ignore changes whose lines are all blank"
+msgstr "игнорировать пустые строки"
+
+msgid "number of lines of context to show"
+msgstr "показываемое количество строк контекста"
+
+msgid "SIMILARITY"
+msgstr "ПОХОЖЕСТЬ"
+
+msgid "guess renamed files by similarity (0<=s<=100)"
+msgstr ""
+"считать файлы переименованными исходя из степени их похожести (от 0 до 100)"
+
+msgid "recurse into subrepositories"
+msgstr "рекурсивно обрабатывать субрепозитории"
+
+msgid "[OPTION]... [FILE]..."
+msgstr "[ПАРАМЕТР]... [ФАЙЛ]..."
+
+msgid "add the specified files on the next commit"
+msgstr "добавить указанный файл при следующем коммите"
+
+msgid ""
+"    Schedule files to be version controlled and added to the\n"
+"    repository."
+msgstr ""
+"    Планирует помещение файлов под контроль версий и\n"
+"    добавление их в репозиторий."
+
+msgid ""
+"    The files will be added to the repository at the next commit. To\n"
+"    undo an add before that, see :hg:`forget`."
+msgstr ""
+"    Файлы будут добавлены в репозиторий при следующем коммите. Чтобы\n"
+"    отменить добавление до коммита, см. :hg:`forget`."
+
+msgid "    If no names are given, add all files to the repository."
+msgstr "    Если имена файлов не заданы, в будут добавлены все файлы."
+
+msgid "    .. container:: verbose"
+msgstr ""
+
+msgid ""
+"       An example showing how new (unknown) files are added\n"
+"       automatically by :hg:`add`::"
+msgstr ""
+"       Пример, демонстрирующий автоматическое добавление новых\n"
+"       (неизвестных) файлов с помощью :hg:`add`::"
+
+msgid ""
+"         $ ls\n"
+"         foo.c\n"
+"         $ hg status\n"
+"         ? foo.c\n"
+"         $ hg add\n"
+"         adding foo.c\n"
+"         $ hg status\n"
+"         A foo.c"
+msgstr ""
+"         $ ls\n"
+"         foo.c\n"
+"         $ hg status\n"
+"         ? foo.c\n"
+"         $ hg add\n"
+"         adding foo.c\n"
+"         $ hg status\n"
+"         A foo.c"
+
+msgid ""
+"    Returns 0 if all files are successfully added.\n"
+"    "
+msgstr ""
+"    Возвращает 0, если все файлы были успешно добавлены.\n"
+"    "
+
+msgid "add all new files, delete all missing files"
+msgstr "добавить все новые, удалить все отсутвующие файлы"
+
+msgid ""
+"    Add all new files and remove all missing files from the\n"
+"    repository."
+msgstr ""
+"    Добавляет все новые и удаляет все отсутсвующие файлы из\n"
+"    репозитория."
+
+msgid ""
+"    New files are ignored if they match any of the patterns in\n"
+"    ``.hgignore``. As with add, these changes take effect at the next\n"
+"    commit."
+msgstr ""
+"    Новые файлы игнорируются, если они подходят под любой шаблон\n"
+"    в ``.hgignore``. Аналогично команде ``add``, изменения фиксируются\n"
+"    при следующем коммите."
+
+msgid ""
+"    Use the -s/--similarity option to detect renamed files. With a\n"
+"    parameter greater than 0, this compares every removed file with\n"
+"    every added file and records those similar enough as renames. This\n"
+"    option takes a percentage between 0 (disabled) and 100 (files must\n"
+"    be identical) as its parameter. Detecting renamed files this way\n"
+"    can be expensive. After using this option, :hg:`status -C` can be\n"
+"    used to check which files were identified as moved or renamed."
+msgstr ""
+"    Используйте параметр -s/--similarity чтобы найти переименованные\n"
+"    файлы. Если этот параметр больше 0, то производится сравнение\n"
+"    каждого удаленного файла с каждым добавленным, и если они достаточно\n"
+"    похожи, то это фиксируется как переименование. Этот параметр принимает\n"
+"    в качестве параметра \"процент похожести\" от 0 (отключено) до 100\n"
+"    (файлы дожны быть одинаковыми). Этот способ нахождения\n"
+"    переименованных файлов может оказать дорогим. После использования\n"
+"    этого параметра можно использовать :hg:`status -C` чтобы проверить,\n"
+"    какие файлы были идентифицированы как перемещенные или\n"
+"    переименованные."
+
+msgid "similarity must be a number"
+msgstr "параметр \"similarity\" должен быть числом"
+
+msgid "similarity must be between 0 and 100"
+msgstr "параметр similarity должен быть от 0 до 100"
+
+msgid "annotate the specified revision"
+msgstr "аннотировать указанную ревизию"
+
+msgid "follow copies/renames and list the filename (DEPRECATED)"
+msgstr "отслеживать копирования/переименования и писать имя файла (УСТАРЕЛО)"
+
+msgid "don't follow copies and renames"
+msgstr "не отслеживать копирования и перемещения"
+
+msgid "list the author (long with -v)"
+msgstr "писать имя автора (длинный формат с -v)"
+
+msgid "list the filename"
+msgstr "писать имя файла"
+
+msgid "list the date (short with -q)"
+msgstr "писать дату (короткий формат с -q"
+
+msgid "list the revision number (default)"
+msgstr "писать номер ревизии (по умолчанию)"
+
+msgid "list the changeset"
+msgstr "писать набор изменений"
+
+msgid "show line number at the first appearance"
+msgstr "указывать номер строки при первом появлении"
+
+msgid "[-r REV] [-f] [-a] [-u] [-d] [-n] [-c] [-l] FILE..."
+msgstr ""
+
+msgid "show changeset information by line for each file"
+msgstr "информация о наборе изменений построчно для каждого файла"
+
+msgid ""
+"    List changes in files, showing the revision id responsible for\n"
+"    each line"
+msgstr ""
+"    Для каждой строки файла показывает номер ревизии, из которой\n"
+"    эта строка взялась"
+
+msgid ""
+"    This command is useful for discovering when a change was made and\n"
+"    by whom."
+msgstr ""
+"    Эта комадна полезна для того чтобы узнать, когда и кем было внесено\n"
+"    изменение."
+
+msgid ""
+"    Without the -a/--text option, annotate will avoid processing files\n"
+"    it detects as binary. With -a, annotate will annotate the file\n"
+"    anyway, although the results will probably be neither useful\n"
+"    nor desirable."
+msgstr ""
+"    Без параметра -a/--test, annotate не будет обрабатывать файлы,\n"
+"    которые она считает бинарными. С параметром -a, бинарные файлы\n"
+"    также будут аннотированы, хотя как правило это нежелательно и\n"
+"    бесполезно."
+
+msgid "at least one filename or pattern is required"
+msgstr "требуется указать как минимум одно имя файла или шаблон"
+
+msgid "at least one of -n/-c is required for -l"
+msgstr "с -l требуется указать хотя бы одно из -n/-c"
+
+#, python-format
+msgid "%s: binary file\n"
+msgstr "%s: бинарный файл\n"
+
+msgid "do not pass files through decoders"
+msgstr "не обрабатывать файлы декодерами"
+
+msgid "directory prefix for files in archive"
+msgstr "префикс каталога для файлов в архиве"
+
+msgid "PREFIX"
+msgstr "ПРЕФИКС"
+
+msgid "revision to distribute"
+msgstr "ревизия для архивирования"
+
+msgid "type of distribution to create"
+msgstr "тип создаваемого архива"
+
+#, fuzzy
+msgid "[OPTION]... DEST"
+msgstr "[ПАРАМЕТР]... [-r] РЕВИЗИЯ"
+
+msgid "create an unversioned archive of a repository revision"
+msgstr "создать неверсионируемую архивную копию ревизии репозитория"
+
+msgid ""
+"    By default, the revision used is the parent of the working\n"
+"    directory; use -r/--rev to specify a different revision."
+msgstr ""
+"    По умолчанию используется ревизия, являющаяся родителем рабочего\n"
+"    каталога; используйте -r/--rev чтобы указать другую ревизию."
+
+msgid ""
+"    The archive type is automatically detected based on file\n"
+"    extension (or override using -t/--type)."
+msgstr ""
+"    Тип архива выбирается автоматически на основе расширения файла\n"
+"    (можно переопределить с помощью -t/--type)."
+
+msgid "    Valid types are:"
+msgstr "    Допустимые типы:"
+
+msgid ""
+"    :``files``: a directory full of files (default)\n"
+"    :``tar``:   tar archive, uncompressed\n"
+"    :``tbz2``:  tar archive, compressed using bzip2\n"
+"    :``tgz``:   tar archive, compressed using gzip\n"
+"    :``uzip``:  zip archive, uncompressed\n"
+"    :``zip``:   zip archive, compressed using deflate"
+msgstr ""
+"    :``files``: каталог с файлами (по умолчанию)\n"
+"    :``tar``:   tar-архив, без сжатия\n"
+"    :``tbz2``:  tar-архив, сжатый bzip2\n"
+"    :``tgz``:   tar-архив, сжатый gzip\n"
+"    :``uzip``:  zip-архив, без сжатия\n"
+"    :``zip``:   zip-архив, сжатый"
+
+msgid ""
+"    The exact name of the destination archive or directory is given\n"
+"    using a format string; see :hg:`help export` for details."
+msgstr ""
+"    Точное имя архива или каталога задается с помощью форматирующей\n"
+"    строки; см. :hg:`help export`."
+
+msgid ""
+"    Each member added to an archive file has a directory prefix\n"
+"    prepended. Use -p/--prefix to specify a format string for the\n"
+"    prefix. The default is the basename of the archive, with suffixes\n"
+"    removed."
+msgstr ""
+"    К каждому элементу архива добавляется префикс в виде имени\n"
+"    каталога. Префикс может быть задан в виде форматирующей строки\n"
+"    с помощью -p/--prefix. По умолчанию это имя архива с удаленным\n"
+"    расширением."
+
+msgid "no working directory: please specify a revision"
+msgstr "нет рабочего каталога: пожалуйста, укажите ревизию"
+
+msgid "repository root cannot be destination"
+msgstr "корень репозитория не может быть назначением"
+
+msgid "cannot archive plain files to stdout"
+msgstr "не могу архивировать обычный каталог в stdout"
+
+#, fuzzy
+msgid "merge with old dirstate parent after backout"
+msgstr "слить со старым родителем после отмены"
+
+msgid "parent to choose when backing out merge"
+msgstr "выбираемая родительская ревизия при отмене слияния"
+
+msgid "revision to backout"
+msgstr "ревизия для отмены"
+
+msgid "[OPTION]... [-r] REV"
+msgstr "[ПАРАМЕТР]... [-r] РЕВИЗИЯ"
+
+msgid "reverse effect of earlier changeset"
+msgstr "отменить эффект более раннего набора изменений"
+
+msgid ""
+"    Prepare a new changeset with the effect of REV undone in the\n"
+"    current working directory."
+msgstr ""
+"    Создает в текущем рабочем каталоге новый набор изменений, который\n"
+"    имеет эффект отмены изменений РЕВИЗИИ."
+
+msgid ""
+"    If REV is the parent of the working directory, then this new changeset\n"
+"    is committed automatically. Otherwise, hg needs to merge the\n"
+"    changes and the merged result is left uncommitted."
+msgstr ""
+"    Если РЕВИЗИЯ - родитель рабочего каталога, то созданный набор\n"
+"    изменений коммитится автоматически. В противном случае Mercurial\n"
+"    проводит слияние изменений, результат слияния остается\n"
+"    незакоммиченным."
+
+msgid ""
+"    By default, the pending changeset will have one parent,\n"
+"    maintaining a linear history. With --merge, the pending changeset\n"
+"    will instead have two parents: the old parent of the working\n"
+"    directory and a new child of REV that simply undoes REV."
+msgstr ""
+"    По умолчанию, созданный набор изменений будет иметь одного\n"
+"    родителя, что сохраняет линейую история. Если указан --merge,\n"
+"    он будет иметь двух родителей: предыдущего родителя рабочего\n"
+"    каталога и новую дочернюю ревизию РЕВИЗИИ, которая просто\n"
+"    отменяет ее действие."
+
+msgid ""
+"    Before version 1.7, the behavior without --merge was equivalent to\n"
+"    specifying --merge followed by :hg:`update --clean .` to cancel\n"
+"    the merge and leave the child of REV as a head to be merged\n"
+"    separately."
+msgstr ""
+"    До версии 1.7 поведение без --merge было эквивалентно поведению\n"
+"    с --merge с последующим :hg:`update --clean .` с целью отменить\n"
+"    слияние и оставить дочернюю ревизию РЕВИЗИИ как голову для\n"
+"    для дальнейшего слияния"
+
+msgid "please specify just one revision"
+msgstr "пожалуйста, укажите ровно одну ревизию"
+
+msgid "please specify a revision to backout"
+msgstr "пожалуйста, укажите ревизию для отмены"
+
+msgid "cannot backout change on a different branch"
+msgstr "не могу отменить ревизию на другой ветке"
+
+msgid "cannot backout a change with no parents"
+msgstr "не могу отменить ревизию без родителей"
+
+msgid "cannot backout a merge changeset without --parent"
+msgstr "немогу отменить ревизию слияния без --parent"
+
+#, python-format
+msgid "%s is not a parent of %s"
+msgstr "%s не родитель %s"
+
+msgid "cannot use --parent on non-merge changeset"
+msgstr ""
+"нельзя использовать --parent для ревизии, не являющейся результатом слияния"
+
+#, python-format
+msgid "changeset %s backs out changeset %s\n"
+msgstr "ревизия %s отменяет ревизию %s\n"
+
+#, python-format
+msgid "merging with changeset %s\n"
+msgstr "слияние с ревизией %s\n"
+
+msgid "reset bisect state"
+msgstr "сбросить поиск"
+
+msgid "mark changeset good"
+msgstr "пометить ревизию как хорошую"
+
+msgid "mark changeset bad"
+msgstr "пометить ревизию как плохую"
+
+msgid "skip testing changeset"
+msgstr "пропустить тестирование набора изменений"
+
+msgid "extend the bisect range"
+msgstr "расширить диапазон поиска"
+
+msgid "use command to check changeset state"
+msgstr "использовать команду для проверки состояния набора изменений"
+
+msgid "do not update to target"
+msgstr "не обновляться до целевой ревизии"
+
+msgid "[-gbsr] [-U] [-c CMD] [REV]"
+msgstr "[-gbsr] [-U] [-c КОМАНДА] [РЕВИЗИЯ]"
+
+msgid "subdivision search of changesets"
+msgstr "поиск ревизии методом деления пополам"
+
+msgid ""
+"    This command helps to find changesets which introduce problems. To\n"
+"    use, mark the earliest changeset you know exhibits the problem as\n"
+"    bad, then mark the latest changeset which is free from the problem\n"
+"    as good. Bisect will update your working directory to a revision\n"
+"    for testing (unless the -U/--noupdate option is specified). Once\n"
+"    you have performed tests, mark the working directory as good or\n"
+"    bad, and bisect will either update to another candidate changeset\n"
+"    or announce that it has found the bad revision."
+msgstr ""
+"    Эта команда полезна при поиске ревизии, в которой была внесена\n"
+"    ошибка. Для этого самая ранняя ревизия, про которую известно, что\n"
+"    она содержит ошибку, помечается как плохая, после чего самая\n"
+"    поздняя ревизия, не содержащая эту ошибку, помечается как хорошая.\n"
+"    Bisect обновит рабочий каталог до ревизии для тестирования (если\n"
+"    не указан -U/--update). После того, как тесты проведены, ревизия\n"
+"    помечается как хорошая или плохая в зависимости от результата, и\n"
+"    bisect либо обновит каталог до новой ревизии-кандидата, либо\n"
+"    объявит, что нашел плохую ревизию."
+
+msgid ""
+"    As a shortcut, you can also use the revision argument to mark a\n"
+"    revision as good or bad without checking it out first."
+msgstr ""
+"    Для краткости можно также использовать номер ревизии в качестве\n"
+"    параметра, чтобы пометить ревизию как плохую или хорошую, не\n"
+"    обновляя до нее предварительно рабочий каталог."
+
+msgid ""
+"    If you supply a command, it will be used for automatic bisection.\n"
+"    Its exit status will be used to mark revisions as good or bad:\n"
+"    status 0 means good, 125 means to skip the revision, 127\n"
+"    (command not found) will abort the bisection, and any other\n"
+"    non-zero exit status means the revision is bad."
+msgstr ""
+"    Если вы укажите команду, она будет использована для автоматического\n"
+"    поиска. Ее код возврата будет использован чтобы пометить ревизию\n"
+"    как плохую или хорошую: код 0 - хорошая, код 125 означает пропустить\n"
+"    ревизию, 127 (команда не найдена) отменяет поиск, любой другой\n"
+"    код возврата означает плохую ревизию."
+
+msgid "The first good revision is:\n"
+msgstr "Первая хорошая ревизия:\n"
+
+msgid "The first bad revision is:\n"
+msgstr "Первая плохая ревизия:\n"
+
+#, python-format
+msgid ""
+"Not all ancestors of this changeset have been checked.\n"
+"Use bisect --extend to continue the bisection from\n"
+"the common ancestor, %s.\n"
+msgstr ""
+"Не все предки этого набора изменений были проверены.\n"
+"Используйте bisect --extend чтобы продолжить поиск\n"
+"от общей родительской ревизии %s.\n"
+
+msgid "Due to skipped revisions, the first good revision could be any of:\n"
+msgstr "Из-за пропущенных ревизий, первой хорошей может быть любая из:\n"
+
+msgid "Due to skipped revisions, the first bad revision could be any of:\n"
+msgstr "Из-за пропущенных ревизий, первой плохой может быть любая из:\n"
+
+msgid "cannot bisect (no known good revisions)"
+msgstr "не могу поделить пополам (нет известных хороших ревизий)"
+
+msgid "cannot bisect (no known bad revisions)"
+msgstr "не могу поделить пополам (нет известных плохих ревизий)"
+
+msgid "(use of 'hg bisect <cmd>' is deprecated)\n"
+msgstr "(использование 'hg bisect <cmd>' устарело)\n"
+
+msgid "incompatible arguments"
+msgstr "несовместимые аргументы"
+
+#, python-format
+msgid "failed to execute %s"
+msgstr "не удалось выполнить %s"
+
+#, python-format
+msgid "%s killed"
+msgstr "%s завершен (killed)"
+
+#, python-format
+msgid "Changeset %d:%s: %s\n"
+msgstr "Набор изменений %d:%s: %s\n"
+
+#, python-format
+msgid "Extending search to changeset %d:%s\n"
+msgstr "Расширяем поиск до ревизии %d:%s\n"
+
+msgid "nothing to extend"
+msgstr "некуда расширять поиск"
+
+#, python-format
+msgid "Testing changeset %d:%s (%d changesets remaining, ~%d tests)\n"
+msgstr "Тестирование ревизии %d:%s (%d ревизий осталось, ~%d тестов)\n"
+
+msgid "force"
+msgstr "принудительно"
+
+msgid "delete a given bookmark"
+msgstr "удалить указанную закладку"
+
+msgid "rename a given bookmark"
+msgstr "переимновать указанную закладку"
+
+msgid "do not mark a new bookmark active"
+msgstr "не помечать новую закладку как активную"
+
+msgid "hg bookmarks [-f] [-d] [-i] [-m NAME] [-r REV] [NAME]"
+msgstr "hg bookmarks [-f] [-d] [-i] [-m ИМЯ] [-r РЕВИЗИЯ] [ИМЯ]"
+
+msgid "track a line of development with movable markers"
+msgstr "отслеживать ветвь разработки с помощью передвигаемых меток"
+
+msgid ""
+"    Bookmarks are pointers to certain commits that move when\n"
+"    committing. Bookmarks are local. They can be renamed, copied and\n"
+"    deleted. It is possible to use bookmark names in :hg:`merge` and\n"
+"    :hg:`update` to merge and update respectively to a given bookmark."
+msgstr ""
+"    Закладки (bookmarks) - это указатели на некторый коммит, которые\n"
+"    перемещаются при коммите. Закладки локальны. Их можно переименовывать\n"
+"    копировать и удалять. Можно использовать имя закладки в :hg:`merge`\n"
+"    и :hg:`update` для слияния или обновления до заданной закладки\n"
+"    соответвенно."
+
+msgid ""
+"    You can use :hg:`bookmark NAME` to set a bookmark on the working\n"
+"    directory's parent revision with the given name. If you specify\n"
+"    a revision using -r REV (where REV may be an existing bookmark),\n"
+"    the bookmark is assigned to that revision."
+msgstr ""
+"    Используйте :hg:`bookmark ИМЯ` чтобы создать закладку с заданным\n"
+"    именем на родительскую ревизию рабочего каталога. Если указывается\n"
+"    -r РЕВИЗИЯ (где РЕВИЗИЯ может также быть существующей закладкой),\n"
+"    закладка будет указывать на эту ревизию."
+
+msgid ""
+"    Bookmarks can be pushed and pulled between repositories (see :hg:`help\n"
+"    push` and :hg:`help pull`). This requires both the local and remote\n"
+"    repositories to support bookmarks. For versions prior to 1.8, this "
+"means\n"
+"    the bookmarks extension must be enabled.\n"
+"    "
+msgstr ""
+"    Закладки могут передаваться между репозиториями с помощью команд\n"
+"    push и pull (см. :hg:`help push` и :hg:`help pull). Для этого\n"
+"    необходимо, чтобы удаленный и локальный репозиторий поддерживали\n"
+"    закладки. Для Mercurial версий меньше 1.8 это означает, что\n"
+"    должно быть включено расширение bookmarks.\n"
+"    "
+
+#, python-format
+msgid "bookmark '%s' does not exist"
+msgstr "закладки '%s' не существует"
+
+#, python-format
+msgid "bookmark '%s' already exists (use -f to force)"
+msgstr "закладка '%s' уже существует (-f - принудительно) "
+
+msgid "new bookmark name required"
+msgstr "укажите новое имя закладки"
+
+msgid "bookmark name required"
+msgstr "укажите имя закладки"
+
+msgid "bookmark name cannot contain newlines"
+msgstr "имя закладки не может содержать символ перевода строки"
+
+msgid "bookmark names cannot consist entirely of whitespace"
+msgstr "имя закладки не может состоять из одних пробелов"
+
+msgid "a bookmark cannot have the name of an existing branch"
+msgstr "закладка не может назыаться так же, как существующая ветвь"
+
+msgid "no bookmarks set\n"
+msgstr "нет ни одной закладки\n"
+
+msgid "set branch name even if it shadows an existing branch"
+msgstr "использовать имя ветви, даже если оно скрывает уже существующую ветвь"
+
+msgid "reset branch name to parent branch name"
+msgstr "сбросить имя ветви в имя ветви родителя"
+
+msgid "[-fC] [NAME]"
+msgstr "[-fC] [ИМЯ]"
+
+msgid "set or show the current branch name"
+msgstr "задать или показать имя текущей ветви"
+
+msgid ""
+"    With no argument, show the current branch name. With one argument,\n"
+"    set the working directory branch name (the branch will not exist\n"
+"    in the repository until the next commit). Standard practice\n"
+"    recommends that primary development take place on the 'default'\n"
+"    branch."
+msgstr ""
+"    Без аргументов показывает имя текущей ветви. С одним аргументом\n"
+"    задает имя ветви для рабочего каталога (ветвь не будет создана\n"
+"    в репозитории до следующего коммита). Рекомендуется вести основную\n"
+"    разработку в ветви 'default'."
+
+msgid ""
+"    Unless -f/--force is specified, branch will not let you set a\n"
+"    branch name that already exists, even if it's inactive."
+msgstr ""
+"    Если не указан -f/--force, branch не даст вам задать имя\n"
+"    существующей ветви, даже если она не активна."
+
+msgid ""
+"    Use -C/--clean to reset the working directory branch to that of\n"
+"    the parent of the working directory, negating a previous branch\n"
+"    change."
+msgstr ""
+"    Используйте -C/--clean чтобы установить ветку рабочего каталога\n"
+"    такой же, как ветвь его родителя, отменяя предыдущую смену ветви."
+
+msgid ""
+"    Use the command :hg:`update` to switch to an existing branch. Use\n"
+"    :hg:`commit --close-branch` to mark this branch as closed."
+msgstr ""
+"    Используйте команду :hg:`update` чтобы переключиться на существующую\n"
+"    ветвь. Используйте :hg:`commit --close-branch` чтобы пометить эту\n"
+"    ветвь как закрытую."
+
+#, python-format
+msgid "reset working directory to branch %s\n"
+msgstr "рабочий каталог сброшен на ветвь %s\n"
+
+msgid "a branch of the same name already exists"
+msgstr "ветвь с таким именем уже существует"
+
+#. i18n: "it" refers to an existing branch
+msgid "use 'hg update' to switch to it"
+msgstr "используйте 'hg update' чтобы переключиться на нее"
+
+#, python-format
+msgid "marked working directory as branch %s\n"
+msgstr "рабочий каталог помечен как ветвь %s\n"
+
+msgid "show only branches that have unmerged heads"
+msgstr "показывать только ветви, на которых есть неслитые головы"
+
+msgid "show normal and closed branches"
+msgstr "показывать обычные и закрытые ветви"
+
+msgid "[-ac]"
+msgstr "[-ac]"
+
+msgid "list repository named branches"
+msgstr "перечислить именованные ветки в репозитории"
+
+msgid ""
+"    List the repository's named branches, indicating which ones are\n"
+"    inactive. If -c/--closed is specified, also list branches which have\n"
+"    been marked closed (see :hg:`commit --close-branch`)."
+msgstr ""
+"    Перечисляет именованные ветви в репозитории, выделяя активные.\n"
+"    Если указан -c/--close, печатает также ветви, помеченные как\n"
+"    закрытые (см. :hg:`commit --close-branch`)."
+
+msgid ""
+"    If -a/--active is specified, only show active branches. A branch\n"
+"    is considered active if it contains repository heads."
+msgstr ""
+"    Если укзан -a/--active, показывает только активные ветви. Ветвь\n"
+"    считается активной, если она содержит головные ревизии."
+
+msgid "    Use the command :hg:`update` to switch to an existing branch."
+msgstr ""
+"    Используйте :hg:`update` чтобы переключиться на существующую ветвь."
+
+msgid ""
+"    Returns 0.\n"
+"    "
+msgstr ""
+"    Возвращает 0.\n"
+"    "
+
+msgid " (closed)"
+msgstr " (закрыта)"
+
+msgid " (inactive)"
+msgstr " (неактивна)"
+
+msgid "run even when the destination is unrelated"
+msgstr "работать даже если репозиторий не связан с репозиторием назначения"
+
+msgid "a changeset intended to be added to the destination"
+msgstr "набор изменений для добавления в репозиторий назначения"
+
+msgid "a specific branch you would like to bundle"
+msgstr "ветвь для упаковки"
+
+msgid "a base changeset assumed to be available at the destination"
+msgstr ""
+"базовый набор изменений, который предполагается доступным в репозитории "
+"назначения"
+
+msgid "bundle all changesets in the repository"
+msgstr "упаковать все ревизии в репозитории"
+
+msgid "bundle compression type to use"
+msgstr "тип сжатия"
+
+msgid "[-f] [-t TYPE] [-a] [-r REV]... [--base REV]... FILE [DEST]"
+msgstr "[-f] [-t ТИП] [-a] [-r РЕВИЗИЯ]... [--base РЕВИЗИЯ]... ФАЙЛ [НАЗН]"
+
+msgid "create a changegroup file"
+msgstr "создать файл с группой наборов изменений"
+
+msgid ""
+"    Generate a compressed changegroup file collecting changesets not\n"
+"    known to be in another repository."
+msgstr ""
+"    Создает сжатый файл, содержащий группу наборов изменений, которые\n"
+"    отсутсвуют в другом репозитории."
+
+msgid ""
+"    If you omit the destination repository, then hg assumes the\n"
+"    destination will have all the nodes you specify with --base\n"
+"    parameters. To create a bundle containing all changesets, use\n"
+"    -a/--all (or --base null)."
+msgstr ""
+"    Если репозиторий назначения опущен, то Mercurial предполагает,\n"
+"    что там имеются все ревизии, до указанной в --base. Чтобы создать\n"
+"    файл, содержащий все наборы изменений, используйте -a/--all\n"
+"    (или --base null)."
+
+msgid ""
+"    You can change compression method with the -t/--type option.\n"
+"    The available compression methods are: none, bzip2, and\n"
+"    gzip (by default, bundles are compressed using bzip2)."
+msgstr ""
+"    Способ сжатия можно задать с помощью параметра -t/--type.\n"
+"    Доступные методы сжатия: без сжатия (none), bzip2, gzip\n"
+"    (по умолчанию используется bzip2)."
+
+msgid ""
+"    The bundle file can then be transferred using conventional means\n"
+"    and applied to another repository with the unbundle or pull\n"
+"    command. This is useful when direct push and pull are not\n"
+"    available or when exporting an entire repository is undesirable."
+msgstr ""
+"    Файл с группой изменений (bundle) может быть передан обычными\n"
+"    средствами, или применен в другом репозитории с помощью команд\n"
+"    unbundle или pull. Это полезно когда команды push и pull напрямую\n"
+"    недоступны или когда пулбликация всего репозитория нежелательна."
+
+msgid ""
+"    Applying bundles preserves all changeset contents including\n"
+"    permissions, copy/rename information, and revision history."
+msgstr ""
+"    Применение групп изменений сохраняет все аттрибуты наборов\n"
+"    изменений, включая права доступа, информацию о копировании/\n"
+"    переименовании и историю ревизий."
+
+msgid ""
+"    Returns 0 on success, 1 if no changes found.\n"
+"    "
+msgstr ""
+"    Возвращает 0 в случае успеха, 1 если изменения не найдены\n"
+"    "
+
+msgid "--base is incompatible with specifying a destination"
+msgstr "нельзя одновременно указывать --base и репозиторий назначения"
+
+msgid "unknown bundle type specified with --type"
+msgstr "неизвестный способ задан в --type"
+
+msgid "print output to file with formatted name"
+msgstr "печатать в файл с именем согласно ФОРМАТУ"
+
+msgid "print the given revision"
+msgstr "напечатать заданную ревизию"
+
+msgid "apply any matching decode filter"
+msgstr "декодировать любым подходящим фильтром"
+
+msgid "[OPTION]... FILE..."
+msgstr "[ПАРАМЕТР]... ФАЙЛ..."
+
+msgid "output the current or given revision of files"
+msgstr "напечатать текущую или заданную ревизию файлов"
+
+msgid ""
+"    Print the specified files as they were at the given revision. If\n"
+"    no revision is given, the parent of the working directory is used,\n"
+"    or tip if no revision is checked out."
+msgstr ""
+"    Печатает содержимое указанных файлов, каким оно бало на момент\n"
+"    указанной ревизии. Если невизия не указана, используется\n"
+"    родительская ревизия рабочего каталога или вершина (tip), если\n"
+"    работий каталог пуст."
+
+msgid ""
+"    Output may be to a file, in which case the name of the file is\n"
+"    given using a format string. The formatting rules are the same as\n"
+"    for the export command, with the following additions:"
+msgstr ""
+"    Можно печатать в файл, в этом случае его имя задается в виде\n"
+"    форматирущей строки. Формат строки такой же, как в команде export,\n"
+"    со следующими дополнениями:"
+
+msgid ""
+"    :``%s``: basename of file being printed\n"
+"    :``%d``: dirname of file being printed, or '.' if in repository root\n"
+"    :``%p``: root-relative path name of file being printed"
+msgstr ""
+"    :``%s``: базовое имя печатаемого файла\n"
+"    :``%d``: имя каталога печатаемого файла или '.', если файл в корне\n"
+"    :``%p``: путь к печатаемому файлу относительно корня репозитория"
+
+msgid "the clone will include an empty working copy (only a repository)"
+msgstr "клон будет включать пустой рабочий каталог (только репозиторий)"
+
+msgid "revision, tag or branch to check out"
+msgstr "ревизия, метка или ветвь на которую обновиться"
+
+msgid "include the specified changeset"
+msgstr "включить указанный набор изменений"
+
+msgid "clone only the specified branch"
+msgstr "клонировать только указанную ветвь"
+
+msgid "[OPTION]... SOURCE [DEST]"
+msgstr "[ПАРАМЕТР]... ИСТОЧНИК [НАЗН]"
+
+msgid "make a copy of an existing repository"
+msgstr "создать копию существующего репозитория"
+
+msgid "    Create a copy of an existing repository in a new directory."
+msgstr "    Создает копию существующего репозитория в новом каталоге."
+
+msgid ""
+"    If no destination directory name is specified, it defaults to the\n"
+"    basename of the source."
+msgstr ""
+"    Если директорий назначения не задан, используется имя базового\n"
+"    каталога источника."
+
+msgid ""
+"    The location of the source is added to the new repository's\n"
+"    ``.hg/hgrc`` file, as the default to be used for future pulls."
+msgstr ""
+"    Адрес источника добавляется в файл ``.hg/hgrc`` нового репозитория,\n"
+"    и используется по умолчанию для последующих pull'ов и push'ей."
+
+msgid "    See :hg:`help urls` for valid source format details."
+msgstr "    См. :hg:`help urls` о форматах адреса источника."
+
+msgid ""
+"    It is possible to specify an ``ssh://`` URL as the destination, but no\n"
+"    ``.hg/hgrc`` and working directory will be created on the remote side.\n"
+"    Please see :hg:`help urls` for important details about ``ssh://`` URLs."
+msgstr ""
+"    Можно указать ``ssh://...`` в качестве адреса назначения, но файл\n"
+"    ``.hg/hgrc`` и рабочая копия не будут созданы на удаленном компьютере.\n"
+"    См. :hg:`help urls` для важной информации об адресах вида ``ssh://...``."
+
+msgid ""
+"    A set of changesets (tags, or branch names) to pull may be specified\n"
+"    by listing each changeset (tag, or branch name) with -r/--rev.\n"
+"    If -r/--rev is used, the cloned repository will contain only a subset\n"
+"    of the changesets of the source repository. Only the set of changesets\n"
+"    defined by all -r/--rev options (including all their ancestors)\n"
+"    will be pulled into the destination repository.\n"
+"    No subsequent changesets (including subsequent tags) will be present\n"
+"    in the destination."
+msgstr ""
+"    Копируемые наборы изменений (changesets) (как метки или имена ветвей)\n"
+"    могут быть заданы указанием каждого набора изменений (метки или имени\n"
+"    ветви) с помощью -r/--rev. При использовании -r/--rev, клонированный\n"
+"    репозиторий будет содержать только подмножество наборов изменений\n"
+"    источника."
+
+msgid ""
+"    Using -r/--rev (or 'clone src#rev dest') implies --pull, even for\n"
+"    local source repositories."
+msgstr ""
+"    Использование -r/--rev (или 'clone источник#ревизия назн')\n"
+"    предполагает --pull, даже если источник локален."
+
+msgid ""
+"    For efficiency, hardlinks are used for cloning whenever the source\n"
+"    and destination are on the same filesystem (note this applies only\n"
+"    to the repository data, not to the working directory). Some\n"
+"    filesystems, such as AFS, implement hardlinking incorrectly, but\n"
+"    do not report errors. In these cases, use the --pull option to\n"
+"    avoid hardlinking."
+msgstr ""
+"    Для эффективности, при клонировании источника на одной файловой\n"
+"    системе с целевым репозиторием, используются жесткие ссылки (это\n"
+"    относится только к данным репозитория, не рабочему каталогу).\n"
+"    Некоторые файловые системы, например, AFS, некорректно реализуют\n"
+"    жесткие ссылки, но не сообщают об ошибках. В этом случае используйте\n"
+"    --pull чтобы избежать жестких ссылок."
+
+msgid ""
+"    In some cases, you can clone repositories and the working directory\n"
+"    using full hardlinks with ::"
+msgstr ""
+"    В некоторых случаях можно клонировать репозитории и рабочие\n"
+"    каталоги целиком жесткими ссылками ::"
+
+msgid "      $ cp -al REPO REPOCLONE"
+msgstr "      $ cp -al РЕПОЗИТОРИЙ КЛОН"
+
+msgid ""
+"    This is the fastest way to clone, but it is not always safe. The\n"
+"    operation is not atomic (making sure REPO is not modified during\n"
+"    the operation is up to you) and you have to make sure your editor\n"
+"    breaks hardlinks (Emacs and most Linux Kernel tools do so). Also,\n"
+"    this is not compatible with certain extensions that place their\n"
+"    metadata under the .hg directory, such as mq."
+msgstr ""
+"    Это самый быстрый способ клонирования, но он не всегда безопасен.\n"
+"    Эта операция не атомарна (вам надо следить за тем, что РЕПОЗИТОРИЙ\n"
+"    не изменяется в процессе копирования), и вам надо убедиться, что\n"
+"    ваш редактор умеет разрывать жесткие ссылки (Emacs и большинство\n"
+"    инструментов разработчика ядра Linux умеют). Этот способ также\n"
+"    не совместим с некоторыми расширениями, которые хранят свои\n"
+"    метаданные в каталоге .hg, как mq."
+
+msgid ""
+"    Mercurial will update the working directory to the first applicable\n"
+"    revision from this list:"
+msgstr ""
+"    Mercurial обновит рабочий каталог до первой подходящей ревизии по\n"
+"    списку:"
+
+msgid ""
+"    a) null if -U or the source repository has no changesets\n"
+"    b) if -u . and the source repository is local, the first parent of\n"
+"       the source repository's working directory\n"
+"    c) the changeset specified with -u (if a branch name, this means the\n"
+"       latest head of that branch)\n"
+"    d) the changeset specified with -r\n"
+"    e) the tipmost head specified with -b\n"
+"    f) the tipmost head specified with the url#branch source syntax\n"
+"    g) the tipmost head of the default branch\n"
+"    h) tip"
+msgstr ""
+"    а) пустой каталог, если в источнике нет наборов изменений или указан -U\n"
+"    б) если указан -u . и источник локален, до первого родителя рабочей "
+"копии\n"
+"       источника\n"
+"    в) ревизия, указанная в -u (если это имя ветви, то до головной ревизии\n"
+"       этой ветви)\n"
+"    г) до ревизии, укзанной с помощью -r\n"
+"    д) до последней ревизии указанной в -b\n"
+"    е) до последней ревизии указанной как url#ветвь\n"
+"    ж) до последней ревизии ветви default\n"
+"    з) до последней ревизии"
+
+msgid "cannot specify both --noupdate and --updaterev"
+msgstr "нельзя указывать --noupdate и --updaterev одновременно"
+
+msgid "mark new/missing files as added/removed before committing"
+msgstr ""
+"пометить новые/недостающие файлы как добавленные/удаленные перед коммитом"
+
+msgid "mark a branch as closed, hiding it from the branch list"
+msgstr "пометить ветвь как закрытую, скрыть ее из списка ветвей"
+
+msgid "commit the specified files or all outstanding changes"
+msgstr "зафиксировать указанные файлы или все изменения в репозитории"
+
+msgid ""
+"    Commit changes to the given files into the repository. Unlike a\n"
+"    centralized SCM, this operation is a local operation. See\n"
+"    :hg:`push` for a way to actively distribute your changes."
+msgstr ""
+"    Зафиксировать (закоммитить) указанные файлы в репозитории. В\n"
+"    отличие от централизованных SCM, это локальная операция. См.\n"
+"    :hg:`push` чтобы узнать, как опубликовать свои изменения."
+
+msgid ""
+"    If a list of files is omitted, all changes reported by :hg:`status`\n"
+"    will be committed."
+msgstr ""
+"    Если список файлов опущен, будут закоммичены все изменения, которые\n"
+"    показывает :hg:`status`."
+
+msgid ""
+"    If you are committing the result of a merge, do not provide any\n"
+"    filenames or -I/-X filters."
+msgstr ""
+"    Если вы коммитите результат слияния, не указывайте никаких\n"
+"    файлов или фильтров в -I/-X."
+
+msgid ""
+"    If no commit message is specified, Mercurial starts your\n"
+"    configured editor where you can enter a message. In case your\n"
+"    commit fails, you will find a backup of your message in\n"
+"    ``.hg/last-message.txt``."
+msgstr ""
+"    Если не указан комментарий к коммиту, Mercurial запустит ваш\n"
+"    настроенный редактор, где можно ввести комментарий. Если при\n"
+"    коммите случается сбой, копию сообщения можно найти в \n"
+"    ``.hg/last-message.txt``."
+
+msgid ""
+"    Returns 0 on success, 1 if nothing changed.\n"
+"    "
+msgstr ""
+"    Возвращает 0 при успехе, 1 если изменения не зафиксированы.\n"
+"    "
+
+msgid "can only close branch heads"
+msgstr "можно закрыть только головную ревизию ветви"
+
+#, python-format
+msgid "nothing changed (%d missing files, see 'hg status')\n"
+msgstr "нет изменений (%d файлов отсутсвует, см. 'hg status')\n"
+
+msgid "nothing changed\n"
+msgstr "нет изменений\n"
+
+msgid "created new head\n"
+msgstr "создана новая голова\n"
+
+#, python-format
+msgid "reopening closed branch head %d\n"
+msgstr "повторно открываю головную ревизию %d закрытой ветви\n"
+
+#, python-format
+msgid "committed changeset %d:%s\n"
+msgstr "зафиксирован набор изменений %d:%s\n"
+
+msgid "record a copy that has already occurred"
+msgstr "записать копирование, которое было проведено ранее"
+
+msgid "forcibly copy over an existing managed file"
+msgstr "перезаписывать существующие контролируемые файлы"
+
+msgid "[OPTION]... [SOURCE]... DEST"
+msgstr "[ПАРАМЕТР]... [ИСТОЧНИК]... НАЗН"
+
+msgid "mark files as copied for the next commit"
+msgstr "пометить файл как скопированный при следующем коммите"
+
+msgid ""
+"    Mark dest as having copies of source files. If dest is a\n"
+"    directory, copies are put in that directory. If dest is a file,\n"
+"    the source must be a single file."
+msgstr ""
+"    Помечает НАЗН как копию источника. Если НАЗН - директория,\n"
+"    копии помещаются туда. Если НАЗН - файл, источник должен\n"
+"    быть одним файлом."
+
+msgid ""
+"    By default, this command copies the contents of files as they\n"
+"    exist in the working directory. If invoked with -A/--after, the\n"
+"    operation is recorded, but no copying is performed."
+msgstr ""
+"    По умолчанию эта команда копирует содержимое файлов в том виде,\n"
+"    как они существуют в рабочем каталоге. Если указан -A/--after,\n"
+"    операция регистрируется, но копирования не производится."
+
+msgid ""
+"    This command takes effect with the next commit. To undo a copy\n"
+"    before that, see :hg:`revert`."
+msgstr ""
+"    Эффект этой команды фиксируется при следующем коммите. Чтобы\n"
+"    отменить копирование, см. :hg:`revert`."
+
+msgid ""
+"    Returns 0 on success, 1 if errors are encountered.\n"
+"    "
+msgstr ""
+"    Возвращает 0 при успехе, 1 при ошибке.\n"
+"    "
+
+msgid "[INDEX] REV1 REV2"
+msgstr "[СПИСОК] РЕВИЗИЯ1 РЕВИЗИЯ2"
+
+msgid "find the ancestor revision of two revisions in a given index"
+msgstr "найти родительскую ревизию двух ревизий в указанном списке"
+
+msgid "either two or three arguments required"
+msgstr "требуются два или три аргумента"
+
+msgid "add single file mergeable changes"
+msgstr ""
+
+msgid "add single file all revs overwrite"
+msgstr ""
+
+msgid "add new file at each rev"
+msgstr ""
+
+msgid "[OPTION]... [TEXT]"
+msgstr "[ПАРАМЕТР]... [ТЕКСТ]..."
+
+msgid "builds a repo with a given DAG from scratch in the current empty repo"
+msgstr ""
+
+msgid ""
+"    The description of the DAG is read from stdin if not given on the\n"
+"    command line."
+msgstr ""
+
+msgid "    Elements:"
+msgstr ""
+
+msgid ""
+"     - \"+n\" is a linear run of n nodes based on the current default "
+"parent\n"
+"     - \".\" is a single node based on the current default parent\n"
+"     - \"$\" resets the default parent to null (implied at the start);\n"
+"           otherwise the default parent is always the last node created\n"
+"     - \"<p\" sets the default parent to the backref p\n"
+"     - \"*p\" is a fork at parent p, which is a backref\n"
+"     - \"*p1/p2\" is a merge of parents p1 and p2, which are backrefs\n"
+"     - \"/p2\" is a merge of the preceding node and p2\n"
+"     - \":tag\" defines a local tag for the preceding node\n"
+"     - \"@branch\" sets the named branch for subsequent nodes\n"
+"     - \"#...\\n\" is a comment up to the end of the line"
+msgstr ""
+
+msgid "    Whitespace between the above elements is ignored."
+msgstr ""
+
+msgid "    A backref is either"
+msgstr ""
+
+msgid ""
+"     - a number n, which references the node curr-n, where curr is the "
+"current\n"
+"       node, or\n"
+"     - the name of a local tag you placed earlier using \":tag\", or\n"
+"     - empty to denote the default parent."
+msgstr ""
+
+msgid ""
+"    All string valued-elements are either strictly alphanumeric, or must\n"
+"    be enclosed in double quotes (\"...\"), with \"\\\" as escape "
+"character.\n"
+"    "
+msgstr ""
+
+msgid "reading DAG from stdin\n"
+msgstr ""
+
+msgid "repository is not empty"
+msgstr ""
+
+msgid "building"
+msgstr ""
+
+msgid "show all details"
+msgstr ""
+
+msgid "lists the contents of a bundle"
+msgstr ""
+
+msgid "validate the correctness of the current dirstate"
+msgstr ""
+
+#, python-format
+msgid "%s in state %s, but not in manifest1\n"
+msgstr ""
+
+#, python-format
+msgid "%s in state %s, but also in manifest1\n"
+msgstr ""
+
+#, python-format
+msgid "%s in state %s, but not in either manifest\n"
+msgstr ""
+
+#, python-format
+msgid "%s in manifest1, but listed as state %s"
+msgstr ""
+
+msgid ".hg/dirstate inconsistent with current parent's manifest"
+msgstr ""
+
+msgid "[COMMAND]"
+msgstr ""
+
+msgid "list all available commands and options"
+msgstr ""
+
+msgid "show the command options"
+msgstr "показать параметры команды"
+
+msgid "[-o] CMD"
+msgstr "[-o] КОМАНДА"
+
+msgid "returns the completion list associated with the given command"
+msgstr ""
+
+msgid "use tags as labels"
+msgstr ""
+
+msgid "annotate with branch names"
+msgstr ""
+
+msgid "use dots for runs"
+msgstr ""
+
+msgid "separate elements by spaces"
+msgstr ""
+
+msgid "[OPTION]... [FILE [REV]...]"
+msgstr ""
+
+msgid "format the changelog or an index DAG as a concise textual description"
+msgstr ""
+
+msgid ""
+"    If you pass a revlog index, the revlog's DAG is emitted. If you list\n"
+"    revision numbers, they get labelled in the output as rN."
+msgstr ""
+
+msgid ""
+"    Otherwise, the changelog DAG of the current repo is emitted.\n"
+"    "
+msgstr ""
+
+msgid "need repo for changelog dag"
+msgstr ""
+
+#, fuzzy
+msgid "open changelog"
+msgstr "открыть журнал изменений"
+
+msgid "open manifest"
+msgstr ""
+
+msgid "-c|-m|FILE REV"
+msgstr ""
+
+msgid "dump the contents of a data file revision"
+msgstr ""
+
+#, python-format
+msgid "invalid revision identifier %s"
+msgstr ""
+
+msgid "try extended date formats"
+msgstr ""
+
+msgid "[-e] DATE [RANGE]"
+msgstr ""
+
+msgid "parse and display a date"
+msgstr ""
+
+msgid "use old-style discovery"
+msgstr ""
+
+msgid "use old-style discovery with non-heads included"
+msgstr ""
+
+msgid "[-l REV] [-r REV] [-b BRANCH]... [OTHER]"
+msgstr ""
+
+msgid "runs the changeset discovery protocol in isolation"
+msgstr ""
+
+msgid "[PATH]"
+msgstr ""
+
+msgid "show information detected about current filesystem"
+msgstr ""
+
+msgid "id of head node"
+msgstr ""
+
+msgid "id of common node"
+msgstr ""
+
+msgid "REPO FILE [-H|-C ID]..."
+msgstr ""
+
+msgid "retrieves a bundle from a repo"
+msgstr ""
+
+msgid ""
+"    Every ID must be a full-length hex node id string. Saves the bundle to "
+"the\n"
+"    given file.\n"
+"    "
+msgstr ""
+
+msgid "display the combined ignore pattern"
+msgstr ""
+
+msgid "no ignore patterns found"
+msgstr ""
+
+msgid "revlog format"
+msgstr ""
+
+msgid "[-f FORMAT] -c|-m|FILE"
+msgstr ""
+
+msgid "dump the contents of an index file"
+msgstr ""
+
+#, python-format
+msgid "unknown format %d"
+msgstr ""
+
+msgid "dump an index DAG as a graphviz dot file"
+msgstr ""
+
+msgid "test Mercurial installation"
+msgstr ""
+
+#, python-format
+msgid "Checking encoding (%s)...\n"
+msgstr ""
+
+msgid " (check that your locale is properly set)\n"
+msgstr ""
+
+#, python-format
+msgid "Checking installed modules (%s)...\n"
+msgstr ""
+
+msgid " One or more extensions could not be found"
+msgstr ""
+
+msgid " (check that you compiled the extensions)\n"
+msgstr ""
+
+msgid "Checking templates...\n"
+msgstr ""
+
+msgid " (templates seem to have been installed incorrectly)\n"
+msgstr ""
+
+msgid "Checking commit editor...\n"
+msgstr ""
+
+msgid " No commit editor set and can't find vi in PATH\n"
+msgstr ""
+
+msgid " (specify a commit editor in your configuration file)\n"
+msgstr ""
+
+#, python-format
+msgid " Can't find editor '%s' in PATH\n"
+msgstr ""
+
+msgid "Checking username...\n"
+msgstr ""
+
+msgid " (specify a username in your configuration file)\n"
+msgstr ""
+
+msgid "No problems detected\n"
+msgstr ""
+
+#, python-format
+msgid "%s problems detected, please check your install!\n"
+msgstr ""
+
+msgid "REPO ID..."
+msgstr ""
+
+msgid "test whether node ids are known to a repo"
+msgstr ""
+
+msgid ""
+"    Every ID must be a full-length hex node id string. Returns a list of 0s "
+"and 1s\n"
+"    indicating unknown/known.\n"
+"    "
+msgstr ""
+
+msgid "REPO NAMESPACE [KEY OLD NEW]"
+msgstr ""
+
+msgid "access the pushkey key/value protocol"
+msgstr ""
+
+msgid "    With two args, list the keys in the given namespace."
+msgstr ""
+
+msgid ""
+"    With five args, set a key to new if it currently is set to old.\n"
+"    Reports success or failure.\n"
+"    "
+msgstr ""
+
+msgid "revision to rebuild to"
+msgstr ""
+
+msgid "[-r REV] [REV]"
+msgstr ""
+
+msgid "rebuild the dirstate as it would look like for the given revision"
+msgstr ""
+
+msgid "revision to debug"
+msgstr ""
+
+msgid "[-r REV] FILE"
+msgstr ""
+
+msgid "dump rename information"
+msgstr ""
+
+#, python-format
+msgid "%s renamed from %s:%s\n"
+msgstr ""
+
+#, python-format
+msgid "%s not renamed\n"
+msgstr ""
+
+msgid "dump index data"
+msgstr ""
+
+msgid "-c|-m|FILE"
+msgstr ""
+
+msgid "show data and statistics about a revlog"
+msgstr ""
+
+msgid "parse and apply a revision specification"
+msgstr ""
+
+msgid "REV1 [REV2]"
+msgstr ""
+
+msgid "manually set the parents of the current working directory"
+msgstr ""
+
+msgid ""
+"    This is useful for writing repository conversion tools, but should\n"
+"    be used with care."
+msgstr ""
+
+msgid "do not display the saved mtime"
+msgstr ""
+
+msgid "sort by saved mtime"
+msgstr ""
+
+msgid "[OPTION]..."
+msgstr ""
+
+msgid "show the contents of the current dirstate"
+msgstr ""
+
+#, python-format
+msgid "copy: %s -> %s\n"
+msgstr ""
+
+msgid "revision to check"
+msgstr ""
+
+msgid "show how files match on given patterns"
+msgstr ""
+
+msgid "REPO [OPTIONS]... [ONE [TWO]]"
+msgstr ""
+
+msgid "[OPTION]... ([-c REV] | [-r REV1 [-r REV2]]) [FILE]..."
+msgstr "[ПАРАМЕТР]... ([-c РЕВ] | [-r РЕВ1 [-r РЕВ2]]) [ФАЙЛ]..."
+
+msgid "diff repository (or selected files)"
+msgstr "показать изменения в репозитории (или выбранных файлах)"
+
+msgid "    Show differences between revisions for the specified files."
+msgstr "    Показывает отличия между ревизиями указанных файлов."
+
+msgid "    Differences between files are shown using the unified diff format."
+msgstr "    Различия показываются в унифицировнном формате diff."
+
+msgid ""
+"    .. note::\n"
+"       diff may generate unexpected results for merges, as it will\n"
+"       default to comparing against the working directory's first\n"
+"       parent changeset if no revisions are specified."
+msgstr ""
+"    .. note::\n"
+"       diff может генерировать неожиданные результаты для слияний,\n"
+"       поскольку по умолчанию сравнивнение производится с первым\n"
+"       родителем рабочего каталога, если не указаны другие ревизии."
+
+msgid ""
+"    Alternatively you can specify -c/--change with a revision to see\n"
+"    the changes in that changeset relative to its first parent."
+msgstr ""
+"    Можно также указать -c/--change чтобы посмотреть изменения\n"
+"    в этой ревизии относительно ее первой родительской ревизии."
+
+msgid ""
+"    Without the -a/--text option, diff will avoid generating diffs of\n"
+"    files it detects as binary. With -a, diff will generate a diff\n"
+"    anyway, probably with undesirable results."
+msgstr ""
+"    Без -a/--text, diff не будет генерировать отличия для файлов,\n"
+"    которые посчитает бинарными. С -а, будет генерировать для всех\n"
+"    файлов, возможно с нежелательными результатами."
+
+msgid ""
+"    Use the -g/--git option to generate diffs in the git extended diff\n"
+"    format. For more information, read :hg:`help diffs`."
+msgstr ""
+"    Используйте -g/--git чтобы генерировать отличися в расширенном\n"
+"    формате git. Подробнее см. :hg:`help diffs`."
+
+msgid "diff against the second parent"
+msgstr "отличия от второй родительской ревизии"
+
+msgid "revisions to export"
+msgstr "ревизии для экспортирования"
+
+msgid "[OPTION]... [-o OUTFILESPEC] REV..."
+msgstr "[ПАРАМЕТР]... [-o OUTFILESPEC] РЕВИЗИЯ..."
+
+msgid "dump the header and diffs for one or more changesets"
+msgstr "сохранить заголовок и diff'ы для одной или нескольких ревизий"
+
+msgid "    Print the changeset header and diffs for one or more revisions."
+msgstr ""
+"    Печатает заголовок набора изменений и отличия для одной или\n"
+"    более ревизии."
+
+msgid ""
+"    The information shown in the changeset header is: author, date,\n"
+"    branch name (if non-default), changeset hash, parent(s) and commit\n"
+"    comment."
+msgstr ""
+"    В заголовке набора изменений содержится следующая информация:\n"
+"    автор, дата, имя ветви (если не default), хэш набора изменений,\n"
+"    родитель (родители) и комментарий к коммиту."
+
+msgid ""
+"    .. note::\n"
+"       export may generate unexpected diff output for merge\n"
+"       changesets, as it will compare the merge changeset against its\n"
+"       first parent only."
+msgstr ""
+"    .. note::\n"
+"       export может генерировать неожиданный вывод diff для ревизий\n"
+"       слияния, потому что сравнение такой ревизии проводится только\n"
+"       с ее первой родительской ревизией."
+
+msgid ""
+"    Output may be to a file, in which case the name of the file is\n"
+"    given using a format string. The formatting rules are as follows:"
+msgstr ""
+"    Можно осуществлять вывод в файл, при этом имя файла задается\n"
+"    в виде форматирующей строки. Правила форматирования:"
+
+msgid ""
+"    :``%%``: literal \"%\" character\n"
+"    :``%H``: changeset hash (40 hexadecimal digits)\n"
+"    :``%N``: number of patches being generated\n"
+"    :``%R``: changeset revision number\n"
+"    :``%b``: basename of the exporting repository\n"
+"    :``%h``: short-form changeset hash (12 hexadecimal digits)\n"
+"    :``%n``: zero-padded sequence number, starting at 1\n"
+"    :``%r``: zero-padded changeset revision number"
+msgstr ""
+"    :``%%``: символ \"%\"\n"
+"    :``%H``: хэш набора изменений (40 шестнадцатеричных цифр)\n"
+"    :``%N``: количество сгенерированных патчей\n"
+"    :``%R``: номер ревизии набора изменений\n"
+"    :``%b``: базовое имя экспортируемого репозитория\n"
+"    :``%h``: короткий хэш набора изменений (12 шестнадцатеричных цифр)\n"
+"    :``%n``: выровненный нулями последовательный номер, начиная с 1\n"
+"    :``%r``: выровненный нулями номер ревизии"
+
+msgid ""
+"    Without the -a/--text option, export will avoid generating diffs\n"
+"    of files it detects as binary. With -a, export will generate a\n"
+"    diff anyway, probably with undesirable results."
+msgstr ""
+"    Без -a/--text, export не будет генерировать diff'ы для файлов,\n"
+"    которые он считает бинарными. С -а diff'ы будут сгенерированы\n"
+"    для всех файлов, часто с нежелательными результатами."
+
+msgid ""
+"    Use the -g/--git option to generate diffs in the git extended diff\n"
+"    format. See :hg:`help diffs` for more information."
+msgstr ""
+"    Используйте -g/--git чтобы сгенерировать diff'ы в расширенном\n"
+"    формате git. Подробнее см. :hg:`help diffs`."
+
+msgid ""
+"    With the --switch-parent option, the diff will be against the\n"
+"    second parent. It can be useful to review a merge."
+msgstr ""
+"    Если указан --switch-parent, будут генерироваться отличия от\n"
+"    второго родителя. Это может быть полезно при анализе слияния."
+
+msgid "export requires at least one changeset"
+msgstr "для экспорта требуется хотя бы один набор изменений"
+
+msgid "exporting patches:\n"
+msgstr "экспортируемые патчи:\n"
+
+msgid "exporting patch:\n"
+msgstr "экспортируемый патч:\n"
+
+msgid "forget the specified files on the next commit"
+msgstr "забыть указанные файлы при следующем коммите"
+
+msgid ""
+"    Mark the specified files so they will no longer be tracked\n"
+"    after the next commit."
+msgstr ""
+"    Помечает указанные файлы, чтобы перестать их отслеживать\n"
+"    при следующем коммите."
+
+msgid ""
+"    This only removes files from the current branch, not from the\n"
+"    entire project history, and it does not delete them from the\n"
+"    working directory."
+msgstr ""
+"    Это удаляет файлы только из текущей ветви, а не из всего\n"
+"    репозитория, и не удаляет их из рабочего каталога."
+
+msgid "    To undo a forget before the next commit, see :hg:`add`."
+msgstr ""
+"    Чтобы отменить действие forget до следующего коммита\n"
+"    см. :hg:`add`."
+
+msgid "no files specified"
+msgstr "не задано ни одного файла"
+
+#, python-format
+msgid "not removing %s: file is already untracked\n"
+msgstr "%s не удален, он и так не отслеживается\n"
+
+#, python-format
+msgid "removing %s\n"
+msgstr "удаляю %s\n"
+
+msgid "end fields with NUL"
+msgstr "заканчивать поля символом NUL"
+
+msgid "print all revisions that match"
+msgstr "печатать все подходящие ревизии"
+
+msgid "follow changeset history, or file history across copies and renames"
+msgstr ""
+"следовать истории набора изменений или истории файла при копированиях/"
+"переименованиях"
+
+msgid "ignore case when matching"
+msgstr "игнорировать регистр букв"
+
+msgid "print only filenames and revisions that match"
+msgstr "печатать только имена совпадающих файлов и ревизий"
+
+msgid "print matching line numbers"
+msgstr "печатать номера строк"
+
+msgid "only search files changed within revision range"
+msgstr "искать только файлы, измененные в указанном диапазоне ревизий"
+
+msgid "[OPTION]... PATTERN [FILE]..."
+msgstr "[ПАРАМЕТР]... ШАБЛОН [ФАЙЛ]..."
+
+msgid "search for a pattern in specified files and revisions"
+msgstr "искать шаблон в указанных файлах и ревизиях"
+
+msgid "    Search revisions of files for a regular expression."
+msgstr "    Ищет регулярное выражение в указанных ревизиях файлов."
+
+msgid ""
+"    This command behaves differently than Unix grep. It only accepts\n"
+"    Python/Perl regexps. It searches repository history, not the\n"
+"    working directory. It always prints the revision number in which a\n"
+"    match appears."
+msgstr ""
+"    Команда ведет себя не так, как grep в Unix. Она принимает\n"
+"    регулярные выражения Python/Perl. Ищет в истории репозитория,\n"
+"    а не в рабочем каталоге. Она всегда печатает номер ревизии,\n"
+"    в ктором находит совпадение."
+
+msgid ""
+"    By default, grep only prints output for the first revision of a\n"
+"    file in which it finds a match. To get it to print every revision\n"
+"    that contains a change in match status (\"-\" for a match that\n"
+"    becomes a non-match, or \"+\" for a non-match that becomes a match),\n"
+"    use the --all flag."
+msgstr ""
+"    По умолчанию печатается только вывод для первой ревизии файла,\n"
+"    в которой найдено совпадение. Чтобы напечатать все ревизии, в которых\n"
+"    меняется статус совпадения (\"-\", если совпадение перестало\n"
+"    быть совпадением, или \"+\", если совпадение возникло там, где раньше\n"
+"    его не было), используйте флаг --all."
+
+msgid ""
+"    Returns 0 if a match is found, 1 otherwise.\n"
+"    "
+msgstr ""
+"    Возвращает 0, если совпадение найдено, 1 в противном случае.\n"
+"    "
+
+#, python-format
+msgid "grep: invalid match pattern: %s\n"
+msgstr "grep: наверный шаблон: %s\n"
+
+msgid "STARTREV"
+msgstr "НАЧРЕВИЗИЯ"
+
+msgid "show only heads which are descendants of STARTREV"
+msgstr "показать только головные ревизии-потомки НАЧРЕВИЗИИ"
+
+msgid "show topological heads only"
+msgstr "показать только топологические головные ревизии"
+
+msgid "show active branchheads only (DEPRECATED)"
+msgstr "показать только активные головы ветвей (УСТАРЕЛО)"
+
+msgid "show normal and closed branch heads"
+msgstr "показать обычные и закрытые головы ветвей"
+
+msgid "[-ac] [-r STARTREV] [REV]..."
+msgstr "[-ac] [-r НАЧРЕВИЗИЯ] [РЕВИЗИЯ]..."
+
+msgid "show current repository heads or show branch heads"
+msgstr "показать головы текущего репозитория или головы ветвей"
+
+msgid "    With no arguments, show all repository branch heads."
+msgstr "    Без аргуметов показывает все головы ветвей репозитория."
+
+msgid ""
+"    Repository \"heads\" are changesets with no child changesets. They are\n"
+"    where development generally takes place and are the usual targets\n"
+"    for update and merge operations. Branch heads are changesets that have\n"
+"    no child changeset on the same branch."
+msgstr ""
+"    \"Головы\" репозитория - это наборы изменений, у которых нет дочерних\n"
+"    наборов. Именно в них происходит разработка и они как правило являются\n"
+"    объектами для операций update или merge. Головы ветвей - это наборы\n"
+"    изменений, у которых нет дочерних наборов на той же ветви."
+
+msgid ""
+"    If one or more REVs are given, only branch heads on the branches\n"
+"    associated with the specified changesets are shown."
+msgstr ""
+"    Если указана одна или более РЕВИЗИЯ, показываются только головы\n"
+"    на ветвях, ассоциированных с указанными ревизиями."
+
+msgid ""
+"    If -c/--closed is specified, also show branch heads marked closed\n"
+"    (see :hg:`commit --close-branch`)."
+msgstr ""
+"    Если указан -c/--closed, показываются также головы на закрытых\n"
+"    ветвях (см. :hg:`commit --close-branch`)"
+
+msgid ""
+"    If STARTREV is specified, only those heads that are descendants of\n"
+"    STARTREV will be displayed."
+msgstr ""
+"    Если задана НАЧАЛЬНАЯРЕВИЗИЯ, показываются только головы,\n"
+"    являющиеся ее потомками."
+
+msgid ""
+"    If -t/--topo is specified, named branch mechanics will be ignored and "
+"only\n"
+"    changesets without children will be shown."
+msgstr ""
+"    Если указан -t/--topo, механизм именованных ветвей игнорируется,    и "
+"будут\n"
+"    показаны только наборы изменений без дочерних наборов."
+
+msgid ""
+"    Returns 0 if matching heads are found, 1 if not.\n"
+"    "
+msgstr ""
+"    Возвращает 0, если головы найдены, 1 в противном случае.\n"
+"    "
+
+#, python-format
+msgid "no open branch heads found on branches %s"
+msgstr "не найдено голов открытых ветвей на ветвях %s"
+
+#, python-format
+msgid " (started at %s)"
+msgstr " (начиная с %s)"
+
+msgid "show only help for extensions"
+msgstr "показать только справку по расширениям"
+
+msgid "show only help for commands"
+msgstr "показать справку для команд"
+
+msgid "[-ec] [TOPIC]"
+msgstr "[-ec] [ТЕМА]"
+
+msgid "show help for a given topic or a help overview"
+msgstr "показать справку по выбранной теме или обзор справочной информации"
+
+msgid ""
+"    With no arguments, print a list of commands with short help messages."
+msgstr "    Без аргументов печатает списко команд с кратким описанием."
+
+msgid ""
+"    Given a topic, extension, or command name, print help for that\n"
+"    topic."
+msgstr ""
+"    Если указана тема, расширение или имя команды, показывает справку\n"
+"    по этой теме."
+
+msgid ""
+"    Returns 0 if successful.\n"
+"    "
+msgstr ""
+"    Возвращает 0 при успешном выполнении.\n"
+"    "
+
+msgid "global options:"
+msgstr "глобальные параметры:"
+
+msgid "use \"hg help\" for the full list of commands"
+msgstr "используйте \"hg help\" чтобы посмотреть полный список команд"
+
+msgid "use \"hg help\" for the full list of commands or \"hg -v\" for details"
+msgstr ""
+"используйте \"hg help\" чтобы посмотреть полный список команд,\"hg -v\" для "
+"подробной информации"
+
+#, python-format
+msgid "use \"hg help %s\" to show the full help text"
+msgstr "используйте \"hg help %s\" чтобы получить полную справку"
+
+#, python-format
+msgid "use \"hg -v help%s\" to show builtin aliases and global options"
+msgstr ""
+"используйте \"hg -v help%s\" чтобы посмотреть встроенные псевдонимы и "
+"глобальные параметры"
+
+#, python-format
+msgid "use \"hg -v help %s\" to show global options"
+msgstr "используйте \"hg -v help %s\" для просмотра глобальных параметров"
+
+msgid "list of commands:"
+msgstr "список команд:"
+
+#, python-format
+msgid ""
+"\n"
+"aliases: %s\n"
+msgstr ""
+"\n"
+"псевдонимы: %s\n"
+
+msgid "(no help text available)"
+msgstr "(справка недоступна)"
+
+#, python-format
+msgid "shell alias for::"
+msgstr "псевдоним оболочки для::"
+
+#, python-format
+msgid "    %s"
+msgstr "    %s"
+
+#, python-format
+msgid "alias for: hg %s"
+msgstr "псевдоним для: hg %s"
+
+#, python-format
+msgid "%s"
+msgstr "%s"
+
+#, python-format
+msgid ""
+"\n"
+"use \"hg -v help %s\" to show verbose help\n"
+msgstr ""
+"\n"
+"используйте \"hg -v help %s\" чтобы посмотреть подробную справку\n"
+
+msgid "options:\n"
+msgstr "параметры:\n"
+
+#, python-format
+msgid "use \"hg help -e %s\" to show help for the %s extension"
+msgstr "используйте \"hg help -e %s\" для просмотра справки по расширению %s"
+
+msgid "no commands defined\n"
+msgstr "команды не определены\n"
+
+#, python-format
+msgid ""
+"\n"
+"use \"hg help -c %s\" to see help for the %s command\n"
+msgstr ""
+"\n"
+"используйте \"hg help -c %s\" для справки по команде %s\n"
+
+msgid "no help text available"
+msgstr "справка недоступна"
+
+#, python-format
+msgid "%s extension - %s"
+msgstr "%s расширение - %s"
+
+msgid "use \"hg help extensions\" for information on enabling extensions\n"
+msgstr "наберите \"hg help extensions\" для справки по включению расширений\n"
+
+#, python-format
+msgid "'%s' is provided by the following extension:"
+msgstr "'%s' предоставляется следующим расширением:"
+
+msgid "Mercurial Distributed SCM\n"
+msgstr "Распределенная SCM Mercurial\n"
+
+msgid "basic commands:"
+msgstr "Основные команды:"
+
+msgid "enabled extensions:"
+msgstr "Включенные расширения:"
+
+msgid "VALUE"
+msgstr "ЗНАЧЕНИЕ"
+
+msgid "DEPRECATED"
+msgstr "УСТАРЕЛО"
+
+msgid ""
+"\n"
+"[+] marked option can be specified multiple times"
+msgstr ""
+"\n"
+"параметры, помеченные [+], могут указываться многократно"
+
+msgid ""
+"\n"
+"additional help topics:"
+msgstr ""
+"\n"
+"дополнительные разделы справки:"
+
+msgid "identify the specified revision"
+msgstr "описать заданную ревизию"
+
+msgid "show local revision number"
+msgstr "показать локальный номер ревизии"
+
+msgid "show global revision id"
+msgstr "показать глобальный идентификатор ревизии"
+
+msgid "show branch"
+msgstr "показать ветку"
+
+msgid "show tags"
+msgstr "показать метки"
+
+msgid "show bookmarks"
+msgstr "показать закладка"
+
+msgid "[-nibtB] [-r REV] [SOURCE]"
+msgstr "[-nibtB] [-r РЕВИЗИЯ] [ИСТОЧНИК]"
+
+msgid "identify the working copy or specified revision"
+msgstr "описать рабочую копию или указанную ревизию"
+
+msgid ""
+"    Print a summary identifying the repository state at REV using one or\n"
+"    two parent hash identifiers, followed by a \"+\" if the working\n"
+"    directory has uncommitted changes, the branch name (if not default),\n"
+"    a list of tags, and a list of bookmarks."
+msgstr ""
+"    Печатает сводку, описывающую состояние репозитория на момент РЕВИЗИЯ,\n"
+"    в виде одного или двух хеш-идентификаторов родителя, за которым\n"
+"    следует \"+\", если рабочая копия содержит незакоммиченные\n"
+"    изменения, имени ветви (если отлично от default), списка ветвей,\n"
+"    списка меток и списка закладок."
+
+msgid ""
+"    When REV is not given, print a summary of the current state of the\n"
+"    repository."
+msgstr ""
+"    Если РЕВИЗИЯ не указан, печатает сводку по текущему состоянию\n"
+"    репозитория."
+
+msgid ""
+"    Specifying a path to a repository root or Mercurial bundle will\n"
+"    cause lookup to operate on that repository/bundle."
+msgstr ""
+"    Если задан путь к репозиторию или бандлу Mercurial, будет\n"
+"    работать с этим репозиторием/бандлом."
+
+msgid "can't query remote revision number, branch, or tags"
+msgstr "не могу запросить номер удаленной ревизии, ветви или метки"
+
+msgid ""
+"directory strip option for patch. This has the same meaning as the "
+"corresponding patch option"
+msgstr ""
+"настройка strip для директории при применении патча. Значит то же,что и в "
+"команде patch"
+
+msgid "PATH"
+msgstr "ПУТЬ"
+
+msgid "base path"
+msgstr "базовый путь"
+
+msgid "skip check for outstanding uncommitted changes"
+msgstr "не проверять "
+
+msgid "don't commit, just update the working directory"
+msgstr "не коммитить, просто обновить рабочий каталог"
+
+msgid "apply patch to the nodes from which it was generated"
+msgstr "применить патч к узлам, для которых он был сгенерирован"
+
+msgid "use any branch information in patch (implied by --exact)"
+msgstr "использовать любую информацию о ветвях из патча (включается --exact)"
+
+#, fuzzy
+msgid "[OPTION]... PATCH..."
+msgstr "[ПАРАМЕТР]... ФАЙЛ..."
+
+msgid "import an ordered set of patches"
+msgstr "импортировать упорядоченный набор патчей"
+
+msgid ""
+"    Import a list of patches and commit them individually (unless\n"
+"    --no-commit is specified)."
+msgstr ""
+"    Импортирует список патчей и коммитит их по отдельности (если не\n"
+"    задан параметр --no-commit)"
+
+msgid ""
+"    If there are outstanding changes in the working directory, import\n"
+"    will abort unless given the -f/--force flag."
+msgstr ""
+"    Если в рабочем каталоге есть незакоммиченные изменения, импорт\n"
+"    отменяется, если не указан флаг -f/--force."
+
+msgid ""
+"    You can import a patch straight from a mail message. Even patches\n"
+"    as attachments work (to use the body part, it must have type\n"
+"    text/plain or text/x-patch). From and Subject headers of email\n"
+"    message are used as default committer and commit message. All\n"
+"    text/plain body parts before first diff are added to commit\n"
+"    message."
+msgstr ""
+"    Можно импортировать патчи прямо из емейла. Работает даже для\n"
+"    патчей в приложениях (чтобы использовать патч из тела письма,\n"
+"    оно должно иметь тип text/plain или text/x-patch).Заголовки\n"
+"    электронного письма From и Subject используются по умолчанию\n"
+"    в качестве автора коммита и комментария к коммиту. Все части\n"
+"    тела письма типа text/plain до первого diff'а добавляются\n"
+"    к комментарию к коммиту."
+
+msgid ""
+"    If the imported patch was generated by :hg:`export`, user and\n"
+"    description from patch override values from message headers and\n"
+"    body. Values given on command line with -m/--message and -u/--user\n"
+"    override these."
+msgstr ""
+"    Если импортируемый патч был сгенерирован с помощью :hg:`export`,\n"
+"    пользователь и описание из патча используются вместо заголовков\n"
+"    и тела электронного письма. С помощью параметров -m/--message и\n"
+"    -u/--user можно задать эти значения явно."
+
+msgid ""
+"    If --exact is specified, import will set the working directory to\n"
+"    the parent of each patch before applying it, and will abort if the\n"
+"    resulting changeset has a different ID than the one recorded in\n"
+"    the patch. This may happen due to character set problems or other\n"
+"    deficiencies in the text patch format."
+msgstr ""
+"    Если указан --exact, рабочий каталог будет обновляться до родителя\n"
+"    каждого патча перед его применением, и импорт будет отменен, если\n"
+"    получившийся набор изменений будет иметь другой хэш, чем записанный\n"
+"    в патче. Это может случиться, например, из-за проблем с кодировкой\n"
+"    или других дефектах в формате патча."
+
+msgid ""
+"    With -s/--similarity, hg will attempt to discover renames and\n"
+"    copies in the patch in the same way as 'addremove'."
+msgstr ""
+"    Если указан -s/--similatity, Mercurial попытается обнаружить\n"
+"    копирования и переименования в патче так же, как в 'addremove'."
+
+msgid ""
+"    To read a patch from standard input, use \"-\" as the patch name. If\n"
+"    a URL is specified, the patch will be downloaded from it.\n"
+"    See :hg:`help dates` for a list of formats valid for -d/--date."
+msgstr ""
+"    Используйте \"-\" вместо имени патча, чтобы прочитать патч со\n"
+"    стандартного ввода. Если указан URL, патч будет загружен оттуда.\n"
+"    См. :hg:`help dates` о допустимых форматах дат для -d/--date."
+
+msgid "to working directory"
+msgstr "в рабочий каталог"
+
+msgid "not a Mercurial patch"
+msgstr "не патч Mercurial"
+
+msgid "patch is damaged or loses information"
+msgstr "патч поврежден или в нем недостает данных"
+
+msgid "applying patch from stdin\n"
+msgstr "применяю патч со стандартного вводар\n"
+
+#, python-format
+msgid "applied %s\n"
+msgstr "применен %s\n"
+
+msgid "no diffs found"
+msgstr "отличий не найдено"
+
+msgid "run even if remote repository is unrelated"
+msgstr "работать даже с несвязанным репозиторием"
+
+msgid "show newest record first"
+msgstr "показывать новые записи в начале"
+
+msgid "file to store the bundles into"
+msgstr "файл для сохранения бандла"
+
+msgid "a remote changeset intended to be added"
+msgstr "удаленная ревизия предполагаемая для добавления"
+
+msgid "compare bookmarks"
+msgstr "сранить закладки"
+
+msgid "a specific branch you would like to pull"
+msgstr "конкретная ветвь, которую вы хотите подтянуть"
+
+msgid "[-p] [-n] [-M] [-f] [-r REV]... [--bundle FILENAME] [SOURCE]"
+msgstr "[-p] [-n] [-M] [-f] [-r РЕВ]... [--bundle ФАЙЛ] [ИСТОЧНИК]"
+
+msgid "show new changesets found in source"
+msgstr "показать новые наборы измений в удаленном репозитории"
+
+msgid ""
+"    Show new changesets found in the specified path/URL or the default\n"
+"    pull location. These are the changesets that would have been pulled\n"
+"    if a pull at the time you issued this command."
+msgstr ""
+"    Показывает новые наборы изменений, найденные по указанному\n"
+"    пути/URL или по пути default (см. :hg:`paths`). Эти наборы\n"
+"    изменений были бы затянуты, если бы была использована команда\n"
+"    pull в то же время."
+
+msgid ""
+"    For remote repository, using --bundle avoids downloading the\n"
+"    changesets twice if the incoming is followed by a pull."
+msgstr ""
+"    Для удаленного репозитроия использование --bundle позволяет\n"
+"    избежать повторной загрузки наборов изменений, если за incoming\n"
+"    следует pull."
+
+msgid "    See pull for valid source format details."
+msgstr "    О форматах источника см. pull."
+
+msgid ""
+"    Returns 0 if there are incoming changes, 1 otherwise.\n"
+"    "
+msgstr ""
+"    Возвращает 0 если есть входящие изменения, 1 в противном случае.\n"
+"    "
+
+msgid "cannot combine --bundle and --subrepos"
+msgstr "нельзя совмещать --bundle и --subrepos"
+
+msgid "remote doesn't support bookmarks\n"
+msgstr "удаленный репозиторий не поддерживает закладки\n"
+
+msgid "[-e CMD] [--remotecmd CMD] [DEST]"
+msgstr "[-e КОМАНДА] [--remotecmd КОМАНДА] [НАЗН]"
+
+msgid "create a new repository in the given directory"
+msgstr "создать новый репозиторий в указанном каталоге"
+
+msgid ""
+"    Initialize a new repository in the given directory. If the given\n"
+"    directory does not exist, it will be created."
+msgstr ""
+"    Инициализирует новый репозиторий в заданном каталоге. Если\n"
+"    указанный каталог не существует, он будет создан."
+
+msgid "    If no directory is given, the current directory is used."
+msgstr "    Если каталог не задан, будет использован текущий."
+
+msgid ""
+"    It is possible to specify an ``ssh://`` URL as the destination.\n"
+"    See :hg:`help urls` for more information."
+msgstr ""
+"    Можно задать URL вида ``ssh://`` в качестве каталога назначения.\n"
+"    См. :hg:`help urls` для дополнительной информации."
+
+msgid "search the repository as it is in REV"
+msgstr "искать в репозитории, каким он был на момент РЕВИЗИЯ"
+
+msgid "end filenames with NUL, for use with xargs"
+msgstr "вставлять NUL после имен файлов, для использования с xargs"
+
+msgid "print complete paths from the filesystem root"
+msgstr "печатать полные пути от корня ФС"
+
+msgid "[OPTION]... [PATTERN]..."
+msgstr "[ПАРАМЕТР]... [ШАБЛОН]..."
+
+msgid "locate files matching specific patterns"
+msgstr "найти файлы подходящие под заданный шаблон"
+
+msgid ""
+"    Print files under Mercurial control in the working directory whose\n"
+"    names match the given patterns."
+msgstr ""
+"    Печатает файлы в текущем каталоге, находящиеся под контролем\n"
+"    Mercurial, имена которых подходят под заданные шаблоны."
+
+msgid ""
+"    By default, this command searches all directories in the working\n"
+"    directory. To search just the current directory and its\n"
+"    subdirectories, use \"--include .\"."
+msgstr ""
+"    По умолчанию, эта команда ищет во всем рабочем каталога. Чтобы\n"
+"    искать только текущем каталоге и его подкаталогах, используйте\n"
+"    \"--include .\"."
+
+msgid ""
+"    If no patterns are given to match, this command prints the names\n"
+"    of all files under Mercurial control in the working directory."
+msgstr ""
+"    Если шаблоны не заданы, печатает именя всех файлов, находящихся\n"
+"    под контролем Mercurial в рабочем каталоге."
+
+msgid ""
+"    If you want to feed the output of this command into the \"xargs\"\n"
+"    command, use the -0 option to both this command and \"xargs\". This\n"
+"    will avoid the problem of \"xargs\" treating single filenames that\n"
+"    contain whitespace as multiple filenames."
+msgstr ""
+"    Если вы хотите передать вывод этой команды \"xargs\", используйте\n"
+"    опцию -0 в этой команде и в \"xargs\". Это поможет избежать\n"
+"    проблем, когда \"xargs\" считает отдельные имена с пробелами\n"
+"    несколькими файлами."
+
+#, fuzzy
+msgid "only follow the first parent of merge changesets"
+msgstr "история только для первого родителя ревизий слияния"
+
+msgid "show revisions matching date spec"
+msgstr "показывать ревизии с датой, соответсвующие данной"
+
+msgid "show copied files"
+msgstr "показыать скопированные файлы"
+
+msgid "do case-insensitive search for a given text"
+msgstr "выполнить поиск данного текста, игнорируя регистр"
+
+msgid "include revisions where files were removed"
+msgstr "включить ревизии, в которых файлы были удалены"
+
+msgid "show only merges"
+msgstr "показывать только слияния"
+
+msgid "revisions committed by user"
+msgstr "только ревизии данного пользователем"
+
+msgid "show only changesets within the given named branch (DEPRECATED)"
+msgstr "показывать только ревизии на данной именованной ветви (УСТАРЕЛО)"
+
+msgid "show changesets within the given named branch"
+msgstr "показывать наборы изменений на данной именованной ветви"
+
+msgid "do not display revision or any of its ancestors"
+msgstr "не показывать ревизию и всех ее предшественников"
+
+msgid "[OPTION]... [FILE]"
+msgstr "[ПАРАМЕТР]... [ФАЙЛ]"
+
+msgid "show revision history of entire repository or files"
+msgstr "показать историю ревизий всего репозитория или файлов"
+
+msgid ""
+"    Print the revision history of the specified files or the entire\n"
+"    project."
+msgstr "    Печатает историю ревизий указанных файлов или всего проекта."
+
+msgid ""
+"    File history is shown without following rename or copy history of\n"
+"    files. Use -f/--follow with a filename to follow history across\n"
+"    renames and copies. --follow without a filename will only show\n"
+"    ancestors or descendants of the starting revision. --follow-first\n"
+"    only follows the first parent of merge revisions."
+msgstr ""
+"    История файла показывается без следования за переименованиями или\n"
+"    копированиями файлов. Используйте -f/-follow, чтобы показать\n"
+"    историю с копированиями и переименованиями. --follow без имени\n"
+"    файла покажет только родительские или дочерние ревизии начальной\n"
+"    ревизии. С --follow-first отслеживает только первого родителя\n"
+"    ревизий слияния."
+
+msgid ""
+"    If no revision range is specified, the default is ``tip:0`` unless\n"
+"    --follow is set, in which case the working directory parent is\n"
+"    used as the starting revision. You can specify a revision set for\n"
+"    log, see :hg:`help revsets` for more information."
+msgstr ""
+"    Если не указан диапазон ревизий, по умолчанию используется\n"
+"    ``tip:0``, если не указан --follow, в случае чего родительская\n"
+"    ревизия рабочего каталога используются как начальная ревизия.\n"
+"    Можно также указывать набор ревизий, см. :hg:`help revsets`."
+
+msgid ""
+"    By default this command prints revision number and changeset id,\n"
+"    tags, non-trivial parents, user, date and time, and a summary for\n"
+"    each commit. When the -v/--verbose switch is used, the list of\n"
+"    changed files and full commit message are shown."
+msgstr ""
+"    По умолчанию эта команда печатает номера ревизий с хэшами наборов\n"
+"    изменений, метки, неочевидных родителей, пользователя, дату и\n"
+"    время, а также комментарий для каждого коммита. Если указан\n"
+"    -v/--verbose, печатется также список измененных файлов и полное\n"
+"    сообщение для каждого коммита."
+
+msgid ""
+"    .. note::\n"
+"       log -p/--patch may generate unexpected diff output for merge\n"
+"       changesets, as it will only compare the merge changeset against\n"
+"       its first parent. Also, only files different from BOTH parents\n"
+"       will appear in files:."
+msgstr ""
+"    .. note::\n"
+"       log -p/--patch может генерировать неожиданные diff'ы для\n"
+"       ревизий слияния, поскольку сравнение слитой ревизии\n"
+"       производится только с ее первым родителем. Также в список\n"
+"       попадут только файлы, отличные от ОБОИХ родителей:."
+
+msgid "revision to display"
+msgstr "показать ревизию"
+
+msgid "[-r REV]"
+msgstr "[-r РЕВИЗИЯ]"
+
+msgid "output the current or given revision of the project manifest"
+msgstr "показать текущую или заданную ревизию манифеста проекта"
+
+msgid ""
+"    Print a list of version controlled files for the given revision.\n"
+"    If no revision is given, the first parent of the working directory\n"
+"    is used, or the null revision if no revision is checked out."
+msgstr ""
+"    Печатает список файлов, находящихся под контролем версий, для\n"
+"    текущей или заданной ревизии. Если ревизия не задана, используется\n"
+"    либо первый родитель рабочего каталога, либо пустая (null) ревизия,\n"
+"    если никакой ревизии не извлечено."
+
+msgid ""
+"    With -v, print file permissions, symlink and executable bits.\n"
+"    With --debug, print file revision hashes."
+msgstr ""
+"    С -v печатает права доступа файлов и признаки символической ссылки\n"
+"    и исполняемого файла. С --debug печатает хэши ревизий."
+
+msgid "force a merge with outstanding changes"
+msgstr "слить принудительно, даже если есть незакоммиченные изменения"
+
+msgid "revision to merge"
+msgstr "ревизия для слияния"
+
+msgid "review revisions to merge (no merge is performed)"
+msgstr "просмотреть ревизия для слияния (слияние не проводится)"
+
+msgid "[-P] [-f] [[-r] REV]"
+msgstr "[-P] [-f] [[-r] РЕВИЗИЯ]"
+
+msgid "merge working directory with another revision"
+msgstr "слить рабочий каталог с другой ревизией"
+
+msgid ""
+"    The current working directory is updated with all changes made in\n"
+"    the requested revision since the last common predecessor revision."
+msgstr ""
+"    В текущий рабочий каталог добавляются все изменения, сделанные\n"
+"    в заданной ревизии с момента последней общей ревизии."
+
+msgid ""
+"    Files that changed between either parent are marked as changed for\n"
+"    the next commit and a commit must be performed before any further\n"
+"    updates to the repository are allowed. The next commit will have\n"
+"    two parents."
+msgstr ""
+"    Файлы, измененные по сравнению с любым из родителей, помечаются\n"
+"    как измененные для следующего коммита, который обязательно должен\n"
+"    быть сделан до того, как будут разрешены последующие обновления\n"
+"    робочего каталога. У следующего коммита будет два родителя."
+
+msgid ""
+"    ``--tool`` can be used to specify the merge tool used for file\n"
+"    merges. It overrides the HGMERGE environment variable and your\n"
+"    configuration files. See :hg:`help merge-tools` for options."
+msgstr ""
+"    С помощью ``--tool`` можно задать инструмент для слияния файлов.\n"
+"    Она заменяет переменную окружения HGEMERGT и настройки конфига.\n"
+"    Подробнее см. :hg:``help merge-tool``."
+
+msgid ""
+"    If no revision is specified, the working directory's parent is a\n"
+"    head revision, and the current branch contains exactly one other\n"
+"    head, the other head is merged with by default. Otherwise, an\n"
+"    explicit revision with which to merge with must be provided."
+msgstr ""
+"    Если ревизия не указана, родитель рабочего каталога является\n"
+"    головной ревизией и текущая ветвь имеет ровно одну другую голову,\n"
+"    производится слияние с этой головой по умолчанию. В противном\n"
+"    случае, требуется явно указать ревизию для слияния."
+
+msgid "    :hg:`resolve` must be used to resolve unresolved files."
+msgstr ""
+"    Используйте :hg:`resolve`, чтобы пометить файлы с устраненными "
+"конфликтами"
+
+#, fuzzy
+msgid ""
+"    To undo an uncommitted merge, use :hg:`update --clean .` which\n"
+"    will check out a clean copy of the original merge parent, losing\n"
+"    all changes."
+msgstr ""
+"    Используйте :hg:`update -clean .`, чтобы отменить незакоммиченное\n"
+"    слияние. Это извлечет чистую копию родителя, изначально выбранного\n"
+"    для слияния, с потерей всех  изменений."
+
+msgid ""
+"    Returns 0 on success, 1 if there are unresolved files.\n"
+"    "
+msgstr ""
+"    При успехе возвращает 0, 1 если есть неразрешенные конфликты.\n"
+"    "
+
+#, python-format
+msgid "branch '%s' has %d heads - please merge with an explicit rev"
+msgstr "ветвь '%s' имеет %d голов(ы) - явно укажите ревизию для слияния"
+
+msgid "run 'hg heads .' to see heads"
+msgstr "используйте 'hg heads .' чтобы посмотреть головы"
+
+#, python-format
+msgid "branch '%s' has one head - please merge with an explicit rev"
+msgstr "ветвь '%s' имеет одну голову - явно укажите ревизию для слияния"
+
+msgid "run 'hg heads' to see all heads"
+msgstr "используйте 'hg heads' чтобы посмотреть все головы"
+
+msgid "there is nothing to merge"
+msgstr "нечего сливать"
+
+#, python-format
+msgid "%s - use \"hg update\" instead"
+msgstr "%s - используйте \"hg update\""
+
+msgid "working directory not at a head revision"
+msgstr "рабочий каталог не на головной ревизии"
+
+msgid "use 'hg update' or merge with an explicit revision"
+msgstr "используйте 'hg update' или явно укажите ревизию"
+
+msgid "a changeset intended to be included in the destination"
+msgstr "набора изменений для добавления в удаленный репозиторий"
+
+msgid "a specific branch you would like to push"
+msgstr "одна ветвь, которую вы хотите втолкнуть"
+
+msgid "[-M] [-p] [-n] [-f] [-r REV]... [DEST]"
+msgstr "[-M] [-p] [-n] [-f] [-r РЕВИЗИЯ]... [НАЗН]"
+
+msgid "show changesets not found in the destination"
+msgstr "показать наборы изменений, отсутвующие в другом репозитории"
+
+msgid ""
+"    Show changesets not found in the specified destination repository\n"
+"    or the default push location. These are the changesets that would\n"
+"    be pushed if a push was requested."
+msgstr ""
+"    Показыает наборы изменений, не найденные в указанном удаленном\n"
+"    репозитории или по пути по умолчанию для push. Эти наборы\n"
+"    изменений были бы переданы командой push."
+
+msgid "    See pull for details of valid destination formats."
+msgstr "    Подробней о форматах пути репозитория назначения см. pull"
+
+msgid ""
+"    Returns 0 if there are outgoing changes, 1 otherwise.\n"
+"    "
+msgstr ""
+"    Возвращает 0, если есть исходящие изменения, иначе 1.\n"
+"    "
+
+msgid "show parents of the specified revision"
+msgstr "показать родителей указанной ревизии"
+
+msgid "[-r REV] [FILE]"
+msgstr "[-r РЕВИЗИЯ] [ФАЙЛ]"
+
+msgid "show the parents of the working directory or revision"
+msgstr "показать родителя рабочего каталога или ревизии"
+
+msgid ""
+"    Print the working directory's parent revisions. If a revision is\n"
+"    given via -r/--rev, the parent of that revision will be printed.\n"
+"    If a file argument is given, the revision in which the file was\n"
+"    last changed (before the working directory revision or the\n"
+"    argument to --rev if given) is printed."
+msgstr ""
+"    Печатает родительскую ревизию рабочего каталога. Если указана\n"
+"    ревизия с помощью -r/--rev, печатает родителя этой ревизии.\n"
+"    Если задано имя файла, печатает ревизию, в которой этот файл был\n"
+"    изменен последний раз (до ревизии рабочего каталога или ревизии,\n"
+"    заданной через --rev)"
+
+msgid "can only specify an explicit filename"
+msgstr "можно задать только явное имя файла"
+
+#, python-format
+msgid "'%s' not found in manifest!"
+msgstr "'%s' не найден в манифесте!"
+
+msgid "[NAME]"
+msgstr "[ИМЯ]"
+
+msgid "show aliases for remote repositories"
+msgstr "показать псевдонимы удаленных репозиториев"
+
+msgid ""
+"    Show definition of symbolic path name NAME. If no name is given,\n"
+"    show definition of all available names."
+msgstr ""
+"    Показывает полный путь для сокращенного имени репозитория ИМЯ.\n"
+"    Если имя не задано, показывает полные пути для всех известных\n"
+"    псевдонимов."
+
+msgid ""
+"    Option -q/--quiet suppresses all output when searching for NAME\n"
+"    and shows only the path names when listing all definitions."
+msgstr ""
+"    Параметр -q/--quite полностью отключает вывод при поиске одного\n"
+"    ИМЕНИ и показывает только псевдонимы без полных путей если ИМЯ\n"
+"    не задано."
+
+msgid ""
+"    Path names are defined in the [paths] section of your\n"
+"    configuration file and in ``/etc/mercurial/hgrc``. If run inside a\n"
+"    repository, ``.hg/hgrc`` is used, too."
+msgstr ""
+"    Псевдонимы путей репозиториев определены в секции [path] вашего \n"
+"    конфига и в ``etc/mercurial/hgrc``. Если запускается из каталога,\n"
+"    содержащего репозиторий, используется также ``.hg/hgrc``."
+
+msgid ""
+"    The path names ``default`` and ``default-push`` have a special\n"
+"    meaning.  When performing a push or pull operation, they are used\n"
+"    as fallbacks if no location is specified on the command-line.\n"
+"    When ``default-push`` is set, it will be used for push and\n"
+"    ``default`` will be used for pull; otherwise ``default`` is used\n"
+"    as the fallback for both.  When cloning a repository, the clone\n"
+"    source is written as ``default`` in ``.hg/hgrc``.  Note that\n"
+"    ``default`` and ``default-push`` apply to all inbound (e.g.\n"
+"    :hg:`incoming`) and outbound (e.g. :hg:`outgoing`, :hg:`email` and\n"
+"    :hg:`bundle`) operations."
+msgstr ""
+"    Пути ``default`` и ``default-push`` имеют специальное значение.\n"
+"    Они используются по умолчание при операциях push и pull, если\n"
+"    путь не указан явно. Если установлен ``default-push``, он будет\n"
+"    использован для операции push, ``default`` будет использован для\n"
+"    pull; в противном случае, ``default`` будет использован для обеих\n"
+"    операций. При клонировании адрес источника записывается как\n"
+"    ``default`` в ``.hg/hgrc``. Обратите внимание, что ``default``\n"
+"    и ``default-push`` применяются для всех входящих (например,\n"
+"    :hg:`incoming`) и исходящих (напр, :hg:`outgoing`, :hg:`email` и\n"
+"    :hg:`bundle`) операций."
+
+msgid "    See :hg:`help urls` for more information."
+msgstr "    Подробнее см. :hg:`help urls`."
+
+msgid "not found!\n"
+msgstr "не найден!\n"
+
+msgid "not updating, since new heads added\n"
+msgstr "не обновляюсь т.к. добавлены новые головы\n"
+
+msgid "(run 'hg heads' to see heads, 'hg merge' to merge)\n"
+msgstr ""
+"(используйте 'hg heads' чтобы посмотреть головы, 'hg merge' для слияния)\n"
+
+msgid "(run 'hg heads .' to see heads, 'hg merge' to merge)\n"
+msgstr ""
+"(используйте 'hg heads .' чтобы посмотреть головы, 'hg merge' для слияния)\n"
+
+msgid "(run 'hg heads' to see heads)\n"
+msgstr "(используйте 'hg heads' чтобы посмотреть головы)\n"
+
+msgid "(run 'hg update' to get a working copy)\n"
+msgstr "(используйте 'hg update' чтобы получить рабочую копию)\n"
+
+msgid "update to new branch head if changesets were pulled"
+msgstr "обновиться до новой головы ветви если наборы изменений были подтянуты"
+
+msgid "run even when remote repository is unrelated"
+msgstr "работать даже на несвязанном репозитории"
+
+msgid "BOOKMARK"
+msgstr "ЗАКЛАДКА"
+
+msgid "bookmark to pull"
+msgstr "подтянуть закладку"
+
+msgid "[-u] [-f] [-r REV]... [-e CMD] [--remotecmd CMD] [SOURCE]"
+msgstr "[-u] [-f] [-r РЕВ]... [-e КОМ-ДА] [--remotecmd КОМ-ДА] [ИСТОЧНИК]"
+
+msgid "pull changes from the specified source"
+msgstr "подтянуть изменения из указанного источника"
+
+msgid "    Pull changes from a remote repository to a local one."
+msgstr "    Подтягивает изменения из удаленного репозитория в локальный."
+
+msgid ""
+"    This finds all changes from the repository at the specified path\n"
+"    or URL and adds them to a local repository (the current one unless\n"
+"    -R is specified). By default, this does not update the copy of the\n"
+"    project in the working directory."
+msgstr ""
+"    Находит все измения в репозитории по указанному пути или URL и\n"
+"    добавляет их в локальный репозиторий (по умолчанию текущий, если\n"
+"    не указан другой через -R). По умолчанию рабочая копия\n"
+"    обновляется."
+
+msgid ""
+"    Use :hg:`incoming` if you want to see what would have been added\n"
+"    by a pull at the time you issued this command. If you then decide\n"
+"    to add those changes to the repository, you should use :hg:`pull\n"
+"    -r X` where ``X`` is the last changeset listed by :hg:`incoming`."
+msgstr ""
+"    Используйте :hg:`incoming` чтобы посмотреть, что было бы добавлено\n"
+"    командой pull, вызванной в тот же момент времени. Если потом вы\n"
+"    вы решите добавить эти изменения в репозиторий, следует\n"
+"    использовать :hg:`pull -r X`, где ``X`` - последняя ревизия,\n"
+"    показанная :hg:`incoming`."
+
+msgid ""
+"    If SOURCE is omitted, the 'default' path will be used.\n"
+"    See :hg:`help urls` for more information."
+msgstr ""
+"    Если ИСТОЧНИК не задан, будет использова путь 'default'.\n"
+"    Подробнее см. :hg:`help urls`."
+
+msgid ""
+"    Returns 0 on success, 1 if an update had unresolved files.\n"
+"    "
+msgstr ""
+"    Возвращает 0 при успехе, 1 если есть конфликты при обновлении.\n"
+"    "
+
+#, python-format
+msgid "remote bookmark %s not found!"
+msgstr "закладка %s не найдена в удаленном репозитории"
+
+msgid ""
+"other repository doesn't support revision lookup, so a rev cannot be "
+"specified."
+msgstr ""
+"Удаленый репозиторий не поддерживает поиск ревизий, поэтому ревизия неможет "
+"быть задана."
+
+#, python-format
+msgid "importing bookmark %s\n"
+msgstr "импорируется закладка %s\n"
+
+msgid "force push"
+msgstr "протолкнуть принудительно"
+
+msgid "bookmark to push"
+msgstr "протолкнуть закладку"
+
+msgid "allow pushing a new branch"
+msgstr "разрешить создать новую ветвь в удаленном репозитории"
+
+msgid "[-f] [-r REV]... [-e CMD] [--remotecmd CMD] [DEST]"
+msgstr "[-f] [-r РЕВ]... [-e КОМ-ДА] [--remotecmd КОМ-ДА] [НАЗН]"
+
+msgid "push changes to the specified destination"
+msgstr "\"протолкнуть\" изменения в удаленный репозиторий"
+
+msgid ""
+"    Push changesets from the local repository to the specified\n"
+"    destination."
+msgstr ""
+"    Передает изменения из локального репозитория в удаленный\n"
+"    "
+
+msgid ""
+"    This operation is symmetrical to pull: it is identical to a pull\n"
+"    in the destination repository from the current one."
+msgstr ""
+"    Эта операция симметрична pull: она имеет такой же эффект, как\n"
+"    если бы в удаленном репозитория был выполнен pull из текущего."
+
+msgid ""
+"    By default, push will not allow creation of new heads at the\n"
+"    destination, since multiple heads would make it unclear which head\n"
+"    to use. In this situation, it is recommended to pull and merge\n"
+"    before pushing."
+msgstr ""
+"    По умолчанию push не даст создать новые \"головы\" в удаленном\n"
+"    репозитории, потому что в этом случае было бы не ясно, какую\n"
+"    голову использовать. В такой ситуации рекомендуется\n"
+"    подтянуть (pull) и слить (merge) изменения перед push'ем."
+
+msgid ""
+"    Use --new-branch if you want to allow push to create a new named\n"
+"    branch that is not present at the destination. This allows you to\n"
+"    only create a new branch without forcing other changes."
+msgstr ""
+"    Используйте --new-branch, если вы хотите разрешить создание\n"
+"    именованной ветви, которой нет в удаленном репозитории. Это\n"
+"    позволяет просто создать новую ветвь в удаленном репозитории,\n"
+"    не проталкивая остальные изменения."
+
+msgid ""
+"    Use -f/--force to override the default behavior and push all\n"
+"    changesets on all branches."
+msgstr ""
+"    Используйте -f/--force чтобы игнорировать поведение по\n"
+"    умолчанию и протолкнуть все изменения на всех ветвях."
+
+msgid ""
+"    If -r/--rev is used, the specified revision and all its ancestors\n"
+"    will be pushed to the remote repository."
+msgstr ""
+"    Если указан -r/--rev, то заданная ревизия и все ее потомки\n"
+"    будут переданы в удаленный репозиторий."
+
+msgid ""
+"    Please see :hg:`help urls` for important details about ``ssh://``\n"
+"    URLs. If DESTINATION is omitted, a default path will be used."
+msgstr ""
+"    См. :hg:`help urls` о важных подробностях об URL вида ``ssh://``.\n"
+"    Если НАЗНАЧЕНИЕ опущено, используется путь по умолчанию (default)."
+
+msgid ""
+"    Returns 0 if push was successful, 1 if nothing to push.\n"
+"    "
+msgstr ""
+"    Возвращает 0 в случае успехе, 1 если нет изменений для push'а.\n"
+"    "
+
+#, python-format
+msgid "pushing to %s\n"
+msgstr "проталкиваю в %s\n"
+
+#, python-format
+msgid "exporting bookmark %s\n"
+msgstr "экспортируется закладка %s\n"
+
+#, python-format
+msgid "deleting remote bookmark %s\n"
+msgstr "удаляется удаленная закладка %s\n"
+
+#, python-format
+msgid "bookmark %s does not exist on the local or remote repository!\n"
+msgstr "закладка %s не существует в локальном или удаленном репозитории!\n"
+
+#, python-format
+msgid "updating bookmark %s failed!\n"
+msgstr "не удалось обновить закладку %s!\n"
+
+msgid "roll back an interrupted transaction"
+msgstr "откатить прерванную транзакцию"
+
+msgid "    Recover from an interrupted commit or pull."
+msgstr "    Восстанавливает репозиторий после прерванного push или pull"
+
+msgid ""
+"    This command tries to fix the repository status after an\n"
+"    interrupted operation. It should only be necessary when Mercurial\n"
+"    suggests it."
+msgstr ""
+"    Эта команда пытается исправить состояние репозитория после\n"
+"    прерванной операции. Это должно быть необходимо только если\n"
+"    Mercurial сам предлагает это сделать."
+
+msgid ""
+"    Returns 0 if successful, 1 if nothing to recover or verify fails.\n"
+"    "
+msgstr ""
+"    Возвращает 0 в случае успеха, 1 если нечего восстанавливать или\n"
+"    проверка целостности не прошла."
+
+msgid "record delete for missing files"
+msgstr "удалить отсутствующие файлы"
+
+msgid "remove (and delete) file even if added or modified"
+msgstr ""
+"удалять файлы из каталога и репозитория даже если они были добавлены или "
+"изменены"
+
+msgid "remove the specified files on the next commit"
+msgstr "удалить указанные файлы при следующем коммите"
+
+msgid "    Schedule the indicated files for removal from the repository."
+msgstr "    Помечает заданные файлы для удаления из репозитория."
+
+msgid ""
+"    This only removes files from the current branch, not from the\n"
+"    entire project history. -A/--after can be used to remove only\n"
+"    files that have already been deleted, -f/--force can be used to\n"
+"    force deletion, and -Af can be used to remove files from the next\n"
+"    revision without deleting them from the working directory."
+msgstr ""
+"    Удаляются только файлы с текущей ветки, а не из всей истории\n"
+"    проекта. Используйте -A/--after, чтобы удалить из репозитория\n"
+"    файлы, которые были удалены из рабочего каталога. -f/--force\n"
+"    удаляет файлы принудительно, -Af можно использовать чтобы\n"
+"    удалить файлы из следующей ревизии, не удаляя их из рабочего\n"
+"    каталога."
+
+msgid ""
+"    The following table details the behavior of remove for different\n"
+"    file states (columns) and option combinations (rows). The file\n"
+"    states are Added [A], Clean [C], Modified [M] and Missing [!] (as\n"
+"    reported by :hg:`status`). The actions are Warn, Remove (from\n"
+"    branch) and Delete (from disk)::"
+msgstr ""
+"    Приведенная ниже таблица поясняет поведение команды remove для\n"
+"    разных состояний файла (столбцы) и комбинаций параметров (строки).\n"
+"    Состояния файлов (как их показывает :hg:`status`):\n"
+"    Добавлен (Added) [A], Без изменений (Clean) [C],\n"
+"    Изменен (Modified) [M], Отсутствует (Missing) [!]. Действия:\n"
+"    Предупредить (Warn - W), удалить из ветви (Remove - R), удалить\n"
+"    из каталога (Delete - D)."
+
+msgid ""
+"             A  C  M  !\n"
+"      none   W  RD W  R\n"
+"      -f     R  RD RD R\n"
+"      -A     W  W  W  R\n"
+"      -Af    R  R  R  R"
+msgstr ""
+"             A  C  M  !\n"
+"      нет    W  RD W  R\n"
+"      -f     R  RD RD R\n"
+"      -A     W  W  W  R\n"
+"      -Af    R  R  R  R"
+
+msgid ""
+"    This command schedules the files to be removed at the next commit.\n"
+"    To undo a remove before that, see :hg:`revert`."
+msgstr ""
+"    Эта команда помечает файлы для удаления при следующем коммите.\n"
+"    Чтобы отменить удаление до коммита, см. :hg:`revert`."
+
+msgid ""
+"    Returns 0 on success, 1 if any warnings encountered.\n"
+"    "
+msgstr "    При успехе возвращает 0, 1 если были придупреждения."
+
+#, python-format
+msgid "not removing %s: file is untracked\n"
+msgstr "%s не удален: файл не контролируется\n"
+
+#, python-format
+msgid "not removing %s: file still exists (use -f to force removal)\n"
+msgstr "%s не удален: файл еще существует (-f - удалить принудительно)\n"
+
+#, python-format
+msgid "not removing %s: file is modified (use -f to force removal)\n"
+msgstr "%s не удален: файл изменен (-f - удалить принудительно)\n"
+
+#, python-format
+msgid ""
+"not removing %s: file has been marked for add (use -f to force removal)\n"
+msgstr ""
+"%s не удален: файл был помечен для добавления (-f - удалить принудительно)\n"
+
+msgid "record a rename that has already occurred"
+msgstr "записать переименование, которое уже было сделано"
+
+msgid "[OPTION]... SOURCE... DEST"
+msgstr "[ПАРАМЕТР]... ИСТОЧНИК... НАЗНАЧЕНИЕ"
+
+msgid "rename files; equivalent of copy + remove"
+msgstr "переименовать файлы; эквивалентно copy + remove"
+
+msgid ""
+"    Mark dest as copies of sources; mark sources for deletion. If dest\n"
+"    is a directory, copies are put in that directory. If dest is a\n"
+"    file, there can only be one source."
+msgstr ""
+"    Помечает файлы назначения как копии файлов-источников; помечает\n"
+"    источники для удаления. Если НАЗНАЧЕНИЕ - каталог, копии\n"
+"    помещаются в этот каталог. Если НАЗНАЧЕНИЕ - файл, то ИСТОЧНИК\n"
+"    может быть только один."
+
+msgid ""
+"    This command takes effect at the next commit. To undo a rename\n"
+"    before that, see :hg:`revert`."
+msgstr ""
+"    Эффект команды закрепляется при следующем коммите. чтобы отменить\n"
+"    переимнование, см. :hg:`revert`."
+
+msgid "select all unresolved files"
+msgstr "работать со всеми требущими слияния файлами"
+
+msgid "list state of files needing merge"
+msgstr "показать состояния файлов, трубующих слияния"
+
+msgid "mark files as resolved"
+msgstr "пометить файлы как корректно слитый"
+
+msgid "mark files as unresolved"
+msgstr "пометить файлы как требующие слияния"
+
+msgid "hide status prefix"
+msgstr "не показывать префикс состояния"
+
+msgid "redo merges or set/view the merge status of files"
+msgstr "повторить слияния или задать/посмотреть статус слитых файлов"
+
+msgid ""
+"    Merges with unresolved conflicts are often the result of\n"
+"    non-interactive merging using the ``internal:merge`` configuration\n"
+"    setting, or a command-line merge tool like ``diff3``. The resolve\n"
+"    command is used to manage the files involved in a merge, after\n"
+"    :hg:`merge` has been run, and before :hg:`commit` is run (i.e. the\n"
+"    working directory must have two parents)."
+msgstr ""
+"    Неразрешенные конфликтами часто являются результатом неинтерактивного\n"
+"    слияния с использованием ``internal:merge``, или программы слияния\n"
+"    с текстовым интерфесом, вроде ``diff3``. Команда resolve может\n"
+"    быть использована для управления файлами, участвующими в слиянии,\n"
+"    после того, как была запущена :hg:`merge`, но до :hg:`commit`\n"
+"    (т.е. рабочий каталог должен иметь двух \"родителей\")."
+
+msgid "    The resolve command can be used in the following ways:"
+msgstr "    Команда resolve может использоваться следующими способами:"
+
+msgid ""
+"    - :hg:`resolve [--tool TOOL] FILE...`: attempt to re-merge the "
+"specified\n"
+"      files, discarding any previous merge attempts. Re-merging is not\n"
+"      performed for files already marked as resolved. Use ``--all/-a``\n"
+"      to selects all unresolved files. ``--tool`` can be used to specify\n"
+"      the merge tool used for the given files. It overrides the HGMERGE\n"
+"      environment variable and your configuration files."
+msgstr ""
+"    - :hg:`resolve [--tool ПРОГРАММА] ФАЙЛ...`: попытаться повторитьслияние\n"
+"    файлов, отменяя предыдущие попытки. Повторное слияние не проводится\n"
+"    для файлов, помеченных как разрешенные. Используйте ``--all/-a``,\n"
+"    чтобы повторить слияние для всех неразрешенных файлов. Параметр\n"
+"    ``--tool`` может быть использован, чтобы задать программу для слияния.\n"
+"    Он замещает переменную окружения HGMERGE и конфиг."
+
+msgid ""
+"    - :hg:`resolve -m [FILE]`: mark a file as having been resolved\n"
+"      (e.g. after having manually fixed-up the files). The default is\n"
+"      to mark all unresolved files."
+msgstr ""
+"    - :hg:`resolve -m [ФАЙЛ]`: пометить указанный файл как файл с\n"
+"      разрешенными конфликтами (т.е. после ручного исправления\n"
+"      конфликтов). По умолчанию помечает все файлы с конфликтами."
+
+msgid ""
+"    - :hg:`resolve -u [FILE]...`: mark a file as unresolved. The\n"
+"      default is to mark all resolved files."
+msgstr ""
+"    - :hg:`resolve -u [ФАЙЛ]...`: пометить файл как файл с\n"
+"      неразрешенными конфликтами. По умолчанию помечает все\n"
+"      неразрешенные файлы."
+
+msgid ""
+"    - :hg:`resolve -l`: list files which had or still have conflicts.\n"
+"      In the printed list, ``U`` = unresolved and ``R`` = resolved."
+msgstr ""
+"    - :hg:`resolve -l`: перечислить файлы, в которых были или\n"
+"      до сих пор есть конфликты. В списке ``U`` = конфликты есть\n"
+"      (Unresolved), ``R`` = конфликтов нет (Resolved)."
+
+msgid ""
+"    Note that Mercurial will not let you commit files with unresolved\n"
+"    merge conflicts. You must use :hg:`resolve -m ...` before you can\n"
+"    commit after a conflicting merge."
+msgstr ""
+"    Обратите внимание, что Mercurial не даст вам закоммитить файлы\n"
+"    с неразрешенными конфликтами слияния. Необходимо использовать\n"
+"    :hg:`resolve -m` перед коммитом после слияния с конфликтами."
+
+msgid ""
+"    Returns 0 on success, 1 if any files fail a resolve attempt.\n"
+"    "
+msgstr ""
+"    При успехе возвращает 0, 1 если не удалось разрешить файл.\n"
+"    "
+
+msgid "too many options specified"
+msgstr "указано слишком много параметров"
+
+msgid "can't specify --all and patterns"
+msgstr "нельзя задавать шаблон и --all одновременно"
+
+msgid "no files or directories specified; use --all to remerge all files"
+msgstr "не заданы файлы или каталоги; --all повторит слияние для всех файлов"
+
+msgid "revert all changes when no arguments given    \n"
+msgstr "без параметров вернуть файлы к прежнему состоянию    \n"
+
+msgid "tipmost revision matching date"
+msgstr "максимальная ревизия не позднее ДАТЫ"
+
+msgid "revert to the specified revision"
+msgstr "вернуть состяние на момент указанной ревизию"
+
+msgid "do not save backup copies of files"
+msgstr "не делать бэкап файлов"
+
+msgid "[OPTION]... [-r REV] [NAME]..."
+msgstr "[ПАРАМЕТР]... [-r РЕВИЗИЯ] [ИМЯ]..."
+
+msgid "restore individual files or directories to an earlier state"
+msgstr "вернуть файлы или каталоги к более раннему состоянию"
+
+msgid ""
+"    .. note::\n"
+"       This command is most likely not what you are looking for.\n"
+"       Revert will partially overwrite content in the working\n"
+"       directory without changing the working directory parents. Use\n"
+"       :hg:`update -r rev` to check out earlier revisions, or\n"
+"       :hg:`update --clean .` to undo a merge which has added another\n"
+"       parent."
+msgstr ""
+"    .. note::\n"
+"       Эта команда почти наверняка не то, что вы ищете. Revert\n"
+"       частично переписывает файлы в рабочем каталоге, не изменяя его\n"
+"       родительскую ревизию в репозитории. Используйте \n"
+"       :hg:`update -r рев` чтобы извлечь предыдущие ревизии, или\n"
+"       :hg update --clean .` чтобы отменить слияние, которе добавило\n"
+"       второго родителя."
+
+msgid ""
+"    With no revision specified, revert the named files or directories\n"
+"    to the contents they had in the parent of the working directory.\n"
+"    This restores the contents of the affected files to an unmodified\n"
+"    state and unschedules adds, removes, copies, and renames. If the\n"
+"    working directory has two parents, you must explicitly specify a\n"
+"    revision."
+msgstr ""
+"    Если ревизия не задана, вернуть указанные файлы и каталоги к\n"
+"    состоянию, в котором они сохранены в родительской ревизии\n"
+"    рабочего каталога. Это восстанавливает содержимое указанных\n"
+"    файлов до неизмененного состояния и отменяет запланированные\n"
+"    добавления, удаления, копирования и переименования файлов.\n"
+"    Если у рабочего каталога два родителя, ревизия нужно указать\n"
+"    явно."
+
+msgid ""
+"    Using the -r/--rev option, revert the given files or directories\n"
+"    to their contents as of a specific revision. This can be helpful\n"
+"    to \"roll back\" some or all of an earlier change. See :hg:`help\n"
+"    dates` for a list of formats valid for -d/--date."
+msgstr ""
+"    С параметром -r/--rev восстанавливает содержимое заданных файлов\n"
+"    и каталогов до указанной ревизии. Это может быть полезным чтобы\n"
+"    \"откатить\" все или некоторые предшествующие изменения.\n"
+"    О форматах датах для -d/--date см. :hg:`help dates`."
+
+msgid ""
+"    Revert modifies the working directory. It does not commit any\n"
+"    changes, or change the parent of the working directory. If you\n"
+"    revert to a revision other than the parent of the working\n"
+"    directory, the reverted files will thus appear modified\n"
+"    afterwards."
+msgstr ""
+"    Revert изменяет рабочий каталог. Она не комитит никаких\n"
+"    изменений и не меняет родителя рабочего каталога. Если вы\n"
+"    выполните revert на ревизию, отличную от текущей родительской,\n"
+"    восстановленные файлы будут иметь статус измененных."
+
+msgid ""
+"    If a file has been deleted, it is restored. Files scheduled for\n"
+"    addition are just unscheduled and left as they are. If the\n"
+"    executable mode of a file was changed, it is reset."
+msgstr ""
+"    Если файл был удален, он восстанавливается. У файлов, помеченных\n"
+"    для добавления, пометка снимается, сами файлы при этом не\n"
+"    изменяются. Если изменился признак исполнимости файла, он\n"
+"    сбраывается."
+
+msgid ""
+"    If names are given, all files matching the names are reverted.\n"
+"    If no arguments are given, no files are reverted."
+msgstr ""
+"    Если заданы имена, восстанавливаются все файлы с подходящими\n"
+"    именами. Без аргумнтов никакие файлы не будут восстановлены."
+
+msgid ""
+"    Modified files are saved with a .orig suffix before reverting.\n"
+"    To disable these backups, use --no-backup."
+msgstr ""
+"    Измененные файлы сохранятся с расширением .orig перед\n"
+"    восстановлением. Можно отключить это резервное копирование\n"
+"    с помощью --no-backup."
+
+msgid "you can't specify a revision and a date"
+msgstr "нельзя указывать одновременно дату и ревизию"
+
+msgid "uncommitted merge - use \"hg update\", see \"hg help revert\""
+msgstr ""
+"незакомиченное слияние - используйте \"hg update\", см. \"hg help revert\""
+
+msgid "no files or directories specified; use --all to revert the whole repo"
+msgstr "не заданы файлы или каталоги; --all откатит весь репозиторий"
+
+#, python-format
+msgid "forgetting %s\n"
+msgstr "забываю %s\n"
+
+#, python-format
+msgid "reverting %s\n"
+msgstr "восстанавление %s\n"
+
+#, python-format
+msgid "undeleting %s\n"
+msgstr "отмена удаления %s\n"
+
+#, python-format
+msgid "saving current version of %s as %s\n"
+msgstr "текущая версисия %s сохраняется как %s\n"
+
+#, python-format
+msgid "file not managed: %s\n"
+msgstr "файл не под контролем версий: %s\n"
+
+#, python-format
+msgid "no changes needed to %s\n"
+msgstr "не требуются изменения для %s\n"
+
+msgid "roll back the last transaction (dangerous)"
+msgstr "откатить последнюю транзакцию (опасно)"
+
+msgid ""
+"    This command should be used with care. There is only one level of\n"
+"    rollback, and there is no way to undo a rollback. It will also\n"
+"    restore the dirstate at the time of the last transaction, losing\n"
+"    any dirstate changes since that time. This command does not alter\n"
+"    the working directory."
+msgstr ""
+"    Эту команду следует использовать очень осторожно, поскольку\n"
+"    можно откатить только на один уровень вглубь и нельзя отменить\n"
+"    откат. Она также восстановит dirstate на время последней\n"
+"    транзакции, теряя все его изменения, сделанные после этого. Не\n"
+"    изменяет рабочий каталог."
+
+msgid ""
+"    Transactions are used to encapsulate the effects of all commands\n"
+"    that create new changesets or propagate existing changesets into a\n"
+"    repository. For example, the following commands are transactional,\n"
+"    and their effects can be rolled back:"
+msgstr ""
+"    Транзакции используются для инкапсуляции эффектов всех команд,\n"
+"    которые создают новые наборы изменений или передают уже\n"
+"    существующие в репозиторий. Действие таких команд можно откатиь.\n"
+"    Транзакционными являются, например, следующие команды:"
+
+msgid ""
+"    - commit\n"
+"    - import\n"
+"    - pull\n"
+"    - push (with this repository as the destination)\n"
+"    - unbundle"
+msgstr ""
+"    - commit\n"
+"    - import\n"
+"    - pull\n"
+"    - push (с текущим репозиторием в качестве назначения)\n"
+"    - unbundle"
+
+msgid ""
+"    This command is not intended for use on public repositories. Once\n"
+"    changes are visible for pull by other users, rolling a transaction\n"
+"    back locally is ineffective (someone else may already have pulled\n"
+"    the changes). Furthermore, a race is possible with readers of the\n"
+"    repository; for example an in-progress pull from the repository\n"
+"    may fail if a rollback is performed."
+msgstr ""
+"    Эта команда не предназначена для использования на публичных\n"
+"    репозиториях. Если изменения могут быть утянутыми другими\n"
+"    пользователями, локальный откат транзакций не имеет смысла\n"
+"    (кто-то могу уже утянуть изменения). Более того, возможны гонки\n"
+"    с читающими репозитрий; например, текущий pull может завершиться\n"
+"    нудачей, если в это время будет вызван rollback."
+
+msgid ""
+"    Returns 0 on success, 1 if no rollback data is available.\n"
+"    "
+msgstr ""
+"    Возвращает 0 при успехе, 1 если нет данных для отката.\n"
+"    "
+
+msgid "print the root (top) of the current working directory"
+msgstr "напечатать корневой каталог текущего репозитория"
+
+msgid "    Print the root directory of the current repository."
+msgstr "    Печатает корневой каталог текущего репозитория."
+
+msgid "name of access log file to write to"
+msgstr "имя файла для записи журнала доступа"
+
+msgid "name of error log file to write to"
+msgstr "имя файла для записи журнала ошибок"
+
+msgid "PORT"
+msgstr "ПОРТ"
+
+msgid "port to listen on (default: 8000)"
+msgstr "номер порта для входящих соединений (по умолчанию 8000)"
+
+msgid "address to listen on (default: all interfaces)"
+msgstr "адрес для входящих соединений (по умолчанию - все интерфейсы)"
+
+msgid "ADDR"
+msgstr "АДРЕС"
+
+#, fuzzy
+msgid "prefix path to serve from (default: server root)"
+msgstr "корневая директория сервера (по умолчанию: корень сервера)"
+
+msgid "name to show in web pages (default: working directory)"
+msgstr ""
+"имя, показываемое на веб-страницах (по умолчанию имя рабочего каталога)"
+
+msgid "name of the hgweb config file (see \"hg help hgweb\")"
+msgstr "путь к конфигу hgweb (см. \"hg help hgweb\")"
+
+msgid "name of the hgweb config file (DEPRECATED)"
+msgstr "путь к конфигу hgweb (УСТАРЕЛО)"
+
+msgid "for remote clients"
+msgstr "для удалённых клиентов"
+
+msgid "web templates to use"
+msgstr "используемые веб-шаблоны"
+
+msgid "template style to use"
+msgstr "используемый стиль шаблона"
+
+msgid "use IPv6 in addition to IPv4"
+msgstr "использовать IPv6 вместе с IPv4"
+
+msgid "SSL certificate file"
+msgstr "Файл сертификата SSL"
+
+msgid "start stand-alone webserver"
+msgstr "запустить автономный веб-серве"
+
+msgid ""
+"    Start a local HTTP repository browser and pull server. You can use\n"
+"    this for ad-hoc sharing and browsing of repositories. It is\n"
+"    recommended to use a real web server to serve a repository for\n"
+"    longer periods of time."
+msgstr ""
+"    Запускает локальный HTTP-обзреватель репозитория и pull-сервер.\n"
+"    Эту команду можно использовать в качетве простого способа\n"
+"    организации совместного доступа и просмотра репозитория по сети.\n"
+"    Для более серьезной работы в течение длительного времени,\n"
+"    рекомендуется использовать нормальный веб-сервер."
+
+msgid ""
+"    Please note that the server does not implement access control.\n"
+"    This means that, by default, anybody can read from the server and\n"
+"    nobody can write to it by default. Set the ``web.allow_push``\n"
+"    option to ``*`` to allow everybody to push to the server. You\n"
+"    should use a real web server if you need to authenticate users."
+msgstr ""
+"    Обратите внимание, что такой сервер не подерживает права доступа.\n"
+"    Это значит, что по умолчанию кто угодно пожет читать репозитории\n"
+"    и не может писать в них. Установите параметр ``web.allow_push`` в\n"
+"    значение ``*``, чтобы разрешить всем делать push на сервер.\n"
+"    Используйте настоящий веб-сервер, если требуется аутентификация\n"
+"    пользователей."
+
+msgid ""
+"    By default, the server logs accesses to stdout and errors to\n"
+"    stderr. Use the -A/--accesslog and -E/--errorlog options to log to\n"
+"    files."
+msgstr ""
+"    По умолчанию сервер направляет лог входящих соединений в stdout,\n"
+"    а лог ошибок - в stderr. Используйте -A/--accesslog и -E/--errlog\n"
+"    для записи логов в файлы."
+
+msgid ""
+"    To have the server choose a free port number to listen on, specify\n"
+"    a port number of 0; in this case, the server will print the port\n"
+"    number it uses."
+msgstr ""
+"    Сервер сам выберет свободный порт для входящих соединений, если\n"
+"    указать 0 в качестве номера входящего порта; в этом случае он\n"
+"    напечатает выбранный порт."
+
+msgid "There is no Mercurial repository here (.hg not found)"
+msgstr "Здесь нет репозитория Mercurial (.hg не обнаружен)"
+
+#, fuzzy, python-format
+msgid "listening at http://%s%s/%s (bound to %s:%d)\n"
+msgstr "слушаю по адресу http://%s%s/%s (привязан к %s:%d)\n"
+
+msgid "show untrusted configuration options"
+msgstr "показать недоверенные настройки конфига"
+
+msgid "[-u] [NAME]..."
+msgstr "[-u] [ИМЯ]..."
+
+msgid "show combined config settings from all hgrc files"
+msgstr "показать совмещенные настройки из всех файлов конфигурации"
+
+msgid "    With no arguments, print names and values of all config items."
+msgstr "    Без аргументов печатает имена и значения всех парматров конфига."
+
+msgid ""
+"    With one argument of the form section.name, print just the value\n"
+"    of that config item."
+msgstr ""
+"    С одним аргументом вида \"секция.имя\" печатает только значение\n"
+"    этого параметра."
+
+msgid ""
+"    With multiple arguments, print names and values of all config\n"
+"    items with matching section names."
+msgstr ""
+"    С несколькими аргументами печатает имена и значения всех\n"
+"    параметров конфига с совпадающими именами разделов."
+
+msgid ""
+"    With --debug, the source (filename and line number) is printed\n"
+"    for each config item."
+msgstr ""
+"    Если указан --debug, для каждого параметра печатается имя файла\n"
+"    и номер строки, откуда он был прочитан."
+
+#, python-format
+msgid "read config from: %s\n"
+msgstr "читаю конфиг из: %s\n"
+
+msgid "only one config item permitted"
+msgstr "можно указать только один парметр конфига"
+
+msgid "show status of all files"
+msgstr "показать состояние всех файлов"
+
+msgid "show only modified files"
+msgstr "показать только измененные файлы"
+
+msgid "show only added files"
+msgstr "показать только добавленные файлы"
+
+msgid "show only removed files"
+msgstr "показать только удаленные файлы"
+
+msgid "show only deleted (but tracked) files"
+msgstr "показать только удаленные (но контролируемые) файлы"
+
+msgid "show only files without changes"
+msgstr "показать только неизмененные файлы"
+
+msgid "show only unknown (not tracked) files"
+msgstr "показать только неизвестные (не отслежиываемые) файлы"
+
+msgid "show only ignored files"
+msgstr "показать только игнорируемые файлы"
+
+msgid "show source of copied files"
+msgstr "показать источник скопированного файла"
+
+msgid "show difference from revision"
+msgstr "показать отличия от ревии"
+
+msgid "list the changed files of a revision"
+msgstr "показать измененные файлы с момента ревизии"
+
+msgid "show changed files in the working directory"
+msgstr "показать измененные файлы в рабочем каталоге"
+
+msgid ""
+"    Show status of files in the repository. If names are given, only\n"
+"    files that match are shown. Files that are clean or ignored or\n"
+"    the source of a copy/move operation, are not listed unless\n"
+"    -c/--clean, -i/--ignored, -C/--copies or -A/--all are given.\n"
+"    Unless options described with \"show only ...\" are given, the\n"
+"    options -mardu are used."
+msgstr ""
+"    Показывает статус файлов в репозитории. Если заданы имена файлов,\n"
+"    пеатает состояния только для подходящих файлов. Файлы без\n"
+"    изменений, а также игнорируемые файлы и исходные файлы \n"
+"    скопированных/переименованных файлов не печатаются, если не\n"
+"    задан -c/--clean, -i/--ignored, -C/--copies или -A/-all.\n"
+"    По умолчанию, если не задан ни один из параметром с действием\n"
+"    \"показывать только...\", используется набор опций -mardu."
+
+msgid ""
+"    Option -q/--quiet hides untracked (unknown and ignored) files\n"
+"    unless explicitly requested with -u/--unknown or -i/--ignored."
+msgstr ""
+"    Опция -q/-quite прячет неотслеживаемые (неизвестные и игнорируемые)\n"
+"    файлы, если явно на заданы -u/--unknown или -i/--ignored."
+
+msgid ""
+"    .. note::\n"
+"       status may appear to disagree with diff if permissions have\n"
+"       changed or a merge has occurred. The standard diff format does\n"
+"       not report permission changes and diff only reports changes\n"
+"       relative to one merge parent."
+msgstr ""
+"    .. note::\n"
+"       состояния могут не совпадать с diff'ом, если изменились\n"
+"       права доступа или произошло слияние. Стандартный формат diff\n"
+"       не показывает изменения прав доступа и показывает только\n"
+"       изменения относительно одной родительской ревизии."
+
+msgid ""
+"    If one revision is given, it is used as the base revision.\n"
+"    If two revisions are given, the differences between them are\n"
+"    shown. The --change option can also be used as a shortcut to list\n"
+"    the changed files of a revision from its first parent."
+msgstr ""
+"    Если задана одна ревизия, она используется в качестве базовой.\n"
+"    Если заданы две ревизии, показываются отличия между ними. Можно\n"
+"    использовать --change чтобы вывести только изменные файлы в\n"
+"    в ревизии по сравнению с ее первоым родителем."
+
+msgid "    The codes used to show the status of files are::"
+msgstr "    Испльзуются следующие коды состояний файлов::"
+
+msgid ""
+"      M = modified\n"
+"      A = added\n"
+"      R = removed\n"
+"      C = clean\n"
+"      ! = missing (deleted by non-hg command, but still tracked)\n"
+"      ? = not tracked\n"
+"      I = ignored\n"
+"        = origin of the previous file listed as A (added)"
+msgstr ""
+"      M = изменен (modified\n"
+"      A = добавлен (added)\n"
+"      R = удален (removed)\n"
+"      C = без изменений (clean)\n"
+"      ! = отсутствует (missing) (удален внешней командой, отслеживается)\n"
+"      ? = не отслеживается not tracked\n"
+"      I = игнорируется (ignored)\n"
+"        = источник предыдущего файла показанного как A (добавлен)"
+
+msgid "check for push and pull"
+msgstr "проверить наличие входящих и исходящих изменений"
+
+msgid "summarize working directory state"
+msgstr "показать сводку состояния рабочего каталога"
+
+msgid ""
+"    This generates a brief summary of the working directory state,\n"
+"    including parents, branch, commit status, and available updates."
+msgstr ""
+"    Показывает краткую сводку состояния рабочего каталога, включая\n"
+"    информацию о родителях, ветви, незакоммиченных файлах и доступных\n"
+"    обновлениях."
+
+msgid ""
+"    With the --remote option, this will check the default paths for\n"
+"    incoming and outgoing changes. This can be time-consuming."
+msgstr ""
+"    С опцией --remote также проверяет пути по умолчанию на наличие\n"
+"    входящих и исходящих изменений. Это может занять много времени."
+
+#, python-format
+msgid "parent: %d:%s "
+msgstr "родитель: %d:%s"
+
+msgid " (empty repository)"
+msgstr " (пустой репозиторий)"
+
+msgid " (no revision checked out)"
+msgstr " (нет извлеченной ревизии)"
+
+#, python-format
+msgid "branch: %s\n"
+msgstr "ветвь: %s\n"
+
+#, python-format
+msgid "%d modified"
+msgstr "%d изменено"
+
+#, python-format
+msgid "%d added"
+msgstr "%d добавлено"
+
+#, fuzzy, python-format
+msgid "%d removed"
+msgstr "%d удалено"
+
+#, python-format
+msgid "%d renamed"
+msgstr "%d переименовано"
+
+#, python-format
+msgid "%d copied"
+msgstr "%d скопировано"
+
+#, fuzzy, python-format
+msgid "%d deleted"
+msgstr "%d удалено"
+
+#, python-format
+msgid "%d unknown"
+msgstr "%d неизвестных"
+
+#, python-format
+msgid "%d ignored"
+msgstr "%d игнорируется"
+
+#, python-format
+msgid "%d unresolved"
+msgstr "%d с неразрешенными конфликтами"
+
+#, fuzzy, python-format
+msgid "%d subrepos"
+msgstr "%d субрепозиториев"
+
+msgid " (merge)"
+msgstr " (слияние)"
+
+msgid " (new branch)"
+msgstr " (новая ветвь)"
+
+msgid " (head closed)"
+msgstr " (голова закрыта)"
+
+msgid " (clean)"
+msgstr " (без изменений)"
+
+msgid " (new branch head)"
+msgstr " (новая голова ветви)"
+
+#, python-format
+msgid "commit: %s\n"
+msgstr " коммит: %s\n"
+
+#, fuzzy
+msgid "update: (current)\n"
+msgstr "обновление: (текущее)\n"
+
+#, fuzzy, python-format
+msgid "update: %d new changesets (update)\n"
+msgstr "обновление: %d новых наборов изменений (обновление)\n"
+
+#, fuzzy, python-format
+msgid "update: %d new changesets, %d branch heads (merge)\n"
+msgstr "обновление: %d новых наборов изменений, %d голов (слияние)\n"
+
+msgid "1 or more incoming"
+msgstr "1 или более входящих"
+
+#, python-format
+msgid "%d outgoing"
+msgstr "%d исходящих"
+
+#, python-format
+msgid "%d incoming bookmarks"
+msgstr "%d исходящих закладок"
+
+#, python-format
+msgid "%d outgoing bookmarks"
+msgstr "%d исходящих закладок"
+
+#, python-format
+msgid "remote: %s\n"
+msgstr "удаленный репозиторий: %s\n"
+
+msgid "remote: (synced)\n"
+msgstr "удаленный репозиторий: (синхронизирован)\n"
+
+msgid "force tag"
+msgstr "установить метку принудительно"
+
+msgid "make the tag local"
+msgstr "создать локальную метку"
+
+msgid "revision to tag"
+msgstr "пометить указанную ревизию"
+
+msgid "remove a tag"
+msgstr "уадалить метку"
+
+msgid "use <text> as commit message"
+msgstr "использовать <текст> в качестве сообщения коммита"
+
+msgid "[-f] [-l] [-m TEXT] [-d DATE] [-u USER] [-r REV] NAME..."
+msgstr "[-f] [-l] [-m ТЕКСТ] [-d ДАТА] [-u ПОЛЬЗОВАТЕЛЬ] [-r РЕВ] ИМЯ..."
+
+msgid "add one or more tags for the current or given revision"
+msgstr "присвоить одну или более метку текущей или заданной ревизии"
+
+msgid "    Name a particular revision using <name>."
+msgstr "    Присваивает <имя> заданной ревизии"
+
+msgid ""
+"    Tags are used to name particular revisions of the repository and are\n"
+"    very useful to compare different revisions, to go back to significant\n"
+"    earlier versions or to mark branch points as releases, etc. Changing\n"
+"    an existing tag is normally disallowed; use -f/--force to override."
+msgstr ""
+"    Метки используются в качестве читаемого имени для некоторой ревизии\n"
+"    и очень полезны, например, чтобы сравнить две различные ревизии,\n"
+"    вернуться к важной более ранней версии, чтобы пометить какие-то\n"
+"    ревизии как релизы и т.д. изменение существующих меток обычно\n"
+"    не разрешается; это ограничение можно обойти с помощью -f/--force."
+
+msgid ""
+"    If no revision is given, the parent of the working directory is\n"
+"    used, or tip if no revision is checked out."
+msgstr ""
+"    Если ревизия не указана, используется родитель рабочего каталога\n"
+"    или оконечная ревизия (tip), если рабочая копия не извлечена."
+
+msgid ""
+"    To facilitate version control, distribution, and merging of tags,\n"
+"    they are stored as a file named \".hgtags\" which is managed similarly\n"
+"    to other project files and can be hand-edited if necessary. This\n"
+"    also means that tagging creates a new commit. The file\n"
+"    \".hg/localtags\" is used for local tags (not shared among\n"
+"    repositories)."
+msgstr ""
+"    Чтобы упростить контроль версий, распространение и слияние меток,\n"
+"    они хранятся в файле \".hgtags\", который обрабатывается так же,\n"
+"    как и любой файл в проекте и при необходимости может правиться\n"
+"    вручную. Это означает, что созднание или изменение метки создает\n"
+"    также и новый коммит. Файл \".hg/localtags\" используется для\n"
+"    локальных меток и не передается между репозиториями."
+
+msgid ""
+"    Tag commits are usually made at the head of a branch. If the parent\n"
+"    of the working directory is not a branch head, :hg:`tag` aborts; use\n"
+"    -f/--force to force the tag commit to be based on a non-head\n"
+"    changeset."
+msgstr ""
+"    Обычно коммиты, связанные с метками, создаются на голове ветви.\n"
+"    Если родительская ревизия рабочего каталоа не является головой\n"
+"    ветви, :hg:`tag` не срабатывает. В этом случает можно использовать\n"
+"    -f/-force чтобы принудительно создать коммит для метки на не\n"
+"    головной ревизии."
+
+msgid ""
+"    Since tag names have priority over branch names during revision\n"
+"    lookup, using an existing branch name as a tag name is discouraged."
+msgstr ""
+"    Поскольку имя метки имеет больший приоритерт при поиске ревизии\n"
+"    чем имя ветви, настоятельно не рекомендуется использовать имя\n"
+"    существующей ветви в качестве имени метки."
+
+msgid "tag names must be unique"
+msgstr "имя метки должно быть уникальным"
+
+msgid "tag names cannot consist entirely of whitespace"
+msgstr "имя метки не может состоять из одних пробельных символов"
+
+msgid "--rev and --remove are incompatible"
+msgstr "нельзя одновременно использовать --rev и --remove"
+
+#, python-format
+msgid "tag '%s' does not exist"
+msgstr "метка '%s' не существует"
+
+#, python-format
+msgid "tag '%s' is not a global tag"
+msgstr "метка '%s' не является глобальной"
+
+#, python-format
+msgid "tag '%s' is not a local tag"
+msgstr "метка '%s' не является локальной"
+
+#, python-format
+msgid "tag '%s' already exists (use -f to force)"
+msgstr "метка '%s' уже сущестует (-f - задать принудительно)"
+
+msgid "uncommitted merge"
+msgstr "незакоммиченное слияние"
+
+msgid "not at a branch head (use -f to force)"
+msgstr "не на голове ветви (-f - установить принудительно)"
+
+msgid "list repository tags"
+msgstr "перечислить метки в репозитории"
+
+msgid ""
+"    This lists both regular and local tags. When the -v/--verbose\n"
+"    switch is used, a third column \"local\" is printed for local tags."
+msgstr ""
+"    Печатает обычные и локальные метки. Если указан -v/--verbose\n"
+"    для локальных меток добавляется третий столбец \"local\"."
+
+msgid "[-p] [-g]"
+msgstr "[-p] [-g]"
+
+msgid "show the tip revision"
+msgstr "показать оконечную (tip) ревизию"
+
+msgid ""
+"    The tip revision (usually just called the tip) is the changeset\n"
+"    most recently added to the repository (and therefore the most\n"
+"    recently changed head)."
+msgstr ""
+"    Оконечная ревизия (tip) - это набор последний добавленный в\n"
+"    репозиторий набор изменений (и следовательно последняя\n"
+"    измененная головная ревизия)."
+
+msgid ""
+"    If you have just made a commit, that commit will be the tip. If\n"
+"    you have just pulled changes from another repository, the tip of\n"
+"    that repository becomes the current tip. The \"tip\" tag is special\n"
+"    and cannot be renamed or assigned to a different changeset."
+msgstr ""
+"    Если вы только что сделали коммит, этот коммит и будет tip'ом.\n"
+"    Если вы только что подтянули изменения из другого репозитория,\n"
+"    tip этого репозитория станет текущим tip'ом. Метка \"tip\"\n"
+"    является служебной и не может быть переименована или назначена\n"
+"    другой ревизии."
+
+msgid "update to new branch head if changesets were unbundled"
+msgstr "обновиться на новую голову ветви, если были добавлены наборы изменений"
+
+msgid "[-u] FILE..."
+msgstr "[-u] ФАЙЛ..."
+
+msgid "apply one or more changegroup files"
+msgstr "применить один или несколько файлов групп изменений"
+
+msgid ""
+"    Apply one or more compressed changegroup files generated by the\n"
+"    bundle command."
+msgstr ""
+"    Применяет один или несколько сжатых файлов групп изменений,\n"
+"    сгенерированных командой bundle."
+
+msgid ""
+"    Returns 0 on success, 1 if an update has unresolved files.\n"
+"    "
+msgstr ""
+"    При успехе возвращает 0, 1 если при обновлении остались конфликты "
+"слияния.\n"
+"    "
+
+msgid "discard uncommitted changes (no backup)"
+msgstr "затереть незакоммиченные изменения (без бэкапа)"
+
+msgid "update across branches if no uncommitted changes"
+msgstr "обновиться на другую ветвь если нет незакоммиченных изменений"
+
+msgid "[-c] [-C] [-d DATE] [[-r] REV]"
+msgstr "[-c] [-C] [-d ДАТА] [[-r] РЕВИЗИЯ]"
+
+msgid "update working directory (or switch revisions)"
+msgstr "обновить рабочий каталог (или переключить ревизию)"
+
+msgid ""
+"    Update the repository's working directory to the specified\n"
+"    changeset. If no changeset is specified, update to the tip of the\n"
+"    current named branch."
+msgstr ""
+"    Обновляет рабочую копию репозитория до указанную ревизию. Если\n"
+"    ревизия не задана, обновляет до оконечной ревизии (tip) текущей\n"
+"    именованной ветви."
+
+msgid ""
+"    If the changeset is not a descendant of the working directory's\n"
+"    parent, the update is aborted. With the -c/--check option, the\n"
+"    working directory is checked for uncommitted changes; if none are\n"
+"    found, the working directory is updated to the specified\n"
+"    changeset."
+msgstr ""
+"    Если РЕВИЗИЯ - не потомок родителя рабочего каталога, update\n"
+"    завершается с ошибкой. С опцией -c/--check рабочий каталог\n"
+"    проверяется на наличие незакоммиченных изменений; если таковых\n"
+"    нет, раочий каталог обновляется до указанной ревизии."
+
+msgid ""
+"    The following rules apply when the working directory contains\n"
+"    uncommitted changes:"
+msgstr ""
+"    Если рабочий каталог содержит незакоммиченные изменения,\n"
+"    применяются следующие правила:"
+
+msgid ""
+"    1. If neither -c/--check nor -C/--clean is specified, and if\n"
+"       the requested changeset is an ancestor or descendant of\n"
+"       the working directory's parent, the uncommitted changes\n"
+"       are merged into the requested changeset and the merged\n"
+"       result is left uncommitted. If the requested changeset is\n"
+"       not an ancestor or descendant (that is, it is on another\n"
+"       branch), the update is aborted and the uncommitted changes\n"
+"       are preserved."
+msgstr ""
+"    1. Если не указаны ни -c/--check, ни -C/--clean и если заданная\n"
+"       ревизия является предком или потомком родителя рабочего\n"
+"       каталога, незакоммиченные изменения сливаются в заданную\n"
+"       ревизию и результат слияния остается незакоммиченным. Если\n"
+"       заданная ревизия не предок и не потомок (т.е. на другой ветке)\n"
+"       update завершается с ошибкой, незакоммиченные изменения\n"
+"       сохраняются."
+
+msgid ""
+"    2. With the -c/--check option, the update is aborted and the\n"
+"       uncommitted changes are preserved."
+msgstr ""
+"    2. С опцией -c/--check update завершается с ошибкой и\n"
+"       незакоммиченные изменения сохраняются."
+
+msgid ""
+"    3. With the -C/--clean option, uncommitted changes are discarded and\n"
+"       the working directory is updated to the requested changeset."
+msgstr ""
+"    3. С опцией -C/--clean незакоммиченные изменения отбрасываются\n"
+"       и рабочий каталог обновляется до указанной ревизии."
+
+msgid ""
+"    Use null as the changeset to remove the working directory (like\n"
+"    :hg:`clone -U`)."
+msgstr ""
+"    Используйте ревизию с именем null чтобы удалить рабочий каталог\n"
+"    (как :hg:`clone -U`)."
+
+msgid ""
+"    If you want to update just one file to an older changeset, use\n"
+"    :hg:`revert`."
+msgstr ""
+"    Если вы хотите просто обновить один файл до состяния в более\n"
+"    ревизии, используйте :hg:`revert`."
+
+msgid "cannot specify both -c/--check and -C/--clean"
+msgstr "нельзя одновременно указывать -c/--check и -C/-clean"
+
+msgid "uncommitted local changes"
+msgstr "незакоммиченные локальные изменения"
+
+msgid "verify the integrity of the repository"
+msgstr "проверить целостность репозитория"
+
+msgid "    Verify the integrity of the current repository."
+msgstr "    Проверяет целостность текущего репозитория."
+
+msgid ""
+"    This will perform an extensive check of the repository's\n"
+"    integrity, validating the hashes and checksums of each entry in\n"
+"    the changelog, manifest, and tracked files, as well as the\n"
+"    integrity of their crosslinks and indices."
+msgstr ""
+"    Эта команда проводит тщательную проверку целостности репозитория\n"
+"    сверяя хэши и контрольные суммы каждого элемента в журнале\n"
+"    изменений, манифесте и отслеживаемых файлах, а также целостность\n"
+"    их взаимосвязей и индексов."
+
+msgid "output version and copyright information"
+msgstr "показать версию и копирайт"
+
+#, python-format
+msgid "Mercurial Distributed SCM (version %s)\n"
+msgstr "Распределенная SCM Mercurial (версия %s)\n"
+
+msgid "(see http://mercurial.selenic.com for more information)"
+msgstr "(подробнее см. http://mercurial.selenic.com)"
+
+#, fuzzy
+msgid ""
+"Copyright (C) 2005-2011 Matt Mackall and others\n"
+"This is free software; see the source for copying conditions. There is NO\n"
+"warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
+msgstr ""
+"(С) 2005-2011 Matt Mackall и другие\n"
+"Mercurial - свободное ПО; см. исходники об условиях распространения.\n"
+"НЕ предоставляются НИКАКИЕ гарантии, т.ч. ПРИГОДНОСТИ ДЛЯ ПРОДАЖИ или\n"
+"КАКОЙ-ЛИБО ДРУГОЙ ЦЕЛИ."
+
+#, python-format
+msgid "cannot include %s (%s)"
+msgstr ""
+
+msgid "not found in manifest"
+msgstr ""
+
+#, python-format
+msgid "no such file in rev %s"
+msgstr ""
+
+msgid "branch name not in UTF-8!"
+msgstr ""
+
+#, python-format
+msgid "%s does not exist!\n"
+msgstr ""
+
+#, python-format
+msgid ""
+"%s: up to %d MB of RAM may be required to manage this file\n"
+"(use 'hg revert %s' to cancel the pending addition)\n"
+msgstr ""
+
+#, python-format
+msgid "%s not added: only files and symlinks supported currently\n"
+msgstr ""
+
+#, python-format
+msgid "%s already tracked!\n"
+msgstr ""
+
+#, python-format
+msgid "%s not added!\n"
+msgstr ""
+
+#, fuzzy, python-format
+msgid "%s still exists!\n"
+msgstr "файл %s уже существует\n"
+
+#, python-format
+msgid "%s not tracked!\n"
+msgstr ""
+
+#, python-format
+msgid "%s not removed!\n"
+msgstr ""
+
+#, python-format
+msgid "copy failed: %s is not a file or a symbolic link\n"
+msgstr ""
+
+#, python-format
+msgid "invalid character in dag description: %s..."
+msgstr ""
+
+#, python-format
+msgid "expected id %i, got %i"
+msgstr ""
+
+#, python-format
+msgid "parent id %i is larger than current id %i"
+msgstr ""
+
+#, python-format
+msgid "invalid event type in dag: %s"
+msgstr ""
+
+msgid "nullid"
+msgstr ""
+
+msgid "working directory state appears damaged!"
+msgstr ""
+
+#, python-format
+msgid "directory %r already in dirstate"
+msgstr ""
+
+#, python-format
+msgid "file %r in dirstate clashes with %r"
+msgstr ""
+
+#, python-format
+msgid "setting %r to other parent only allowed in merges"
+msgstr ""
+
+#, fuzzy, python-format
+msgid "not in dirstate: %s\n"
+msgstr "не обновлено: %s\n"
+
+msgid "unknown"
+msgstr "неизвесно"
+
+msgid "character device"
+msgstr ""
+
+msgid "block device"
+msgstr ""
+
+msgid "fifo"
+msgstr ""
+
+msgid "socket"
+msgstr ""
+
+msgid "directory"
+msgstr ""
+
+#, python-format
+msgid "unsupported file type (type is %s)"
+msgstr ""
+
+#, python-format
+msgid "push creates new remote branches: %s!"
+msgstr ""
+
+msgid "use 'hg push --new-branch' to create new remote branches"
+msgstr ""
+
+#, python-format
+msgid "push creates new remote heads on branch '%s'!"
+msgstr ""
+
+msgid "push creates new remote heads!"
+msgstr ""
+
+msgid "you should pull and merge or use push -f to force"
+msgstr ""
+
+msgid "did you forget to merge? use push -f to force"
+msgstr ""
+
+msgid "note: unsynced remote changes!\n"
+msgstr ""
+
+#, python-format
+msgid "abort: %s\n"
+msgstr ""
+
+#, python-format
+msgid "(%s)\n"
+msgstr ""
+
+#, python-format
+msgid "hg: parse error at %s: %s\n"
+msgstr ""
+
+#, python-format
+msgid "hg: parse error: %s\n"
+msgstr ""
+
+msgid "entering debugger - type c to continue starting hg or h for help\n"
+msgstr ""
+
+#, python-format
+msgid ""
+"hg: command '%s' is ambiguous:\n"
+"    %s\n"
+msgstr ""
+
+#, python-format
+msgid "timed out waiting for lock held by %s"
+msgstr ""
+
+#, python-format
+msgid "lock held by %s"
+msgstr ""
+
+#, python-format
+msgid "abort: %s: %s\n"
+msgstr ""
+
+#, python-format
+msgid "abort: could not lock %s: %s\n"
+msgstr ""
+
+#, python-format
+msgid "hg %s: %s\n"
+msgstr ""
+
+#, python-format
+msgid "hg: %s\n"
+msgstr ""
+
+#, python-format
+msgid "abort: %s!\n"
+msgstr "прервано: %s!\n"
+
+#, python-format
+msgid "abort: %s"
+msgstr ""
+
+msgid " empty string\n"
+msgstr ""
+
+msgid "killed!\n"
+msgstr ""
+
+#, python-format
+msgid "hg: unknown command '%s'\n"
+msgstr ""
+
+msgid "(did you forget to compile extensions?)\n"
+msgstr ""
+
+msgid "(is your Python install correct?)\n"
+msgstr ""
+
+#, python-format
+msgid "abort: error: %s\n"
+msgstr ""
+
+msgid "broken pipe\n"
+msgstr ""
+
+msgid "interrupted!\n"
+msgstr ""
+
+msgid ""
+"\n"
+"broken pipe\n"
+msgstr ""
+
+msgid "abort: out of memory\n"
+msgstr ""
+
+msgid "** unknown exception encountered, please report by visiting\n"
+msgstr ""
+
+msgid "**  http://mercurial.selenic.com/wiki/BugTracker\n"
+msgstr ""
+
+#, python-format
+msgid "** Python %s\n"
+msgstr ""
+
+#, python-format
+msgid "** Mercurial Distributed SCM (version %s)\n"
+msgstr ""
+
+#, python-format
+msgid "** Extensions loaded: %s\n"
+msgstr ""
+
+#, python-format
+msgid "no definition for alias '%s'\n"
+msgstr ""
+
+#, python-format
+msgid ""
+"No argument found for substitution of %i variable in alias '%s' definition."
+msgstr ""
+
+#, python-format
+msgid ""
+"error in definition for alias '%s': %s may only be given on the command "
+"line\n"
+msgstr ""
+
+#, python-format
+msgid "alias '%s' resolves to unknown command '%s'\n"
+msgstr ""
+
+#, python-format
+msgid "alias '%s' resolves to ambiguous command '%s'\n"
+msgstr ""
+
+#, python-format
+msgid "malformed --config option: %r (use --config section.name=value)"
+msgstr ""
+
+#, python-format
+msgid "error getting current working directory: %s"
+msgstr ""
+
+#, python-format
+msgid "extension '%s' overrides commands: %s\n"
+msgstr "расширение '%s' переопределяет команды: %s\n"
+
+msgid "option --config may not be abbreviated!"
+msgstr ""
+
+msgid "option --cwd may not be abbreviated!"
+msgstr ""
+
+msgid ""
+"Option -R has to be separated from other options (e.g. not -qR) and --"
+"repository may only be abbreviated as --repo!"
+msgstr ""
+
+#, python-format
+msgid "Time: real %.3f secs (user %.3f+%.3f sys %.3f+%.3f)\n"
+msgstr ""
+
+#, python-format
+msgid "repository '%s' is not local"
+msgstr "репозиторий '%s' не локальный"
+
+#, python-format
+msgid "no repository found in %r (.hg not found)"
+msgstr ""
+
+msgid "warning: --repository ignored\n"
+msgstr ""
+
+#, python-format
+msgid "unrecognized profiling format '%s' - Ignored\n"
+msgstr "неопознаный формат профилирования '%s' - Игнорирован\n"
+
+msgid ""
+"lsprof not available - install from http://codespeak.net/svn/user/arigo/hack/"
+"misc/lsprof/"
+msgstr ""
+"lsprof не доступен - установите с http://codespeak.net/svn/user/arigo/hack/"
+"misc/lsprof/"
+
+#, python-format
+msgid "*** failed to import extension %s from %s: %s\n"
+msgstr ""
+
+#, python-format
+msgid "*** failed to import extension %s: %s\n"
+msgstr ""
+
+#, python-format
+msgid "warning: error finding commands in %s\n"
+msgstr ""
+
+#, python-format
+msgid "couldn't find merge tool %s\n"
+msgstr ""
+
+#, python-format
+msgid "tool %s can't handle symlinks\n"
+msgstr ""
+
+#, python-format
+msgid "tool %s can't handle binary\n"
+msgstr ""
+
+#, python-format
+msgid "tool %s requires a GUI\n"
+msgstr ""
+
+#, python-format
+msgid ""
+" no tool found to merge %s\n"
+"keep (l)ocal or take (o)ther?"
+msgstr ""
+
+msgid "&Local"
+msgstr "&Локальные"
+
+msgid "&Other"
+msgstr "&Другие"
+
+#, python-format
+msgid "merging %s and %s to %s\n"
+msgstr ""
+
+#, python-format
+msgid "merging %s\n"
+msgstr ""
+
+#, python-format
+msgid "%s.premerge not valid ('%s' is neither boolean nor %s)"
+msgstr ""
+
+#, python-format
+msgid "was merge of '%s' successful (yn)?"
+msgstr ""
+
+#, python-format
+msgid ""
+" output file %s appears unchanged\n"
+"was merge successful (yn)?"
+msgstr ""
+
+#, python-format
+msgid "merging %s failed!\n"
+msgstr ""
+
+msgid "starting revisions are not directly related"
+msgstr ""
+
+#, python-format
+msgid "inconsistent state, %s:%s is good and bad"
+msgstr ""
+
+#, python-format
+msgid "unknown bisect kind %s"
+msgstr ""
+
+msgid "disabled extensions:"
+msgstr "отключенные расширения:"
+
+msgid "Configuration Files"
+msgstr "Файлы конфигурации"
+
+msgid "Date Formats"
+msgstr "Форматы дат"
+
+msgid "File Name Patterns"
+msgstr "Шаблоны имен файлов"
+
+msgid "Environment Variables"
+msgstr "Переменные окружения"
+
+msgid "Specifying Single Revisions"
+msgstr "Задание одной ревизии"
+
+msgid "Specifying Multiple Revisions"
+msgstr "Задание нескольких ревизий"
+
+msgid "Specifying Revision Sets"
+msgstr "Задание набора ревизий"
+
+msgid "Diff Formats"
+msgstr "Форматы diff'ов"
+
+msgid "Merge Tools"
+msgstr "Инструменты для слияния"
+
+msgid "Template Usage"
+msgstr "Использование шаблонов"
+
+msgid "URL Paths"
+msgstr "URL путей"
+
+msgid "Using additional features"
+msgstr "Использвание дополнительных возможностей"
+
+msgid "Subrepositories"
+msgstr "Субрепозитории"
+
+msgid "Configuring hgweb"
+msgstr "Настройка hgweb"
+
+msgid "Glossary"
+msgstr "Глоссарий"
+
+msgid "syntax for Mercurial ignore files"
+msgstr "синтаксис файлов игнорирования Mercurial"
+
+msgid ""
+"Mercurial reads configuration data from several files, if they exist.\n"
+"Below we list the most specific file first."
+msgstr ""
+"Mercurial читает настройки из нескольких файлов, если они существуют.\n"
+"Ниже приведен их список, начиная с наиболее характерных."
+
+msgid "On Windows, these configuration files are read:"
+msgstr "В Windows используются эти файлы:"
+
+msgid ""
+"- ``<repo>\\.hg\\hgrc``\n"
+"- ``%USERPROFILE%\\.hgrc``\n"
+"- ``%USERPROFILE%\\mercurial.ini``\n"
+"- ``%HOME%\\.hgrc``\n"
+"- ``%HOME%\\mercurial.ini``\n"
+"- ``C:\\mercurial\\mercurial.ini`` (unless regkey or hgrc.d\\ or mercurial."
+"ini found)\n"
+"- ``HKEY_LOCAL_MACHINE\\SOFTWARE\\Mercurial`` (unless hgrc.d\\ or mercurial."
+"ini found)\n"
+"- ``<hg.exe-dir>\\hgrc.d\\*.rc`` (unless mercurial.ini found)\n"
+"- ``<hg.exe-dir>\\mercurial.ini``"
+msgstr ""
+"- ``<репозиторий>\\.hg\\hgrc``\n"
+"- ``%USERPROFILE%\\.hgrc``\n"
+"- ``%USERPROFILE%\\mercurial.ini``\n"
+"- ``%HOME%\\.hgrc``\n"
+"- ``%HOME%\\mercurial.ini``\n"
+"- ``C:\\mercurial\\mercurial.ini`` (если не найден ключ в реестре илиhgrc.d"
+"\\)\n"
+"- ``HKEY_LOCAL_MACHINE\\SOFTWARE\\Mercurial`` (если не найден hgrc.d\\или "
+"mercurial.ini)\n"
+"- ``<каталог-с-hg.exe>\\hgrc.d\\*.rc`` (если не найден mercurial.ini)\n"
+"- ``<каталог-с-hg.exe>\\mercurial.ini``"
+
+msgid "On Unix, these files are read:"
+msgstr "В Unix используются эти файлы:"
+
+msgid ""
+"- ``<репозиторий>/.hg/hgrc``\n"
+"- ``$HOME/.hgrc``\n"
+"- ``/etc/mercurial/hgrc``\n"
+"- ``/etc/mercurial/hgrc.d/*.rc``\n"
+"- ``<корень-установки>/etc/mercurial/hgrc``\n"
+"- ``<корень-установки>/etc/mercurial/hgrc.d/*.rc``"
+msgstr ""
+
+msgid ""
+"These files do not exist by default and you will have to create the\n"
+"appropriate configuration files yourself: global configuration like\n"
+"the username setting is typically put into\n"
+"``%USERPROFILE%\\mercurial.ini`` or ``$HOME/.hgrc`` and local\n"
+"configuration is put into the per-repository ``<repo>/.hg/hgrc`` file."
+msgstr ""
+"По умолчанию эти файлы не существуют, и вам надо создать нужные файлы\n"
+"самостоятельно: глобальные настройки, вроде имени пользователя, обычно\n"
+"помещают в ``%USERPROFILE%\\mercurial.ini`` или ``$HOME/.hgrc``, а\n"
+"локальные настройки хранятся для каждого репозитория в файле\n"
+"``<репозиторий>/.hg/hgrc``\n"
+"."
+
+msgid ""
+"If there is a per-repository configuration file which is not owned by\n"
+"the active user, Mercurial will warn you that the file is skipped::"
+msgstr ""
+"Если владелец файла настроек в репозитории - не текущий пользователь,\n"
+"Mercurial предупреждает о том, что этот файл не будет использован::"
+
+msgid ""
+"  not trusting file <repo>/.hg/hgrc from untrusted user USER, group GROUP"
+msgstr ""
+"  не доверяю файлу <репозиторий>/.hg/hgrc от недоверенного пользователя\n"
+"  ПОЛЬЗОВАТЕЛЬ в группе ГРУППА"
+
+msgid ""
+"If this bothers you, the warning can be silenced (the file would still\n"
+"be ignored) or trust can be established. Use one of the following\n"
+"settings, the syntax is explained below:"
+msgstr ""
+"Если это вас раздражает, можно отключить предупреждение (файл все равно\n"
+"игнорируется), или начать доверять пользователю. Для этого используйте\n"
+"следующие настройки, синтаксис которых описан далее:"
+
+msgid ""
+"- ``ui.report_untrusted = False``\n"
+"- ``trusted.users = USER``\n"
+"- ``trusted.groups = GROUP``"
+msgstr ""
+"- ``ui.report_untrusted = False``\n"
+"- ``trusted.users = ПОЛЬЗОВАТЕЛЬ``\n"
+"- ``trusted.groups = ГРУППА``"
+
+msgid ""
+"The configuration files for Mercurial use a simple ini-file format. A\n"
+"configuration file consists of sections, led by a ``[section]`` header\n"
+"and followed by ``name = value`` entries::"
+msgstr ""
+"Конфиги Mercurial это простые ini-файлы. Файл конфига состоит из разделов\n"
+"(секций), начинающихся с заголовка ``[секция]`` с последующими настройками\n"
+"вида ``имя = значение``::"
+
+msgid ""
+"  [ui]\n"
+"  username = Firstname Lastname <firstname.lastname@example.net>\n"
+"  verbose = True"
+msgstr ""
+"  [ui]\n"
+"  username = Имя Фамилия <имя.фамилия@example.net>\n"
+"  verbose = True"
+
+msgid ""
+"The above entries will be referred to as ``ui.username`` and\n"
+"``ui.verbose``, respectively. Please see the hgrc man page for a full\n"
+"description of the possible configuration values:"
+msgstr ""
+"Эти праметры далее будут упоминаться как ``ui.username`` и\n"
+"``ui.verbose`` соответсвенно. Полное описание возможных параметров\n"
+"конфигурации см. man hgrc:"
+
+msgid ""
+"- on Unix-like systems: ``man hgrc``\n"
+"- online: http://www.selenic.com/mercurial/hgrc.5.html\n"
+msgstr ""
+"- в Unix-подобных ОС: ``man hgrc``\n"
+"- онлайн: http://www.selenic.com/mercurial/hgrc.5.html\n"
+
+msgid "Some commands allow the user to specify a date, e.g.:"
+msgstr "Некоторые команды позволяют задать дату, например:"
+
+msgid ""
+"- backout, commit, import, tag: Specify the commit date.\n"
+"- log, revert, update: Select revision(s) by date."
+msgstr ""
+"- backout, commit, import, tag: указать дату коммита.\n"
+"- log, revert, update: выбрать ревизию(и) по дате."
+
+msgid "Many date formats are valid. Here are some examples:"
+msgstr "Возможны много форматов даты. Например:"
+
+msgid ""
+"- ``Wed Dec 6 13:18:29 2006`` (local timezone assumed)\n"
+"- ``Dec 6 13:18 -0600`` (year assumed, time offset provided)\n"
+"- ``Dec 6 13:18 UTC`` (UTC and GMT are aliases for +0000)\n"
+"- ``Dec 6`` (midnight)\n"
+"- ``13:18`` (today assumed)\n"
+"- ``3:39`` (3:39AM assumed)\n"
+"- ``3:39pm`` (15:39)\n"
+"- ``2006-12-06 13:18:29`` (ISO 8601 format)\n"
+"- ``2006-12-6 13:18``\n"
+"- ``2006-12-6``\n"
+"- ``12-6``\n"
+"- ``12/6``\n"
+"- ``12/6/6`` (Dec 6 2006)"
+msgstr ""
+"- ``Wed Dec 6 13:18:29 2006`` (предполагается местное время)\n"
+"- ``Dec 6 13:18 -0600`` (смещение относитльно начала года)\n"
+"- ``Dec 6 13:18 UTC`` (UTC и GMT это псевдонимы для +0000)\n"
+"- ``Dec 6`` (полночь)\n"
+"- ``13:18`` (сегодняшний день)\n"
+"- ``3:39`` (3:39AM)\n"
+"- ``3:39pm`` (15:39)\n"
+"- ``2006-12-06 13:18:29`` (формат ISO 8601)\n"
+"- ``2006-12-6 13:18``\n"
+"- ``2006-12-6``\n"
+"- ``12-6``\n"
+"- ``12/6``\n"
+"- ``12/6/6`` (6 декабря 2006)"
+
+msgid "Lastly, there is Mercurial's internal format:"
+msgstr "Наконец, есть внутренний формат Mercurial:"
+
+msgid "- ``1165432709 0`` (Wed Dec 6 13:18:29 2006 UTC)"
+msgstr "- ``1165432709 0`` (Среда 6 декабря 13:18:29 2006 UTC)"
+
+msgid ""
+"This is the internal representation format for dates. The first number\n"
+"is the number of seconds since the epoch (1970-01-01 00:00 UTC). The\n"
+"second is the offset of the local timezone, in seconds west of UTC\n"
+"(negative if the timezone is east of UTC)."
+msgstr ""
+"Это внутренний формат представление дат. Первое число - это количество\n"
+"секунд с начала эпохи (1970-01-01 00:00 UTC). Второе число - смещение\n"
+"текущего часового пояса, в секундах к западу от UTC (отрицательные\n"
+"числа - к востоку от UTC)."
+
+msgid "The log command also accepts date ranges:"
+msgstr "Команда log также принимает диапазоны дат:"
+
+msgid ""
+"- ``<DATE`` - at or before a given date/time\n"
+"- ``>DATE`` - on or after a given date/time\n"
+"- ``DATE to DATE`` - a date range, inclusive\n"
+"- ``-DAYS`` - within a given number of days of today\n"
+msgstr ""
+"- ``<DATE`` - до заданной даты/времени включительно\n"
+"- ``>DATE`` - после заданной даты/времени включительно\n"
+"- ``DATE to DATE`` - диапазон дат, включительно\n"
+"- ``-DAYS`` - заданное количство дней назад от сегодняшнего дня\n"
+
+msgid ""
+"Mercurial's default format for showing changes between two versions of\n"
+"a file is compatible with the unified format of GNU diff, which can be\n"
+"used by GNU patch and many other standard tools."
+msgstr ""
+"По умолчанию Mercurial показывает отличия между ревизиями файла в\n"
+"унифицированном формате GNU diff (unified diff), который может быть\n"
+"использован в GNU patch и многих других стандартных инструментах."
+
+msgid ""
+"While this standard format is often enough, it does not encode the\n"
+"following information:"
+msgstr ""
+"Хотя как правило стандартного формата достаточно, он не содержит\n"
+"следующей информации:"
+
+msgid ""
+"- executable status and other permission bits\n"
+"- copy or rename information\n"
+"- changes in binary files\n"
+"- creation or deletion of empty files"
+msgstr ""
+"- признаки исполняемого файла и биты прав доступа\n"
+"- информацию о копировании и перемещении\n"
+"- изменения в бинарных файлах\n"
+"- создание или удаление пустых файлов"
+
+msgid ""
+"Mercurial also supports the extended diff format from the git VCS\n"
+"which addresses these limitations. The git diff format is not produced\n"
+"by default because a few widespread tools still do not understand this\n"
+"format."
+msgstr ""
+"Mercurial также поддерживает расширенный формат diff VCS git, который\n"
+"исправляет эти недостатки. Этот формат не используется по умолчанию,\n"
+"потому что многие распространенные изменения его не понимают."
+
+msgid ""
+"This means that when generating diffs from a Mercurial repository\n"
+"(e.g. with :hg:`export`), you should be careful about things like file\n"
+"copies and renames or other things mentioned above, because when\n"
+"applying a standard diff to a different repository, this extra\n"
+"information is lost. Mercurial's internal operations (like push and\n"
+"pull) are not affected by this, because they use an internal binary\n"
+"format for communicating changes."
+msgstr ""
+"Это значит, что при генерировании diff'ов из репозитория Mercurial\n"
+"(например, с помощью :hg:`export`), нужно быть осторожным с такими\n"
+"вещами как копирования и переименования и другими перечиленными выше,\n"
+"потому что при применении стандартного diff'а к другому репозиторию\n"
+"эта информация теряется. На внутреннии операции Mercurial (как push\n"
+"или pull) это не влияет, потому что они используют внутренний бинарный\n"
+"формат для обмна изменениями."
+
+msgid ""
+"To make Mercurial produce the git extended diff format, use the --git\n"
+"option available for many commands, or set 'git = True' in the [diff]\n"
+"section of your configuration file. You do not need to set this option\n"
+"when importing diffs in this format or using them in the mq extension.\n"
+msgstr ""
+"Чтобы генерировать diff'ы в расширенном формате git, используйте опцию\n"
+"--git, которая доступна для многих команд, или установите 'git = True'\n"
+"в секции [diff] в вашем конфиге. Эту опцию не обязательно указыать\n"
+"при импорте diff'ов в этом формате или использовании расширения mq.\n"
+
+#, fuzzy
+msgid ""
+"HG\n"
+"    Path to the 'hg' executable, automatically passed when running\n"
+"    hooks, extensions or external tools. If unset or empty, this is\n"
+"    the hg executable's name if it's frozen, or an executable named\n"
+"    'hg' (with %PATHEXT% [defaulting to COM/EXE/BAT/CMD] extensions on\n"
+"    Windows) is searched."
+msgstr ""
+"HG\n"
+"    Путь к исполняемому файлу 'hg', передается автоматически при\n"
+"    при обработке хуков, расширений или внешних программ. Если не\n"
+"    установлена или пустая, это имя исполняемого файла hg, если\n"
+"    если оно зафиксировано, либо выполняется поиск исполняемого\n"
+"    файла 'hg' (с добавленным %PATHEXT% [по умолчанию COM/EXE/BAT/CMD]\n"
+"    в Windows)"
+
+msgid ""
+"HGEDITOR\n"
+"    This is the name of the editor to run when committing. See EDITOR."
+msgstr ""
+"HGEDITOR\n"
+"\n"
+"    Имя редактора, который запускается при коммите. См. EDITOR."
+
+msgid "    (deprecated, use configuration file)"
+msgstr "    (устарело, используйте файл конфигурации)"
+
+msgid ""
+"HGENCODING\n"
+"    This overrides the default locale setting detected by Mercurial.\n"
+"    This setting is used to convert data including usernames,\n"
+"    changeset descriptions, tag names, and branches. This setting can\n"
+"    be overridden with the --encoding command-line option."
+msgstr ""
+"HGENCODING\n"
+"    Замещает настроку кодировки в локали используемую Mercurial\n"
+"    по умолчанию. Этот параметр используется для преобразования\n"
+"    имен пользователей, описаний ревизий, имен ветвей и меток.\n"
+"    Можно переопределить эту настройку с помощью опции командной\n"
+"    строки --encoding."
+
+msgid ""
+"HGENCODINGMODE\n"
+"    This sets Mercurial's behavior for handling unknown characters\n"
+"    while transcoding user input. The default is \"strict\", which\n"
+"    causes Mercurial to abort if it can't map a character. Other\n"
+"    settings include \"replace\", which replaces unknown characters, and\n"
+"    \"ignore\", which drops them. This setting can be overridden with\n"
+"    the --encodingmode command-line option."
+msgstr ""
+"HGENCODINGMODE\n"
+"    Определяет поведение Mercurial при обработке неизвестных символов\n"
+"    при перекодировании ввода пользователя. По умолчанию установлен\n"
+"    в \"strict\", что заставляет Mercurial завершиться с ошибкой, если\n"
+"    не получается найти соответствующий символ. Возможны также значения\n"
+"    \"replace\", которое заменяет неизвестные символы, и \"ignore\",\n"
+"    которое удаляет их. Эту настройку можно переопределить с помощью\n"
+"    опции командной строки --encodingmode."
+
+msgid ""
+"HGENCODINGAMBIGUOUS\n"
+"    This sets Mercurial's behavior for handling characters with\n"
+"    \"ambiguous\" widths like accented Latin characters with East Asian\n"
+"    fonts. By default, Mercurial assumes ambiguous characters are\n"
+"    narrow, set this variable to \"wide\" if such characters cause\n"
+"    formatting problems."
+msgstr ""
+"HGENCODINGAMBIGUOUS\n"
+"    Определяет поведение Mercurial при обработке символов с\n"
+"    \"неоднозначной\" шириной, вроде латинских символов с ударением\n"
+"    в восточно-азиатских шрифтах. По умолчанию Mercurial считает\n"
+"    такие символы узкими, установите эту переменную в \"wide\",\n"
+"    если форматирование сбивается."
+
+msgid ""
+"HGMERGE\n"
+"    An executable to use for resolving merge conflicts. The program\n"
+"    will be executed with three arguments: local file, remote file,\n"
+"    ancestor file."
+msgstr ""
+"HGMERGE\n"
+"    Программа для разрешения конфликов слияния. Она будет вызвана\n"
+"    с тремя аргументами: локальный файл, удаленный файл, исходный файл."
+
+msgid ""
+"HGRCPATH\n"
+"    A list of files or directories to search for configuration\n"
+"    files. Item separator is \":\" on Unix, \";\" on Windows. If HGRCPATH\n"
+"    is not set, platform default search path is used. If empty, only\n"
+"    the .hg/hgrc from the current repository is read."
+msgstr ""
+"HGRCPATH\n"
+"    Список файлов или каталогов в которых ищутся файлы конфигурации.\n"
+"    В качестве разделителя в Unix используется \":\", в Windows - \";\".\n"
+"    Если HGRCPATH не установлена, используется путь поиска по умолчанию\n"
+"    для текущей платформы. Если переменная установлена в пустое значение,\n"
+"    то используется .hg/hgrc текущего репозитория."
+
+msgid "    For each element in HGRCPATH:"
+msgstr "    Для каждого элемента в HGRCPATH:"
+
+msgid ""
+"    - if it's a directory, all files ending with .rc are added\n"
+"    - otherwise, the file itself will be added"
+msgstr ""
+"    - если это каталог, читаются все файлы с расширением .rc\n"
+"    - в противном случае, читается сам файл"
+
+msgid ""
+"HGPLAIN\n"
+"    When set, this disables any configuration settings that might\n"
+"    change Mercurial's default output. This includes encoding,\n"
+"    defaults, verbose mode, debug mode, quiet mode, tracebacks, and\n"
+"    localization. This can be useful when scripting against Mercurial\n"
+"    in the face of existing user configuration."
+msgstr ""
+"HGPLAIN\n"
+"    Если установлена, отключает все настройки в конфиге, которые\n"
+"    могут изменить вывод Mercurial. Сюда входят кодировка, параметры\n"
+"    по умолчанию, режим verbose, отладочный режим, подавление вывода,\n"
+"    трассировки стека, локализация. Это полезно при использовании\n"
+"    Mercurial в скриптах при различных пользовательских настройках."
+
+msgid ""
+"    Equivalent options set via command line flags or environment\n"
+"    variables are not overridden."
+msgstr ""
+"    Аналогичные параметры, установленные через командную строку\n"
+"    или переменные среды не переопределяются."
+
+msgid ""
+"HGPLAINEXCEPT\n"
+"    This is a comma-separated list of features to preserve when\n"
+"    HGPLAIN is enabled. Currently the only value supported is \"i18n\",\n"
+"    which preserves internationalization in plain mode."
+msgstr ""
+"HGPLAINEXCEPT\n"
+"    Список разделенных запятой настроек, которые сохраняются при\n"
+"    установленной HGPLAIN. В настоящее время поддерживается только\n"
+"    значение \"i18n\", которое сохраняет вывод на языке локали."
+
+msgid ""
+"    Setting HGPLAINEXCEPT to anything (even an empty string) will\n"
+"    enable plain mode."
+msgstr ""
+"    Установка HGPLAINEXCEPT в любое значение (даже пустую строку)\n"
+"    включит режим HGPLAIN."
+
+msgid ""
+"HGUSER\n"
+"    This is the string used as the author of a commit. If not set,\n"
+"    available values will be considered in this order:"
+msgstr ""
+"HGUSER\n"
+"    Это строка, используемая в качестве имени автора коммита. Если\n"
+"    не установлена, используются значения в следующем порядке:"
+
+msgid ""
+"    - HGUSER (deprecated)\n"
+"    - configuration files from the HGRCPATH\n"
+"    - EMAIL\n"
+"    - interactive prompt\n"
+"    - LOGNAME (with ``@hostname`` appended)"
+msgstr ""
+"    - HGUSER (устарело)\n"
+"    - файлы конфигурации из HGRCPATH\n"
+"    - EMAIL\n"
+"    - интерактивно введенное с клавиатуры имя\n"
+"    - ЛОГИН (с добавленным ``@имя-хоста``)"
+
+msgid ""
+"EMAIL\n"
+"    May be used as the author of a commit; see HGUSER."
+msgstr ""
+"EMAIL\n"
+"    Может быть использовано в качестве автора коммита; см. HGUSER."
+
+msgid ""
+"LOGNAME\n"
+"    May be used as the author of a commit; see HGUSER."
+msgstr ""
+"LOGNAME\n"
+"    Может быть использовано в качестве автора коммита; см. HGUSER."
+
+msgid ""
+"VISUAL\n"
+"    This is the name of the editor to use when committing. See EDITOR."
+msgstr ""
+"VISUAL\n"
+"    Название редактора, используемого при коммитах. См. EDITOR."
+
+msgid ""
+"EDITOR\n"
+"    Sometimes Mercurial needs to open a text file in an editor for a\n"
+"    user to modify, for example when writing commit messages. The\n"
+"    editor it uses is determined by looking at the environment\n"
+"    variables HGEDITOR, VISUAL and EDITOR, in that order. The first\n"
+"    non-empty one is chosen. If all of them are empty, the editor\n"
+"    defaults to 'vi'."
+msgstr ""
+"EDITOR\n"
+"    Инодга требуется открыть текстовый файл в редакторе, чтобы.\n"
+"    внести изменения, например для написания сообщения коммита.\n"
+"    Используемый редактор определяется переменными среды HGEDITOR,\n"
+"    VISUAL и EDITOR, именно в таком порядке. Выбирается первая\n"
+"    непустая переменная. Если они все пусты, используется 'vi'."
+
+msgid ""
+"PYTHONPATH\n"
+"    This is used by Python to find imported modules and may need to be\n"
+"    set appropriately if this Mercurial is not installed system-wide.\n"
+msgstr ""
+"PYTHONPATH\n"
+"    Используется Python'ом для поиска импортирумых модулей и должна\n"
+"    быть корректно установлена, если текущая копия Mercurial не\n"
+"    установлена в систему штатно.\n"
+
+msgid ""
+"Mercurial has the ability to add new features through the use of\n"
+"extensions. Extensions may add new commands, add options to\n"
+"existing commands, change the default behavior of commands, or\n"
+"implement hooks."
+msgstr ""
+
+msgid ""
+"Extensions are not loaded by default for a variety of reasons:\n"
+"they can increase startup overhead; they may be meant for advanced\n"
+"usage only; they may provide potentially dangerous abilities (such\n"
+"as letting you destroy or modify history); they might not be ready\n"
+"for prime time; or they may alter some usual behaviors of stock\n"
+"Mercurial. It is thus up to the user to activate extensions as\n"
+"needed."
+msgstr ""
+
+msgid ""
+"To enable the \"foo\" extension, either shipped with Mercurial or in the\n"
+"Python search path, create an entry for it in your configuration file,\n"
+"like this::"
+msgstr ""
+
+msgid ""
+"  [extensions]\n"
+"  foo ="
+msgstr ""
+
+msgid "You may also specify the full path to an extension::"
+msgstr ""
+
+msgid ""
+"  [extensions]\n"
+"  myfeature = ~/.hgext/myfeature.py"
+msgstr ""
+
+msgid ""
+"To explicitly disable an extension enabled in a configuration file of\n"
+"broader scope, prepend its path with !::"
+msgstr ""
+
+msgid ""
+"  [extensions]\n"
+"  # disabling extension bar residing in /path/to/extension/bar.py\n"
+"  bar = !/path/to/extension/bar.py\n"
+"  # ditto, but no path was supplied for extension baz\n"
+"  baz = !\n"
+msgstr ""
+
+msgid ""
+"Ancestor\n"
+"    Any changeset that can be reached by an unbroken chain of parent\n"
+"    changesets from a given changeset. More precisely, the ancestors\n"
+"    of a changeset can be defined by two properties: a parent of a\n"
+"    changeset is an ancestor, and a parent of an ancestor is an\n"
+"    ancestor. See also: 'Descendant'."
+msgstr ""
+
+msgid ""
+"Branch\n"
+"    (Noun) A child changeset that has been created from a parent that\n"
+"    is not a head. These are known as topological branches, see\n"
+"    'Branch, topological'. If a topological branch is named, it becomes\n"
+"    a named branch. If a topological branch is not named, it becomes\n"
+"    an anonymous branch. See 'Branch, anonymous' and 'Branch, named'."
+msgstr ""
+
+msgid ""
+"    Branches may be created when changes are pulled from or pushed to\n"
+"    a remote repository, since new heads may be created by these\n"
+"    operations. Note that the term branch can also be used informally\n"
+"    to describe a development process in which certain development is\n"
+"    done independently of other development. This is sometimes done\n"
+"    explicitly with a named branch, but it can also be done locally,\n"
+"    using bookmarks or clones and anonymous branches."
+msgstr ""
+
+msgid "    Example: \"The experimental branch\"."
+msgstr ""
+
+msgid ""
+"    (Verb) The action of creating a child changeset which results in\n"
+"    its parent having more than one child."
+msgstr ""
+
+msgid "    Example: \"I'm going to branch at X\"."
+msgstr ""
+
+msgid ""
+"Branch, anonymous\n"
+"    Every time a new child changeset is created from a parent that is not\n"
+"    a head and the name of the branch is not changed, a new anonymous\n"
+"    branch is created."
+msgstr ""
+
+msgid ""
+"Branch, closed\n"
+"    A named branch whose branch heads have all been closed."
+msgstr ""
+
+msgid ""
+"Branch, default\n"
+"    The branch assigned to a changeset when no name has previously been\n"
+"    assigned."
+msgstr ""
+
+msgid ""
+"Branch head\n"
+"    See 'Head, branch'."
+msgstr ""
+
+msgid ""
+"Branch, inactive\n"
+"    If a named branch has no topological heads, it is considered to be\n"
+"    inactive. As an example, a feature branch becomes inactive when it\n"
+"    is merged into the default branch. The :hg:`branches` command\n"
+"    shows inactive branches by default, though they can be hidden with\n"
+"    :hg:`branches --active`."
+msgstr ""
+
+msgid ""
+"    NOTE: this concept is deprecated because it is too implicit.\n"
+"    Branches should now be explicitly closed using :hg:`commit\n"
+"    --close-branch` when they are no longer needed."
+msgstr ""
+
+msgid ""
+"Branch, named\n"
+"    A collection of changesets which have the same branch name. By\n"
+"    default, children of a changeset in a named branch belong to the\n"
+"    same named branch. A child can be explicitly assigned to a\n"
+"    different branch. See :hg:`help branch`, :hg:`help branches` and\n"
+"    :hg:`commit --close-branch` for more information on managing\n"
+"    branches."
+msgstr ""
+
+msgid ""
+"    Named branches can be thought of as a kind of namespace, dividing\n"
+"    the collection of changesets that comprise the repository into a\n"
+"    collection of disjoint subsets. A named branch is not necessarily\n"
+"    a topological branch. If a new named branch is created from the\n"
+"    head of another named branch, or the default branch, but no\n"
+"    further changesets are added to that previous branch, then that\n"
+"    previous branch will be a branch in name only."
+msgstr ""
+
+msgid ""
+"Branch tip\n"
+"    See 'Tip, branch'."
+msgstr ""
+
+msgid ""
+"Branch, topological\n"
+"    Every time a new child changeset is created from a parent that is\n"
+"    not a head, a new topological branch is created. If a topological\n"
+"    branch is named, it becomes a named branch. If a topological\n"
+"    branch is not named, it becomes an anonymous branch of the\n"
+"    current, possibly default, branch."
+msgstr ""
+
+msgid ""
+"Changelog\n"
+"    A record of the changesets in the order in which they were added\n"
+"    to the repository. This includes details such as changeset id,\n"
+"    author, commit message, date, and list of changed files."
+msgstr ""
+
+msgid ""
+"Changeset\n"
+"    A snapshot of the state of the repository used to record a change."
+msgstr ""
+
+msgid ""
+"Changeset, child\n"
+"    The converse of parent changeset: if P is a parent of C, then C is\n"
+"    a child of P. There is no limit to the number of children that a\n"
+"    changeset may have."
+msgstr ""
+
+msgid ""
+"Changeset id\n"
+"    A SHA-1 hash that uniquely identifies a changeset. It may be\n"
+"    represented as either a \"long\" 40 hexadecimal digit string, or a\n"
+"    \"short\" 12 hexadecimal digit string."
+msgstr ""
+
+msgid ""
+"Changeset, merge\n"
+"    A changeset with two parents. This occurs when a merge is\n"
+"    committed."
+msgstr ""
+
+msgid ""
+"Changeset, parent\n"
+"    A revision upon which a child changeset is based. Specifically, a\n"
+"    parent changeset of a changeset C is a changeset whose node\n"
+"    immediately precedes C in the DAG. Changesets have at most two\n"
+"    parents."
+msgstr ""
+
+msgid ""
+"Checkout\n"
+"    (Noun) The working directory being updated to a specific\n"
+"    revision. This use should probably be avoided where possible, as\n"
+"    changeset is much more appropriate than checkout in this context."
+msgstr ""
+
+msgid "    Example: \"I'm using checkout X.\""
+msgstr ""
+
+msgid ""
+"    (Verb) Updating the working directory to a specific changeset. See\n"
+"    :hg:`help update`."
+msgstr ""
+
+msgid "    Example: \"I'm going to check out changeset X.\""
+msgstr ""
+
+msgid ""
+"Child changeset\n"
+"    See 'Changeset, child'."
+msgstr ""
+
+msgid ""
+"Close changeset\n"
+"    See 'Changeset, close'."
+msgstr ""
+
+msgid ""
+"Closed branch\n"
+"    See 'Branch, closed'."
+msgstr ""
+
+msgid ""
+"Clone\n"
+"    (Noun) An entire or partial copy of a repository. The partial\n"
+"    clone must be in the form of a revision and its ancestors."
+msgstr ""
+
+msgid "    Example: \"Is your clone up to date?\"."
+msgstr ""
+
+msgid "    (Verb) The process of creating a clone, using :hg:`clone`."
+msgstr ""
+
+msgid "    Example: \"I'm going to clone the repository\"."
+msgstr ""
+
+msgid ""
+"Closed branch head\n"
+"    See 'Head, closed branch'."
+msgstr ""
+
+msgid ""
+"Commit\n"
+"    (Noun) A synonym for changeset."
+msgstr ""
+
+msgid "    Example: \"Is the bug fixed in your recent commit?\""
+msgstr ""
+
+msgid ""
+"    (Verb) The act of recording changes to a repository. When files\n"
+"    are committed in a working directory, Mercurial finds the\n"
+"    differences between the committed files and their parent\n"
+"    changeset, creating a new changeset in the repository."
+msgstr ""
+
+msgid "    Example: \"You should commit those changes now.\""
+msgstr ""
+
+msgid ""
+"Cset\n"
+"    A common abbreviation of the term changeset."
+msgstr ""
+
+msgid ""
+"DAG\n"
+"    The repository of changesets of a distributed version control\n"
+"    system (DVCS) can be described as a directed acyclic graph (DAG),\n"
+"    consisting of nodes and edges, where nodes correspond to\n"
+"    changesets and edges imply a parent -> child relation. This graph\n"
+"    can be visualized by graphical tools such as :hg:`glog`\n"
+"    (graphlog). In Mercurial, the DAG is limited by the requirement\n"
+"    for children to have at most two parents."
+msgstr ""
+
+msgid ""
+"Default branch\n"
+"    See 'Branch, default'."
+msgstr ""
+
+msgid ""
+"Descendant\n"
+"    Any changeset that can be reached by a chain of child changesets\n"
+"    from a given changeset. More precisely, the descendants of a\n"
+"    changeset can be defined by two properties: the child of a\n"
+"    changeset is a descendant, and the child of a descendant is a\n"
+"    descendant. See also: 'Ancestor'."
+msgstr ""
+
+msgid ""
+"Diff\n"
+"    (Noun) The difference between the contents and attributes of files\n"
+"    in two changesets or a changeset and the current working\n"
+"    directory. The difference is usually represented in a standard\n"
+"    form called a \"diff\" or \"patch\". The \"git diff\" format is used\n"
+"    when the changes include copies, renames, or changes to file\n"
+"    attributes, none of which can be represented/handled by classic\n"
+"    \"diff\" and \"patch\"."
+msgstr ""
+
+msgid "    Example: \"Did you see my correction in the diff?\""
+msgstr ""
+
+msgid ""
+"    (Verb) Diffing two changesets is the action of creating a diff or\n"
+"    patch."
+msgstr ""
+
+msgid ""
+"    Example: \"If you diff with changeset X, you will see what I mean.\""
+msgstr ""
+
+msgid ""
+"Directory, working\n"
+"    The working directory represents the state of the files tracked by\n"
+"    Mercurial, that will be recorded in the next commit. The working\n"
+"    directory initially corresponds to the snapshot at an existing\n"
+"    changeset, known as the parent of the working directory. See\n"
+"    'Parent, working directory'. The state may be modified by changes\n"
+"    to the files introduced manually or by a merge. The repository\n"
+"    metadata exists in the .hg directory inside the working directory."
+msgstr ""
+
+msgid ""
+"Graph\n"
+"    See DAG and :hg:`help graphlog`."
+msgstr ""
+
+msgid ""
+"Head\n"
+"    The term 'head' may be used to refer to both a branch head or a\n"
+"    repository head, depending on the context. See 'Head, branch' and\n"
+"    'Head, repository' for specific definitions."
+msgstr ""
+
+msgid ""
+"    Heads are where development generally takes place and are the\n"
+"    usual targets for update and merge operations."
+msgstr ""
+
+msgid ""
+"Head, branch\n"
+"    A changeset with no descendants on the same named branch."
+msgstr ""
+
+msgid ""
+"Head, closed branch\n"
+"    A changeset that marks a head as no longer interesting. The closed\n"
+"    head is no longer listed by :hg:`heads`. A branch is considered\n"
+"    closed when all its heads are closed and consequently is not\n"
+"    listed by :hg:`branches`."
+msgstr ""
+
+msgid ""
+"Head, repository\n"
+"    A topological head which has not been closed."
+msgstr ""
+
+msgid ""
+"Head, topological\n"
+"    A changeset with no children in the repository."
+msgstr ""
+
+msgid ""
+"History, immutable\n"
+"    Once committed, changesets cannot be altered.  Extensions which\n"
+"    appear to change history actually create new changesets that\n"
+"    replace existing ones, and then destroy the old changesets. Doing\n"
+"    so in public repositories can result in old changesets being\n"
+"    reintroduced to the repository."
+msgstr ""
+
+msgid ""
+"History, rewriting\n"
+"    The changesets in a repository are immutable. However, extensions\n"
+"    to Mercurial can be used to alter the repository, usually in such\n"
+"    a way as to preserve changeset contents."
+msgstr ""
+
+msgid ""
+"Immutable history\n"
+"    See 'History, immutable'."
+msgstr ""
+
+msgid ""
+"Merge changeset\n"
+"    See 'Changeset, merge'."
+msgstr ""
+
+msgid ""
+"Manifest\n"
+"    Each changeset has a manifest, which is the list of files that are\n"
+"    tracked by the changeset."
+msgstr ""
+
+msgid ""
+"Merge\n"
+"    Used to bring together divergent branches of work. When you update\n"
+"    to a changeset and then merge another changeset, you bring the\n"
+"    history of the latter changeset into your working directory. Once\n"
+"    conflicts are resolved (and marked), this merge may be committed\n"
+"    as a merge changeset, bringing two branches together in the DAG."
+msgstr ""
+
+msgid ""
+"Named branch\n"
+"    See 'Branch, named'."
+msgstr ""
+
+msgid ""
+"Null changeset\n"
+"    The empty changeset. It is the parent state of newly-initialized\n"
+"    repositories and repositories with no checked out revision. It is\n"
+"    thus the parent of root changesets and the effective ancestor when\n"
+"    merging unrelated changesets. Can be specified by the alias 'null'\n"
+"    or by the changeset ID '000000000000'."
+msgstr ""
+
+msgid ""
+"Parent\n"
+"    See 'Changeset, parent'."
+msgstr ""
+
+msgid ""
+"Parent changeset\n"
+"    See 'Changeset, parent'."
+msgstr ""
+
+msgid ""
+"Parent, working directory\n"
+"    The working directory parent reflects a virtual revision which is\n"
+"    the child of the changeset (or two changesets with an uncommitted\n"
+"    merge) shown by :hg:`parents`. This is changed with\n"
+"    :hg:`update`. Other commands to see the working directory parent\n"
+"    are :hg:`summary` and :hg:`id`. Can be specified by the alias \".\"."
+msgstr ""
+
+msgid ""
+"Patch\n"
+"    (Noun) The product of a diff operation."
+msgstr ""
+
+msgid "    Example: \"I've sent you my patch.\""
+msgstr ""
+
+msgid ""
+"    (Verb) The process of using a patch file to transform one\n"
+"    changeset into another."
+msgstr ""
+
+msgid "    Example: \"You will need to patch that revision.\""
+msgstr ""
+
+msgid ""
+"Pull\n"
+"    An operation in which changesets in a remote repository which are\n"
+"    not in the local repository are brought into the local\n"
+"    repository. Note that this operation without special arguments\n"
+"    only updates the repository, it does not update the files in the\n"
+"    working directory. See :hg:`help pull`."
+msgstr ""
+
+msgid ""
+"Push\n"
+"    An operation in which changesets in a local repository which are\n"
+"    not in a remote repository are sent to the remote repository. Note\n"
+"    that this operation only adds changesets which have been committed\n"
+"    locally to the remote repository. Uncommitted changes are not\n"
+"    sent. See :hg:`help push`."
+msgstr ""
+
+msgid ""
+"Repository\n"
+"    The metadata describing all recorded states of a collection of\n"
+"    files. Each recorded state is represented by a changeset. A\n"
+"    repository is usually (but not always) found in the ``.hg``\n"
+"    subdirectory of a working directory. Any recorded state can be\n"
+"    recreated by \"updating\" a working directory to a specific\n"
+"    changeset."
+msgstr ""
+
+msgid ""
+"Repository head\n"
+"    See 'Head, repository'."
+msgstr ""
+
+msgid ""
+"Revision\n"
+"    A state of the repository at some point in time. Earlier revisions\n"
+"    can be updated to by using :hg:`update`.  See also 'Revision\n"
+"    number'; See also 'Changeset'."
+msgstr ""
+
+msgid ""
+"Revision number\n"
+"    This integer uniquely identifies a changeset in a specific\n"
+"    repository. It represents the order in which changesets were added\n"
+"    to a repository, starting with revision number 0. Note that the\n"
+"    revision number may be different in each clone of a repository. To\n"
+"    identify changesets uniquely between different clones, see\n"
+"    'Changeset id'."
+msgstr ""
+
+msgid ""
+"Revlog\n"
+"    History storage mechanism used by Mercurial. It is a form of delta\n"
+"    encoding, with occasional full revision of data followed by delta\n"
+"    of each successive revision. It includes data and an index\n"
+"    pointing to the data."
+msgstr ""
+
+msgid ""
+"Rewriting history\n"
+"    See 'History, rewriting'."
+msgstr ""
+
+msgid ""
+"Root\n"
+"    A changeset that has only the null changeset as its parent. Most\n"
+"    repositories have only a single root changeset."
+msgstr ""
+
+msgid ""
+"Tip\n"
+"    The changeset with the highest revision number. It is the changeset\n"
+"    most recently added in a repository."
+msgstr ""
+
+msgid ""
+"Tip, branch\n"
+"    The head of a given branch with the highest revision number. When\n"
+"    a branch name is used as a revision identifier, it refers to the\n"
+"    branch tip. See also 'Branch, head'. Note that because revision\n"
+"    numbers may be different in different repository clones, the\n"
+"    branch tip may be different in different cloned repositories."
+msgstr ""
+
+msgid ""
+"Update\n"
+"    (Noun) Another synonym of changeset."
+msgstr ""
+
+msgid "    Example: \"I've pushed an update\"."
+msgstr ""
+
+msgid ""
+"    (Verb) This term is usually used to describe updating the state of\n"
+"    the working directory to that of a specific changeset. See\n"
+"    :hg:`help update`."
+msgstr ""
+
+msgid "    Example: \"You should update\"."
+msgstr ""
+
+msgid ""
+"Working directory\n"
+"    See 'Directory, working'."
+msgstr ""
+
+msgid ""
+"Working directory parent\n"
+"    See 'Parent, working directory'.\n"
+msgstr ""
+
+msgid ""
+"Synopsis\n"
+"--------"
+msgstr ""
+
+msgid ""
+"The Mercurial system uses a file called ``.hgignore`` in the root\n"
+"directory of a repository to control its behavior when it searches\n"
+"for files that it is not currently tracking."
+msgstr ""
+
+msgid ""
+"Description\n"
+"-----------"
+msgstr ""
+
+msgid ""
+"The working directory of a Mercurial repository will often contain\n"
+"files that should not be tracked by Mercurial. These include backup\n"
+"files created by editors and build products created by compilers.\n"
+"These files can be ignored by listing them in a ``.hgignore`` file in\n"
+"the root of the working directory. The ``.hgignore`` file must be\n"
+"created manually. It is typically put under version control, so that\n"
+"the settings will propagate to other repositories with push and pull."
+msgstr ""
+
+msgid ""
+"An untracked file is ignored if its path relative to the repository\n"
+"root directory, or any prefix path of that path, is matched against\n"
+"any pattern in ``.hgignore``."
+msgstr ""
+
+msgid ""
+"For example, say we have an untracked file, ``file.c``, at\n"
+"``a/b/file.c`` inside our repository. Mercurial will ignore ``file.c``\n"
+"if any pattern in ``.hgignore`` matches ``a/b/file.c``, ``a/b`` or ``a``."
+msgstr ""
+
+msgid ""
+"In addition, a Mercurial configuration file can reference a set of\n"
+"per-user or global ignore files. See the\n"
+"``http://www.selenic.com/mercurial/hgrc.5.html`` man page for details\n"
+"of how to configure these files. Look for the \"ignore\" entry in the\n"
+"\"ui\" section."
+msgstr ""
+
+msgid ""
+"To control Mercurial's handling of files that it manages, see the\n"
+"``http://www.selenic.com/mercurial/hg.1.html`` man page. Look for\n"
+"the ``-I`` and ``-X`` options."
+msgstr ""
+
+msgid ""
+"Syntax\n"
+"------"
+msgstr ""
+
+msgid ""
+"An ignore file is a plain text file consisting of a list of patterns,\n"
+"with one pattern per line. Empty lines are skipped. The ``#``\n"
+"character is treated as a comment character, and the ``\\`` character\n"
+"is treated as an escape character."
+msgstr ""
+
+msgid ""
+"Mercurial supports several pattern syntaxes. The default syntax used\n"
+"is Python/Perl-style regular expressions."
+msgstr ""
+
+msgid "To change the syntax used, use a line of the following form::"
+msgstr ""
+
+msgid "  syntax: NAME"
+msgstr ""
+
+msgid "where ``NAME`` is one of the following:"
+msgstr ""
+
+msgid ""
+"``regexp``\n"
+"  Regular expression, Python/Perl syntax.\n"
+"``glob``\n"
+"  Shell-style glob."
+msgstr ""
+
+msgid ""
+"The chosen syntax stays in effect when parsing all patterns that\n"
+"follow, until another syntax is selected."
+msgstr ""
+
+msgid ""
+"Neither glob nor regexp patterns are rooted. A glob-syntax pattern of\n"
+"the form ``*.c`` will match a file ending in ``.c`` in any directory,\n"
+"and a regexp pattern of the form ``\\.c$`` will do the same. To root a\n"
+"regexp pattern, start it with ``^``."
+msgstr ""
+
+msgid ""
+"Example\n"
+"-------"
+msgstr ""
+
+msgid "Here is an example ignore file. ::"
+msgstr ""
+
+msgid ""
+"  # use glob syntax.\n"
+"  syntax: glob"
+msgstr ""
+
+msgid ""
+"  *.elc\n"
+"  *.pyc\n"
+"  *~"
+msgstr ""
+
+msgid ""
+"  # switch to regexp syntax.\n"
+"  syntax: regexp\n"
+"  ^\\.pc/\n"
+msgstr ""
+
+msgid ""
+"Mercurial's internal web server, hgweb, can serve either a single\n"
+"repository, or a collection of them. In the latter case, a special\n"
+"configuration file can be used to specify the repository paths to use\n"
+"and global web configuration options."
+msgstr ""
+
+msgid ""
+"This file uses the same syntax as other Mercurial configuration files,\n"
+"but only the following sections are recognized:"
+msgstr ""
+
+msgid ""
+"  - web\n"
+"  - paths\n"
+"  - collections"
+msgstr ""
+
+msgid ""
+"The ``web`` section can specify all the settings described in the web\n"
+"section of the hgrc(5) documentation. See :hg:`help config` for\n"
+"information on where to find the manual page."
+msgstr ""
+
+msgid ""
+"The ``paths`` section provides mappings of physical repository\n"
+"paths to virtual ones. For instance::"
+msgstr ""
+
+msgid ""
+"  [paths]\n"
+"  projects/a = /foo/bar\n"
+"  projects/b = /baz/quux\n"
+"  web/root = /real/root/*\n"
+"  / = /real/root2/*\n"
+"  virtual/root2 = /real/root2/**"
+msgstr ""
+
+msgid ""
+"- The first two entries make two repositories in different directories\n"
+"  appear under the same directory in the web interface\n"
+"- The third entry maps every Mercurial repository found in '/real/root'\n"
+"  into 'web/root'. This format is preferred over the [collections] one,\n"
+"  since using absolute paths as configuration keys is not supported on "
+"every\n"
+"  platform (especially on Windows).\n"
+"- The fourth entry is a special case mapping all repositories in\n"
+"  '/real/root2' in the root of the virtual directory.\n"
+"- The fifth entry recursively finds all repositories under the real\n"
+"  root, and maps their relative paths under the virtual root."
+msgstr ""
+
+msgid ""
+"The ``collections`` section provides mappings of trees of physical\n"
+"repositories paths to virtual ones, though the paths syntax is generally\n"
+"preferred. For instance::"
+msgstr ""
+
+msgid ""
+"  [collections]\n"
+"  /foo = /foo"
+msgstr ""
+
+msgid ""
+"Here, the left side will be stripped off all repositories found in the\n"
+"right side. Thus ``/foo/bar`` and ``foo/quux/baz`` will be listed as\n"
+"``bar`` and ``quux/baz`` respectively.\n"
+msgstr ""
+
+msgid "To merge files Mercurial uses merge tools."
+msgstr ""
+
+msgid ""
+"A merge tool combines two different versions of a file into a merged\n"
+"file. Merge tools are given the two files and the greatest common\n"
+"ancestor of the two file versions, so they can determine the changes\n"
+"made on both branches."
+msgstr ""
+
+msgid ""
+"Merge tools are used both for :hg:`resolve`, :hg:`merge`, :hg:`update`,\n"
+":hg:`backout` and in several extensions."
+msgstr ""
+
+msgid ""
+"Usually, the merge tool tries to automatically reconcile the files by\n"
+"combining all non-overlapping changes that occurred separately in\n"
+"the two different evolutions of the same initial base file. Furthermore, "
+"some\n"
+"interactive merge programs make it easier to manually resolve\n"
+"conflicting merges, either in a graphical way, or by inserting some\n"
+"conflict markers. Mercurial does not include any interactive merge\n"
+"programs but relies on external tools for that."
+msgstr ""
+
+msgid ""
+"Available merge tools\n"
+"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\""
+msgstr ""
+
+msgid ""
+"External merge tools and their properties are configured in the\n"
+"merge-tools configuration section - see hgrc(5) - but they can often just\n"
+"be named by their executable."
+msgstr ""
+
+msgid ""
+"A merge tool is generally usable if its executable can be found on the\n"
+"system and if it can handle the merge. The executable is found if it\n"
+"is an absolute or relative executable path or the name of an\n"
+"application in the executable search path. The tool is assumed to be\n"
+"able to handle the merge if it can handle symlinks if the file is a\n"
+"symlink, if it can handle binary files if the file is binary, and if a\n"
+"GUI is available if the tool requires a GUI."
+msgstr ""
+
+msgid ""
+"There are some internal merge tools which can be used. The internal\n"
+"merge tools are:"
+msgstr ""
+
+msgid ""
+"``internal:merge``\n"
+"   Uses the internal non-interactive simple merge algorithm for merging\n"
+"   files. It will fail if there are any conflicts and leave markers in\n"
+"   the partially merged file."
+msgstr ""
+
+msgid ""
+"``internal:fail``\n"
+"   Rather than attempting to merge files that were modified on both\n"
+"   branches, it marks them as unresolved. The resolve command must be\n"
+"   used to resolve these conflicts."
+msgstr ""
+
+msgid ""
+"``internal:local``\n"
+"   Uses the local version of files as the merged version."
+msgstr ""
+
+msgid ""
+"``internal:other``\n"
+"   Uses the other version of files as the merged version."
+msgstr ""
+
+msgid ""
+"``internal:prompt``\n"
+"   Asks the user which of the local or the other version to keep as\n"
+"   the merged version."
+msgstr ""
+
+msgid ""
+"``internal:dump``\n"
+"   Creates three versions of the files to merge, containing the\n"
+"   contents of local, other and base. These files can then be used to\n"
+"   perform a merge manually. If the file to be merged is named\n"
+"   ``a.txt``, these files will accordingly be named ``a.txt.local``,\n"
+"   ``a.txt.other`` and ``a.txt.base`` and they will be placed in the\n"
+"   same directory as ``a.txt``."
+msgstr ""
+
+msgid ""
+"Internal tools are always available and do not require a GUI but will by "
+"default\n"
+"not handle symlinks or binary files."
+msgstr ""
+
+msgid ""
+"Choosing a merge tool\n"
+"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\""
+msgstr ""
+
+msgid "Mercurial uses these rules when deciding which merge tool to use:"
+msgstr ""
+
+msgid ""
+"1. If a tool has been specified with the --tool option to merge or resolve, "
+"it\n"
+"   is used.  If it is the name of a tool in the merge-tools configuration, "
+"its\n"
+"   configuration is used. Otherwise the specified tool must be executable "
+"by\n"
+"   the shell."
+msgstr ""
+
+msgid ""
+"2. If the ``HGMERGE`` environment variable is present, its value is used "
+"and\n"
+"   must be executable by the shell."
+msgstr ""
+
+msgid ""
+"3. If the filename of the file to be merged matches any of the patterns in "
+"the\n"
+"   merge-patterns configuration section, the first usable merge tool\n"
+"   corresponding to a matching pattern is used. Here, binary capabilities of "
+"the\n"
+"   merge tool are not considered."
+msgstr ""
+
+msgid ""
+"4. If ui.merge is set it will be considered next. If the value is not the "
+"name\n"
+"   of a configured tool, the specified value is used and must be executable "
+"by\n"
+"   the shell. Otherwise the named tool is used if it is usable."
+msgstr ""
+
+msgid ""
+"5. If any usable merge tools are present in the merge-tools configuration\n"
+"   section, the one with the highest priority is used."
+msgstr ""
+
+msgid ""
+"6. If a program named ``hgmerge`` can be found on the system, it is used - "
+"but\n"
+"   it will by default not be used for symlinks and binary files."
+msgstr ""
+
+msgid ""
+"7. If the file to be merged is not binary and is not a symlink, then\n"
+"   ``internal:merge`` is used."
+msgstr ""
+
+msgid "8. The merge of the file fails and must be resolved before commit."
+msgstr ""
+
+msgid ""
+".. note::\n"
+"   After selecting a merge program, Mercurial will by default attempt\n"
+"   to merge the files using a simple merge algorithm first. Only if it "
+"doesn't\n"
+"   succeed because of conflicting changes Mercurial will actually execute "
+"the\n"
+"   merge program. Whether to use the simple merge algorithm first can be\n"
+"   controlled by the premerge setting of the merge tool. Premerge is enabled "
+"by\n"
+"   default unless the file is binary or a symlink."
+msgstr ""
+
+msgid ""
+"See the merge-tools and ui sections of hgrc(5) for details on the\n"
+"configuration of merge tools.\n"
+msgstr ""
+
+msgid ""
+"When Mercurial accepts more than one revision, they may be specified\n"
+"individually, or provided as a topologically continuous range,\n"
+"separated by the \":\" character."
+msgstr ""
+
+msgid ""
+"The syntax of range notation is [BEGIN]:[END], where BEGIN and END are\n"
+"revision identifiers. Both BEGIN and END are optional. If BEGIN is not\n"
+"specified, it defaults to revision number 0. If END is not specified,\n"
+"it defaults to the tip. The range \":\" thus means \"all revisions\"."
+msgstr ""
+
+msgid "If BEGIN is greater than END, revisions are treated in reverse order."
+msgstr ""
+
+msgid ""
+"A range acts as a closed interval. This means that a range of 3:5\n"
+"gives 3, 4 and 5. Similarly, a range of 9:6 gives 9, 8, 7, and 6.\n"
+msgstr ""
+
+msgid ""
+"Mercurial accepts several notations for identifying one or more files\n"
+"at a time."
+msgstr ""
+
+msgid ""
+"By default, Mercurial treats filenames as shell-style extended glob\n"
+"patterns."
+msgstr ""
+
+msgid "Alternate pattern notations must be specified explicitly."
+msgstr ""
+
+msgid ""
+"To use a plain path name without any pattern matching, start it with\n"
+"``path:``. These path names must completely match starting at the\n"
+"current repository root."
+msgstr ""
+
+msgid ""
+"To use an extended glob, start a name with ``glob:``. Globs are rooted\n"
+"at the current directory; a glob such as ``*.c`` will only match files\n"
+"in the current directory ending with ``.c``."
+msgstr ""
+
+msgid ""
+"The supported glob syntax extensions are ``**`` to match any string\n"
+"across path separators and ``{a,b}`` to mean \"a or b\"."
+msgstr ""
+
+msgid ""
+"To use a Perl/Python regular expression, start a name with ``re:``.\n"
+"Regexp pattern matching is anchored at the root of the repository."
+msgstr ""
+
+msgid ""
+"To read name patterns from a file, use ``listfile:`` or ``listfile0:``.\n"
+"The latter expects null delimited patterns while the former expects line\n"
+"feeds. Each string read from the file is itself treated as a file\n"
+"pattern."
+msgstr ""
+
+msgid "Plain examples::"
+msgstr ""
+
+msgid ""
+"  path:foo/bar   a name bar in a directory named foo in the root\n"
+"                 of the repository\n"
+"  path:path:name a file or directory named \"path:name\""
+msgstr ""
+
+msgid "Glob examples::"
+msgstr ""
+
+msgid ""
+"  glob:*.c       any name ending in \".c\" in the current directory\n"
+"  *.c            any name ending in \".c\" in the current directory\n"
+"  **.c           any name ending in \".c\" in any subdirectory of the\n"
+"                 current directory including itself.\n"
+"  foo/*.c        any name ending in \".c\" in the directory foo\n"
+"  foo/**.c       any name ending in \".c\" in any subdirectory of foo\n"
+"                 including itself."
+msgstr ""
+
+msgid "Regexp examples::"
+msgstr ""
+
+msgid "  re:.*\\.c$      any name ending in \".c\", anywhere in the repository"
+msgstr ""
+
+msgid "File examples::"
+msgstr ""
+
+msgid ""
+"  listfile:list.txt  read list from list.txt with one file pattern per line\n"
+"  listfile0:list.txt read list from list.txt with null byte delimiters\n"
+msgstr ""
+
+msgid "Mercurial supports several ways to specify individual revisions."
+msgstr ""
+
+msgid ""
+"A plain integer is treated as a revision number. Negative integers are\n"
+"treated as sequential offsets from the tip, with -1 denoting the tip,\n"
+"-2 denoting the revision prior to the tip, and so forth."
+msgstr ""
+
+msgid ""
+"A 40-digit hexadecimal string is treated as a unique revision\n"
+"identifier."
+msgstr ""
+
+msgid ""
+"A hexadecimal string less than 40 characters long is treated as a\n"
+"unique revision identifier and is referred to as a short-form\n"
+"identifier. A short-form identifier is only valid if it is the prefix\n"
+"of exactly one full-length identifier."
+msgstr ""
+
+msgid ""
+"Any other string is treated as a tag or branch name. A tag name is a\n"
+"symbolic name associated with a revision identifier. A branch name\n"
+"denotes the tipmost revision of that branch. Tag and branch names must\n"
+"not contain the \":\" character."
+msgstr ""
+
+msgid ""
+"The reserved name \"tip\" is a special tag that always identifies the\n"
+"most recent revision."
+msgstr ""
+
+msgid ""
+"The reserved name \"null\" indicates the null revision. This is the\n"
+"revision of an empty repository, and the parent of revision 0."
+msgstr ""
+
+msgid ""
+"The reserved name \".\" indicates the working directory parent. If no\n"
+"working directory is checked out, it is equivalent to null. If an\n"
+"uncommitted merge is in progress, \".\" is the revision of the first\n"
+"parent.\n"
+msgstr ""
+
+msgid ""
+"Mercurial supports a functional language for selecting a set of\n"
+"revisions."
+msgstr ""
+
+msgid ""
+"The language supports a number of predicates which are joined by infix\n"
+"operators. Parenthesis can be used for grouping."
+msgstr ""
+
+msgid ""
+"Identifiers such as branch names must be quoted with single or double\n"
+"quotes if they contain characters outside of\n"
+"``[._a-zA-Z0-9\\x80-\\xff]`` or if they match one of the predefined\n"
+"predicates."
+msgstr ""
+
+msgid ""
+"Special characters can be used in quoted identifiers by escaping them,\n"
+"e.g., ``\\n`` is interpreted as a newline. To prevent them from being\n"
+"interpreted, strings can be prefixed with ``r``, e.g. ``r'...'``."
+msgstr ""
+
+msgid "There is a single prefix operator:"
+msgstr ""
+
+msgid ""
+"``not x``\n"
+"  Changesets not in x. Short form is ``! x``."
+msgstr ""
+
+msgid "These are the supported infix operators:"
+msgstr ""
+
+msgid ""
+"``x::y``\n"
+"  A DAG range, meaning all changesets that are descendants of x and\n"
+"  ancestors of y, including x and y themselves. If the first endpoint\n"
+"  is left out, this is equivalent to ``ancestors(y)``, if the second\n"
+"  is left out it is equivalent to ``descendants(x)``."
+msgstr ""
+
+msgid "  An alternative syntax is ``x..y``."
+msgstr ""
+
+msgid ""
+"``x:y``\n"
+"  All changesets with revision numbers between x and y, both\n"
+"  inclusive. Either endpoint can be left out, they default to 0 and\n"
+"  tip."
+msgstr ""
+
+msgid ""
+"``x and y``\n"
+"  The intersection of changesets in x and y. Short form is ``x & y``."
+msgstr ""
+
+msgid ""
+"``x or y``\n"
+"  The union of changesets in x and y. There are two alternative short\n"
+"  forms: ``x | y`` and ``x + y``."
+msgstr ""
+
+msgid ""
+"``x - y``\n"
+"  Changesets in x but not in y.\n"
+"  \n"
+"``x^n``\n"
+"  The nth parent of x, n == 0, 1, or 2.\n"
+"  For n == 0, x; for n == 1, the first parent of each changeset in x;\n"
+"  for n == 2, the second parent of changeset in x."
+msgstr ""
+
+msgid ""
+"``x~n``\n"
+"  The nth first ancestor of x; ``x~0`` is x; ``x~3`` is ``x^^^``."
+msgstr ""
+
+msgid "There is a single postfix operator:"
+msgstr ""
+
+msgid ""
+"``x^``\n"
+"  Equivalent to ``x^1``, the first parent of each changeset in x."
+msgstr ""
+
+msgid ""
+"\n"
+"The following predicates are supported:"
+msgstr ""
+
+msgid ".. predicatesmarker"
+msgstr ""
+
+msgid ""
+"New predicates (known as \"aliases\") can be defined, using any combination "
+"of\n"
+"existing predicates or other aliases. An alias definition looks like::"
+msgstr ""
+
+msgid "  <alias> = <definition>"
+msgstr ""
+
+msgid ""
+"in the ``revsetalias`` section of ``.hgrc``. Arguments of the form `$1`, `"
+"$2`,\n"
+"etc. are substituted from the alias into the definition."
+msgstr ""
+
+msgid "For example,"
+msgstr ""
+
+msgid ""
+"  [revsetalias]\n"
+"  h = heads()\n"
+"  d($1) = sort($1, date)\n"
+"  rs($1, $2) = reverse(sort($1, $2))"
+msgstr ""
+
+msgid ""
+"defines three aliases, ``h``, ``d``, and ``rs``. ``rs(0:tip, author)`` is\n"
+"exactly equivalent to ``reverse(sort(0:tip, author))``."
+msgstr ""
+
+msgid "Command line equivalents for :hg:`log`::"
+msgstr ""
+
+msgid ""
+"  -f    ->  ::.\n"
+"  -d x  ->  date(x)\n"
+"  -k x  ->  keyword(x)\n"
+"  -m    ->  merge()\n"
+"  -u x  ->  user(x)\n"
+"  -b x  ->  branch(x)\n"
+"  -P x  ->  !::x\n"
+"  -l x  ->  limit(expr, x)"
+msgstr ""
+
+msgid "Some sample queries:"
+msgstr ""
+
+msgid "- Changesets on the default branch::"
+msgstr ""
+
+msgid "    hg log -r \"branch(default)\""
+msgstr ""
+
+msgid "- Changesets on the default branch since tag 1.5 (excluding merges)::"
+msgstr ""
+
+msgid "    hg log -r \"branch(default) and 1.5:: and not merge()\""
+msgstr ""
+
+msgid "- Open branch heads::"
+msgstr ""
+
+msgid "    hg log -r \"head() and not closed()\""
+msgstr ""
+
+msgid ""
+"- Changesets between tags 1.3 and 1.5 mentioning \"bug\" that affect\n"
+"  ``hgext/*``::"
+msgstr ""
+
+msgid "    hg log -r \"1.3::1.5 and keyword(bug) and file('hgext/*')\""
+msgstr ""
+
+msgid "- Changesets committed in May 2008, sorted by user::"
+msgstr ""
+
+msgid "    hg log -r \"sort(date('May 2008'), user)\""
+msgstr ""
+
+msgid ""
+"- Changesets mentioning \"bug\" or \"issue\" that are not in a tagged\n"
+"  release::"
+msgstr ""
+
+msgid ""
+"    hg log -r \"(keyword(bug) or keyword(issue)) and not ancestors(tagged())"
+"\"\n"
+msgstr ""
+
+msgid ""
+"Subrepositories let you nest external repositories or projects into a\n"
+"parent Mercurial repository, and make commands operate on them as a\n"
+"group. External Mercurial and Subversion projects are currently\n"
+"supported."
+msgstr ""
+
+msgid "Subrepositories are made of three components:"
+msgstr ""
+
+msgid ""
+"1. Nested repository checkouts. They can appear anywhere in the\n"
+"   parent working directory, and are Mercurial clones or Subversion\n"
+"   checkouts."
+msgstr ""
+
+msgid ""
+"2. Nested repository references. They are defined in ``.hgsub`` and\n"
+"   tell where the subrepository checkouts come from. Mercurial\n"
+"   subrepositories are referenced like:"
+msgstr ""
+
+msgid "     path/to/nested = https://example.com/nested/repo/path"
+msgstr ""
+
+msgid ""
+"   where ``path/to/nested`` is the checkout location relatively to the\n"
+"   parent Mercurial root, and ``https://example.com/nested/repo/path``\n"
+"   is the source repository path. The source can also reference a\n"
+"   filesystem path. Subversion repositories are defined with:"
+msgstr ""
+
+msgid "     path/to/nested = [svn]https://example.com/nested/trunk/path"
+msgstr ""
+
+msgid ""
+"   Note that ``.hgsub`` does not exist by default in Mercurial\n"
+"   repositories, you have to create and add it to the parent\n"
+"   repository before using subrepositories."
+msgstr ""
+
+msgid ""
+"3. Nested repository states. They are defined in ``.hgsubstate`` and\n"
+"   capture whatever information is required to restore the\n"
+"   subrepositories to the state they were committed in a parent\n"
+"   repository changeset. Mercurial automatically record the nested\n"
+"   repositories states when committing in the parent repository."
+msgstr ""
+
+msgid ""
+"   .. note::\n"
+"      The ``.hgsubstate`` file should not be edited manually."
+msgstr ""
+
+msgid ""
+"\n"
+"Adding a Subrepository\n"
+"----------------------"
+msgstr ""
+
+msgid ""
+"If ``.hgsub`` does not exist, create it and add it to the parent\n"
+"repository. Clone or checkout the external projects where you want it\n"
+"to live in the parent repository. Edit ``.hgsub`` and add the\n"
+"subrepository entry as described above. At this point, the\n"
+"subrepository is tracked and the next commit will record its state in\n"
+"``.hgsubstate`` and bind it to the committed changeset."
+msgstr ""
+
+msgid ""
+"Synchronizing a Subrepository\n"
+"-----------------------------"
+msgstr ""
+
+msgid ""
+"Subrepos do not automatically track the latest changeset of their\n"
+"sources. Instead, they are updated to the changeset that corresponds\n"
+"with the changeset checked out in the top-level changeset. This is so\n"
+"developers always get a consistent set of compatible code and\n"
+"libraries when they update."
+msgstr ""
+
+msgid ""
+"Thus, updating subrepos is a manual process. Simply check out target\n"
+"subrepo at the desired revision, test in the top-level repo, then\n"
+"commit in the parent repository to record the new combination."
+msgstr ""
+
+msgid ""
+"Deleting a Subrepository\n"
+"------------------------"
+msgstr ""
+
+msgid ""
+"To remove a subrepository from the parent repository, delete its\n"
+"reference from ``.hgsub``, then remove its files."
+msgstr ""
+
+msgid ""
+"Interaction with Mercurial Commands\n"
+"-----------------------------------"
+msgstr ""
+
+msgid ""
+":add: add does not recurse in subrepos unless -S/--subrepos is\n"
+"    specified. Subversion subrepositories are currently silently\n"
+"    ignored."
+msgstr ""
+
+msgid ""
+":archive: archive does not recurse in subrepositories unless\n"
+"    -S/--subrepos is specified."
+msgstr ""
+
+msgid ""
+":commit: commit creates a consistent snapshot of the state of the\n"
+"    entire project and its subrepositories. It does this by first\n"
+"    attempting to commit all modified subrepositories, then recording\n"
+"    their state and finally committing it in the parent\n"
+"    repository. Mercurial can be made to abort if any subrepository\n"
+"    content is modified by setting \"ui.commitsubrepos=no\" in a\n"
+"    configuration file (see :hg:`help config`)."
+msgstr ""
+
+msgid ""
+":diff: diff does not recurse in subrepos unless -S/--subrepos is\n"
+"    specified. Changes are displayed as usual, on the subrepositories\n"
+"    elements. Subversion subrepositories are currently silently\n"
+"    ignored."
+msgstr ""
+
+msgid ""
+":incoming: incoming does not recurse in subrepos unless -S/--subrepos\n"
+"    is specified. Subversion subrepositories are currently silently\n"
+"    ignored."
+msgstr ""
+
+msgid ""
+":outgoing: outgoing does not recurse in subrepos unless -S/--subrepos\n"
+"    is specified. Subversion subrepositories are currently silently\n"
+"    ignored."
+msgstr ""
+
+msgid ""
+":pull: pull is not recursive since it is not clear what to pull prior\n"
+"    to running :hg:`update`. Listing and retrieving all\n"
+"    subrepositories changes referenced by the parent repository pulled\n"
+"    changesets is expensive at best, impossible in the Subversion\n"
+"    case."
+msgstr ""
+
+msgid ""
+":push: Mercurial will automatically push all subrepositories first\n"
+"    when the parent repository is being pushed. This ensures new\n"
+"    subrepository changes are available when referenced by top-level\n"
+"    repositories."
+msgstr ""
+
+msgid ""
+":status: status does not recurse into subrepositories unless\n"
+"    -S/--subrepos is specified. Subrepository changes are displayed as\n"
+"    regular Mercurial changes on the subrepository\n"
+"    elements. Subversion subrepositories are currently silently\n"
+"    ignored."
+msgstr ""
+
+msgid ""
+":update: update restores the subrepos in the state they were\n"
+"    originally committed in target changeset. If the recorded\n"
+"    changeset is not available in the current subrepository, Mercurial\n"
+"    will pull it in first before updating.  This means that updating\n"
+"    can require network access when using subrepositories."
+msgstr ""
+
+msgid ""
+"Remapping Subrepositories Sources\n"
+"---------------------------------"
+msgstr ""
+
+msgid ""
+"A subrepository source location may change during a project life,\n"
+"invalidating references stored in the parent repository history. To\n"
+"fix this, rewriting rules can be defined in parent repository ``hgrc``\n"
+"file or in Mercurial configuration. See the ``[subpaths]`` section in\n"
+"hgrc(5) for more details."
+msgstr ""
+
+msgid ""
+"Mercurial allows you to customize output of commands through\n"
+"templates. You can either pass in a template from the command\n"
+"line, via the --template option, or select an existing\n"
+"template-style (--style)."
+msgstr ""
+
+msgid ""
+"You can customize output for any \"log-like\" command: log,\n"
+"outgoing, incoming, tip, parents, heads and glog."
+msgstr ""
+
+msgid ""
+"Four styles are packaged with Mercurial: default (the style used\n"
+"when no explicit preference is passed), compact, changelog,\n"
+"and xml.\n"
+"Usage::"
+msgstr ""
+
+msgid "    $ hg log -r1 --style changelog"
+msgstr ""
+
+msgid ""
+"A template is a piece of text, with markup to invoke variable\n"
+"expansion::"
+msgstr ""
+
+msgid ""
+"    $ hg log -r1 --template \"{node}\\n\"\n"
+"    b56ce7b07c52de7d5fd79fb89701ea538af65746"
+msgstr ""
+
+msgid ""
+"Strings in curly braces are called keywords. The availability of\n"
+"keywords depends on the exact context of the templater. These\n"
+"keywords are usually available for templating a log-like command:"
+msgstr ""
+
+msgid ".. keywordsmarker"
+msgstr ""
+
+msgid ""
+"The \"date\" keyword does not produce human-readable output. If you\n"
+"want to use a date in your output, you can use a filter to process\n"
+"it. Filters are functions which return a string based on the input\n"
+"variable. Be sure to use the stringify filter first when you're\n"
+"applying a string-input filter to a list-like input variable.\n"
+"You can also use a chain of filters to get the desired output::"
+msgstr ""
+
+msgid ""
+"   $ hg tip --template \"{date|isodate}\\n\"\n"
+"   2008-08-21 18:22 +0000"
+msgstr ""
+
+msgid "List of filters:"
+msgstr ""
+
+msgid ".. filtersmarker\n"
+msgstr ""
+
+msgid "Valid URLs are of the form::"
+msgstr ""
+
+msgid ""
+"  local/filesystem/path[#revision]\n"
+"  file://local/filesystem/path[#revision]\n"
+"  http://[user[:pass]@]host[:port]/[path][#revision]\n"
+"  https://[user[:pass]@]host[:port]/[path][#revision]\n"
+"  ssh://[user@]host[:port]/[path][#revision]"
+msgstr ""
+
+msgid ""
+"Paths in the local filesystem can either point to Mercurial\n"
+"repositories or to bundle files (as created by :hg:`bundle` or :hg:`\n"
+"incoming --bundle`). See also :hg:`help paths`."
+msgstr ""
+
+msgid ""
+"An optional identifier after # indicates a particular branch, tag, or\n"
+"changeset to use from the remote repository. See also :hg:`help\n"
+"revisions`."
+msgstr ""
+
+msgid ""
+"Some features, such as pushing to http:// and https:// URLs are only\n"
+"possible if the feature is explicitly enabled on the remote Mercurial\n"
+"server."
+msgstr ""
+
+msgid ""
+"Note that the security of HTTPS URLs depends on proper configuration of\n"
+"web.cacerts."
+msgstr ""
+
+msgid "Some notes about using SSH with Mercurial:"
+msgstr ""
+
+msgid ""
+"- SSH requires an accessible shell account on the destination machine\n"
+"  and a copy of hg in the remote path or specified with as remotecmd.\n"
+"- path is relative to the remote user's home directory by default. Use\n"
+"  an extra slash at the start of a path to specify an absolute path::"
+msgstr ""
+
+msgid "    ssh://example.com//tmp/repository"
+msgstr ""
+
+msgid ""
+"- Mercurial doesn't use its own compression via SSH; the right thing\n"
+"  to do is to configure it in your ~/.ssh/config, e.g.::"
+msgstr ""
+
+msgid ""
+"    Host *.mylocalnetwork.example.com\n"
+"      Compression no\n"
+"    Host *\n"
+"      Compression yes"
+msgstr ""
+
+msgid ""
+"  Alternatively specify \"ssh -C\" as your ssh command in your\n"
+"  configuration file or with the --ssh command line option."
+msgstr ""
+
+msgid ""
+"These URLs can all be stored in your configuration file with path\n"
+"aliases under the [paths] section like so::"
+msgstr ""
+
+msgid ""
+"  [paths]\n"
+"  alias1 = URL1\n"
+"  alias2 = URL2\n"
+"  ..."
+msgstr ""
+
+msgid ""
+"You can then use the alias for any command that uses a URL (for\n"
+"example :hg:`pull alias1` will be treated as :hg:`pull URL1`)."
+msgstr ""
+
+msgid ""
+"Two path aliases are special because they are used as defaults when\n"
+"you do not provide the URL to a command:"
+msgstr ""
+
+msgid ""
+"default:\n"
+"  When you create a repository with hg clone, the clone command saves\n"
+"  the location of the source repository as the new repository's\n"
+"  'default' path. This is then used when you omit path from push- and\n"
+"  pull-like commands (including incoming and outgoing)."
+msgstr ""
+
+msgid ""
+"default-push:\n"
+"  The push command will look for a path named 'default-push', and\n"
+"  prefer it over 'default' if both are defined.\n"
+msgstr ""
+
+msgid "remote branch lookup not supported"
+msgstr ""
+
+msgid "dirstate branch not accessible"
+msgstr ""
+
+#, python-format
+msgid "unknown branch '%s'"
+msgstr ""
+
+msgid "can only share local repositories"
+msgstr ""
+
+msgid "destination already exists"
+msgstr ""
+
+msgid "updating working directory\n"
+msgstr ""
+
+#, python-format
+msgid "destination directory: %s\n"
+msgstr ""
+
+#, python-format
+msgid "destination '%s' already exists"
+msgstr ""
+
+#, python-format
+msgid "destination '%s' is not empty"
+msgstr ""
+
+msgid ""
+"src repository does not support revision lookup and so doesn't support clone "
+"by revision"
+msgstr ""
+
+msgid "clone from remote to remote not supported"
+msgstr ""
+
+#, python-format
+msgid "updating to branch %s\n"
+msgstr ""
+
+#, python-format
+msgid ""
+"%d files updated, %d files merged, %d files removed, %d files unresolved\n"
+msgstr ""
+
+msgid "use 'hg resolve' to retry unresolved file merges\n"
+msgstr ""
+
+msgid ""
+"use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to "
+"abandon\n"
+msgstr ""
+
+msgid "(branch merge, don't forget to commit)\n"
+msgstr ""
+
+#, python-format
+msgid "config file %s not found!"
+msgstr ""
+
+#, python-format
+msgid "error reading %s/.hg/hgrc: %s\n"
+msgstr ""
+
+#, python-format
+msgid "error accessing repository at %s\n"
+msgstr ""
+
+msgid "SSL support is unavailable"
+msgstr ""
+
+msgid "IPv6 is not available on this system"
+msgstr ""
+
+#, python-format
+msgid "cannot start server at '%s:%d': %s"
+msgstr ""
+
+#, python-format
+msgid "calling hook %s: %s\n"
+msgstr ""
+
+#, python-format
+msgid "%s hook is invalid (\"%s\" not in a module)"
+msgstr ""
+
+msgid "exception from first failed import attempt:\n"
+msgstr ""
+
+msgid "exception from second failed import attempt:\n"
+msgstr ""
+
+#, python-format
+msgid "%s hook is invalid (import of \"%s\" failed)"
+msgstr ""
+
+#, python-format
+msgid "%s hook is invalid (\"%s\" is not defined)"
+msgstr ""
+
+#, python-format
+msgid "%s hook is invalid (\"%s\" is not callable)"
+msgstr ""
+
+#, python-format
+msgid "error: %s hook failed: %s\n"
+msgstr ""
+
+#, python-format
+msgid "error: %s hook raised an exception: %s\n"
+msgstr ""
+
+#, python-format
+msgid "%s hook failed"
+msgstr ""
+
+#, python-format
+msgid "warning: %s hook failed\n"
+msgstr ""
+
+#, python-format
+msgid "running hook %s: %s\n"
+msgstr ""
+
+#, python-format
+msgid "%s hook %s"
+msgstr ""
+
+#, python-format
+msgid "warning: %s hook %s\n"
+msgstr ""
+
+msgid "kb"
+msgstr ""
+
+#, python-format
+msgid "ignoring invalid [auth] key '%s'\n"
+msgstr ""
+
+msgid "connection ended unexpectedly"
+msgstr ""
+
+#, python-format
+msgid "unsupported URL component: \"%s\""
+msgstr ""
+
+msgid "operation not supported over http"
+msgstr ""
+
+msgid "authorization failed"
+msgstr ""
+
+msgid "http error, possibly caused by proxy setting"
+msgstr ""
+
+#, python-format
+msgid "real URL is %s\n"
+msgstr ""
+
+#, python-format
+msgid ""
+"'%s' does not appear to be an hg repository:\n"
+"---%%<--- (%s)\n"
+"%s\n"
+"---%%<---\n"
+msgstr ""
+
+#, python-format
+msgid "'%s' sent a broken Content-Type header (%s)"
+msgstr ""
+
+#, python-format
+msgid "'%s' uses newer protocol %s"
+msgstr ""
+
+#, python-format
+msgid "push failed: %s"
+msgstr ""
+
+msgid "Python support for SSL and HTTPS is not installed"
+msgstr ""
+
+msgid "cannot create new http repository"
+msgstr ""
+
+#, python-format
+msgid "ignoring invalid syntax '%s'"
+msgstr ""
+
+#, python-format
+msgid "skipping unreadable ignore file '%s': %s\n"
+msgstr ""
+
+#, python-format
+msgid "repository %s not found"
+msgstr "репозиторий %s не найден"
+
+#, python-format
+msgid "repository %s already exists"
+msgstr ""
+
+#, python-format
+msgid "requirement '%s' not supported"
+msgstr ""
+
+#, python-format
+msgid ".hg/sharedpath points to nonexistent directory %s"
+msgstr ""
+
+#, python-format
+msgid "warning: ignoring unknown working parent %s!\n"
+msgstr ""
+
+#, python-format
+msgid "%r cannot be used in a tag name"
+msgstr ""
+
+#, python-format
+msgid "warning: tag %s conflicts with existing branch name\n"
+msgstr ""
+
+msgid "working copy of .hgtags is changed (please commit .hgtags manually)"
+msgstr ""
+
+#, python-format
+msgid "working directory has unknown parent '%s'!"
+msgstr ""
+
+#, python-format
+msgid "unknown revision '%s'"
+msgstr ""
+
+msgid "abandoned transaction found - run hg recover"
+msgstr ""
+
+msgid "rolling back interrupted transaction\n"
+msgstr ""
+
+msgid "no interrupted transaction available\n"
+msgstr ""
+
+#, python-format
+msgid "repository tip rolled back to revision %s (undo %s: %s)\n"
+msgstr ""
+
+#, python-format
+msgid "repository tip rolled back to revision %s (undo %s)\n"
+msgstr ""
+
+msgid "rolling back unknown transaction\n"
+msgstr ""
+
+#, python-format
+msgid "named branch could not be reset, current branch is still: %s\n"
+msgstr ""
+
+#, python-format
+msgid "working directory now based on revisions %d and %d\n"
+msgstr ""
+
+#, python-format
+msgid "working directory now based on revision %d\n"
+msgstr ""
+
+msgid "no rollback information available\n"
+msgstr ""
+
+#, python-format
+msgid "waiting for lock on %s held by %r\n"
+msgstr ""
+
+#, python-format
+msgid "repository %s"
+msgstr ""
+
+#, python-format
+msgid "working directory of %s"
+msgstr ""
+
+#, python-format
+msgid "warning: can't find ancestor for '%s' copied from '%s'!\n"
+msgstr ""
+
+msgid "cannot partially commit a merge (do not specify files or patterns)"
+msgstr ""
+
+msgid "can't commit subrepos without .hgsub"
+msgstr ""
+
+#, python-format
+msgid "uncommitted changes in subrepo %s"
+msgstr ""
+
+msgid "file not found!"
+msgstr ""
+
+msgid "no match under directory!"
+msgstr ""
+
+msgid "file not tracked!"
+msgstr ""
+
+msgid "unresolved merge conflicts (see hg help resolve)"
+msgstr ""
+
+#, python-format
+msgid "committing subrepository %s\n"
+msgstr ""
+
+#, python-format
+msgid "note: commit message saved in %s\n"
+msgstr ""
+
+#, python-format
+msgid "trouble committing %s!\n"
+msgstr ""
+
+msgid "requesting all changes\n"
+msgstr ""
+
+msgid ""
+"partial pull cannot be done because other repository doesn't support "
+"changegroupsubset."
+msgstr ""
+
+#, python-format
+msgid "%d changesets found\n"
+msgstr ""
+
+msgid "bundling"
+msgstr ""
+
+msgid "manifests"
+msgstr ""
+
+#, python-format
+msgid "empty or missing revlog for %s"
+msgstr ""
+
+msgid "adding changesets\n"
+msgstr ""
+
+msgid "chunks"
+msgstr ""
+
+msgid "received changelog group is empty"
+msgstr ""
+
+msgid "adding manifests\n"
+msgstr ""
+
+msgid "adding file changes\n"
+msgstr ""
+
+msgid "received file revlog group is empty"
+msgstr ""
+
+#, python-format
+msgid "missing file data for %s:%s - run hg verify"
+msgstr ""
+
+#, python-format
+msgid " (%+d heads)"
+msgstr ""
+
+#, python-format
+msgid "added %d changesets with %d changes to %d files%s\n"
+msgstr ""
+
+msgid "Unexpected response from remote server:"
+msgstr ""
+
+msgid "operation forbidden by server"
+msgstr ""
+
+msgid "locking the remote repository failed"
+msgstr ""
+
+msgid "the server sent an unknown error code"
+msgstr ""
+
+msgid "streaming all changes\n"
+msgstr ""
+
+#, python-format
+msgid "%d files to transfer, %s of data\n"
+msgstr ""
+
+#, python-format
+msgid "transferred %s in %.1f seconds (%s/sec)\n"
+msgstr ""
+
+msgid "can't use TLS: Python SSL support not installed"
+msgstr ""
+
+msgid "(using smtps)\n"
+msgstr ""
+
+msgid "smtp.host not configured - cannot send mail"
+msgstr ""
+
+#, python-format
+msgid "sending mail: smtp host %s, port %s\n"
+msgstr ""
+
+msgid "(using starttls)\n"
+msgstr ""
+
+#, python-format
+msgid "(authenticating to mail server as %s)\n"
+msgstr ""
+
+#, python-format
+msgid "sending mail: %s\n"
+msgstr ""
+
+msgid "smtp specified as email transport, but no smtp host configured"
+msgstr ""
+
+#, python-format
+msgid "%r specified as email transport, but not in PATH"
+msgstr ""
+
+#, python-format
+msgid "ignoring invalid sendcharset: %s\n"
+msgstr ""
+
+#, python-format
+msgid "invalid email address: %s"
+msgstr ""
+
+#, python-format
+msgid "invalid local address: %s"
+msgstr ""
+
+#, python-format
+msgid "'\\n' and '\\r' disallowed in filenames: %r"
+msgstr ""
+
+#, python-format
+msgid "failed to remove %s from manifest"
+msgstr ""
+
+#, python-format
+msgid "invalid pattern (%s): %s"
+msgstr ""
+
+msgid "invalid pattern"
+msgstr ""
+
+#, python-format
+msgid "unable to read file list (%s)"
+msgstr ""
+
+#, python-format
+msgid "diff context lines count must be an integer, not %r"
+msgstr ""
+
+#, python-format
+msgid ""
+"untracked file in working directory differs from file in requested revision: "
+"'%s'"
+msgstr ""
+
+#, python-format
+msgid "case-folding collision between %s and %s"
+msgstr ""
+
+#, python-format
+msgid ""
+" conflicting flags for %s\n"
+"(n)one, e(x)ec or sym(l)ink?"
+msgstr ""
+
+msgid "&None"
+msgstr ""
+
+msgid "E&xec"
+msgstr ""
+
+msgid "Sym&link"
+msgstr ""
+
+msgid "resolving manifests\n"
+msgstr ""
+
+#, python-format
+msgid ""
+" local changed %s which remote deleted\n"
+"use (c)hanged version or (d)elete?"
+msgstr ""
+
+msgid "&Changed"
+msgstr ""
+
+msgid "&Delete"
+msgstr ""
+
+#, python-format
+msgid ""
+"remote changed %s which local deleted\n"
+"use (c)hanged version or leave (d)eleted?"
+msgstr ""
+
+msgid "&Deleted"
+msgstr ""
+
+msgid "updating"
+msgstr ""
+
+#, python-format
+msgid "update failed to remove %s: %s!\n"
+msgstr ""
+
+#, python-format
+msgid "getting %s\n"
+msgstr ""
+
+#, python-format
+msgid "getting %s to %s\n"
+msgstr ""
+
+#, python-format
+msgid "note: possible conflict - %s was renamed multiple times to:\n"
+msgstr ""
+
+msgid "merging with a working directory ancestor has no effect"
+msgstr ""
+
+msgid "nothing to merge (use 'hg update' or check 'hg heads')"
+msgstr ""
+
+msgid "outstanding uncommitted changes (use 'hg status' to list changes)"
+msgstr ""
+
+#, python-format
+msgid "outstanding uncommitted changes in subrepository '%s'"
+msgstr ""
+
+msgid "crosses branches (merge branches or use --clean to discard changes)"
+msgstr ""
+
+msgid "crosses branches (merge branches or use --check to force update)"
+msgstr ""
+
+msgid "Attention:"
+msgstr ""
+
+msgid "Caution:"
+msgstr ""
+
+msgid "!Danger!"
+msgstr ""
+
+msgid "Error:"
+msgstr ""
+
+msgid "Hint:"
+msgstr ""
+
+msgid "Important:"
+msgstr ""
+
+msgid "Note:"
+msgstr "Примечание:"
+
+msgid "Tip:"
+msgstr ""
+
+msgid "Warning!"
+msgstr ""
+
+#, python-format
+msgid "%d out of %d hunks FAILED -- saving rejects to file %s\n"
+msgstr ""
+
+#, python-format
+msgid "cannot create %s: destination already exists"
+msgstr ""
+
+#, fuzzy, python-format
+msgid "cannot create %s: unable to create destination directory"
+msgstr "ветвь с таким именем уже существует"
+
+#, python-format
+msgid "unable to find '%s' for patching\n"
+msgstr ""
+
+#, python-format
+msgid "patching file %s\n"
+msgstr "применяется патч к файлу %s\n"
+
+#, python-format
+msgid "bad hunk #%d %s (%d %d %d %d)"
+msgstr "плохая полоса #%d %s (%d %d %d %d)"
+
+#, python-format
+msgid "file %s already exists\n"
+msgstr "файл %s уже существует\n"
+
+#, python-format
+msgid "Hunk #%d succeeded at %d with fuzz %d (offset %d lines).\n"
+msgstr ""
+"Полоса #%d была успешной для %d с погрешностью %d (смещение %d строк).\n"
+
+#, python-format
+msgid "Hunk #%d succeeded at %d (offset %d lines).\n"
+msgstr "Полоса #%d была успешной для %d (смещение %d строк).\n"
+
+#, python-format
+msgid "Hunk #%d FAILED at %d\n"
+msgstr "Полоса #%d НЕУДАЧНА для %d\n"
+
+#, python-format
+msgid "bad hunk #%d"
+msgstr "плохая полоса #%d"
+
+#, python-format
+msgid "bad hunk #%d old text line %d"
+msgstr "плохая полоса #%d старая строка текста %d"
+
+msgid "could not extract binary patch"
+msgstr "невозможно извлечь двоичную заплатку"
+
+#, python-format
+msgid "binary patch is %d bytes, not %d"
+msgstr "двоичный патч иммеет размер %d байтов, а не %d"
+
+#, python-format
+msgid "unable to strip away %d of %d dirs from %s"
+msgstr ""
+
+msgid "undefined source and destination files"
+msgstr ""
+
+#, python-format
+msgid "unsupported parser state: %s"
+msgstr ""
+
+#, python-format
+msgid "patch command failed: %s"
+msgstr ""
+
+#, python-format
+msgid "unsupported line endings type: %s"
+msgstr ""
+
+msgid "patch failed to apply"
+msgstr ""
+
+#, python-format
+msgid " %d files changed, %d insertions(+), %d deletions(-)\n"
+msgstr ""
+
+#, python-format
+msgid "exited with status %d"
+msgstr ""
+
+#, python-format
+msgid "killed by signal %d"
+msgstr ""
+
+#, python-format
+msgid "saved backup bundle to %s\n"
+msgstr ""
+
+msgid "adding branch\n"
+msgstr ""
+
+#, python-format
+msgid "strip failed, full bundle stored in '%s'\n"
+msgstr ""
+
+#, python-format
+msgid "strip failed, partial bundle stored in '%s'\n"
+msgstr ""
+
+#, python-format
+msgid "cannot %s; remote repository does not support the %r capability"
+msgstr ""
+
+#, python-format
+msgid "unknown compression type %r"
+msgstr ""
+
+msgid "index entry flags need RevlogNG"
+msgstr ""
+
+#, python-format
+msgid "index %s unknown flags %#04x for format v0"
+msgstr ""
+
+#, python-format
+msgid "index %s unknown flags %#04x for revlogng"
+msgstr ""
+
+#, python-format
+msgid "index %s unknown format %d"
+msgstr ""
+
+#, python-format
+msgid "index %s is corrupted"
+msgstr ""
+
+msgid "no node"
+msgstr ""
+
+msgid "ambiguous identifier"
+msgstr ""
+
+msgid "no match found"
+msgstr ""
+
+#, python-format
+msgid "incompatible revision flag %x"
+msgstr ""
+
+#, python-format
+msgid "%s not found in the transaction"
+msgstr ""
+
+msgid "consistency error in delta"
+msgstr ""
+
+msgid "unknown delta base"
+msgstr ""
+
+msgid "unterminated string"
+msgstr ""
+
+msgid "syntax error"
+msgstr ""
+
+msgid "missing argument"
+msgstr ""
+
+#, python-format
+msgid "can't use %s here"
+msgstr ""
+
+msgid "can't use a list in this context"
+msgstr ""
+
+#, python-format
+msgid "not a function: %s"
+msgstr ""
+
+msgid ""
+"``adds(pattern)``\n"
+"    Changesets that add a file matching pattern."
+msgstr ""
+
+#. i18n: "adds" is a keyword
+msgid "adds requires a pattern"
+msgstr ""
+
+msgid ""
+"``ancestor(single, single)``\n"
+"    Greatest common ancestor of the two changesets."
+msgstr ""
+
+#. i18n: "ancestor" is a keyword
+msgid "ancestor requires two arguments"
+msgstr ""
+
+#. i18n: "ancestor" is a keyword
+msgid "ancestor arguments must be single revisions"
+msgstr ""
+
+msgid ""
+"``ancestors(set)``\n"
+"    Changesets that are ancestors of a changeset in set."
+msgstr ""
+
+msgid "~ expects a number"
+msgstr ""
+
+msgid ""
+"``author(string)``\n"
+"    Alias for ``user(string)``."
+msgstr ""
+
+#. i18n: "author" is a keyword
+msgid "author requires a string"
+msgstr ""
+
+msgid ""
+"``bisected(string)``\n"
+"    Changesets marked in the specified bisect state (good, bad, skip)."
+msgstr ""
+
+msgid "bisect requires a string"
+msgstr ""
+
+msgid "invalid bisect state"
+msgstr ""
+
+msgid ""
+"``bookmark([name])``\n"
+"    The named bookmark or all bookmarks."
+msgstr ""
+
+#. i18n: "bookmark" is a keyword
+msgid "bookmark takes one or no arguments"
+msgstr ""
+
+#. i18n: "bookmark" is a keyword
+msgid "the argument to bookmark must be a string"
+msgstr ""
+
+msgid ""
+"``branch(string or set)``\n"
+"    All changesets belonging to the given branch or the branches of the "
+"given\n"
+"    changesets."
+msgstr ""
+
+msgid ""
+"``children(set)``\n"
+"    Child changesets of changesets in set."
+msgstr ""
+
+msgid ""
+"``closed()``\n"
+"    Changeset is closed."
+msgstr ""
+
+#. i18n: "closed" is a keyword
+msgid "closed takes no arguments"
+msgstr ""
+
+msgid ""
+"``contains(pattern)``\n"
+"    Revision contains a file matching pattern. See :hg:`help patterns`\n"
+"    for information about file patterns."
+msgstr ""
+
+#. i18n: "contains" is a keyword
+msgid "contains requires a pattern"
+msgstr ""
+
+msgid ""
+"``date(interval)``\n"
+"    Changesets within the interval, see :hg:`help dates`."
+msgstr ""
+
+#. i18n: "date" is a keyword
+msgid "date requires a string"
+msgstr ""
+
+msgid ""
+"``descendants(set)``\n"
+"    Changesets which are descendants of changesets in set."
+msgstr ""
+
+msgid ""
+"``filelog(pattern)``\n"
+"    Changesets connected to the specified filelog."
+msgstr ""
+
+msgid "filelog requires a pattern"
+msgstr ""
+
+msgid ""
+"``follow([file])``\n"
+"    An alias for ``::.`` (ancestors of the working copy's first parent).\n"
+"    If a filename is specified, the history of the given file is followed,\n"
+"    including copies."
+msgstr ""
+
+#. i18n: "follow" is a keyword
+msgid "follow takes no arguments or a filename"
+msgstr ""
+
+#. i18n: "follow" is a keyword
+msgid "follow takes no arguments"
+msgstr ""
+
+msgid ""
+"``all()``\n"
+"    All changesets, the same as ``0:tip``."
+msgstr ""
+
+#. i18n: "all" is a keyword
+msgid "all takes no arguments"
+msgstr ""
+
+msgid ""
+"``grep(regex)``\n"
+"    Like ``keyword(string)`` but accepts a regex. Use ``grep(r'...')``\n"
+"    to ensure special escape characters are handled correctly. Unlike\n"
+"    ``keyword(string)``, the match is case-sensitive."
+msgstr ""
+
+#. i18n: "grep" is a keyword
+msgid "grep requires a string"
+msgstr ""
+
+#, python-format
+msgid "invalid match pattern: %s"
+msgstr ""
+
+msgid ""
+"``file(pattern)``\n"
+"    Changesets affecting files matched by pattern."
+msgstr ""
+
+#. i18n: "file" is a keyword
+msgid "file requires a pattern"
+msgstr ""
+
+msgid ""
+"``head()``\n"
+"    Changeset is a named branch head."
+msgstr ""
+
+#. i18n: "head" is a keyword
+msgid "head takes no arguments"
+msgstr ""
+
+msgid ""
+"``heads(set)``\n"
+"    Members of set with no children in set."
+msgstr ""
+
+msgid ""
+"``keyword(string)``\n"
+"    Search commit message, user name, and names of changed files for\n"
+"    string. The match is case-insensitive."
+msgstr ""
+
+#. i18n: "keyword" is a keyword
+msgid "keyword requires a string"
+msgstr ""
+
+msgid ""
+"``limit(set, n)``\n"
+"    First n members of set."
+msgstr ""
+
+#. i18n: "limit" is a keyword
+msgid "limit requires two arguments"
+msgstr ""
+
+#. i18n: "limit" is a keyword
+msgid "limit requires a number"
+msgstr ""
+
+#. i18n: "limit" is a keyword
+msgid "limit expects a number"
+msgstr ""
+
+msgid ""
+"``last(set, n)``\n"
+"    Last n members of set."
+msgstr ""
+
+#. i18n: "last" is a keyword
+msgid "last requires two arguments"
+msgstr ""
+
+#. i18n: "last" is a keyword
+msgid "last requires a number"
+msgstr ""
+
+#. i18n: "last" is a keyword
+msgid "last expects a number"
+msgstr ""
+
+msgid ""
+"``max(set)``\n"
+"    Changeset with highest revision number in set."
+msgstr ""
+
+msgid ""
+"``merge()``\n"
+"    Changeset is a merge changeset."
+msgstr ""
+
+#. i18n: "merge" is a keyword
+msgid "merge takes no arguments"
+msgstr ""
+
+msgid ""
+"``min(set)``\n"
+"    Changeset with lowest revision number in set."
+msgstr ""
+
+msgid ""
+"``modifies(pattern)``\n"
+"    Changesets modifying files matched by pattern."
+msgstr ""
+
+#. i18n: "modifies" is a keyword
+msgid "modifies requires a pattern"
+msgstr ""
+
+msgid ""
+"``id(string)``\n"
+"    Revision non-ambiguously specified by the given hex string prefix."
+msgstr ""
+
+#. i18n: "id" is a keyword
+msgid "id requires one argument"
+msgstr ""
+
+#. i18n: "id" is a keyword
+msgid "id requires a string"
+msgstr ""
+
+msgid ""
+"``outgoing([path])``\n"
+"    Changesets not found in the specified destination repository, or the\n"
+"    default push location."
+msgstr ""
+
+#. i18n: "outgoing" is a keyword
+msgid "outgoing requires a repository path"
+msgstr ""
+
+msgid ""
+"``p1([set])``\n"
+"    First parent of changesets in set, or the working directory."
+msgstr ""
+
+msgid ""
+"``p2([set])``\n"
+"    Second parent of changesets in set, or the working directory."
+msgstr ""
+
+msgid ""
+"``parents([set])``\n"
+"    The set of all parents for all changesets in set, or the working "
+"directory."
+msgstr ""
+
+msgid "^ expects a number 0, 1, or 2"
+msgstr ""
+
+msgid ""
+"``present(set)``\n"
+"    An empty set, if any revision in set isn't found; otherwise,\n"
+"    all revisions in set."
+msgstr ""
+
+msgid ""
+"``removes(pattern)``\n"
+"    Changesets which remove files matching pattern."
+msgstr ""
+
+#. i18n: "removes" is a keyword
+msgid "removes requires a pattern"
+msgstr ""
+
+msgid ""
+"``rev(number)``\n"
+"    Revision with the given numeric identifier."
+msgstr ""
+
+#. i18n: "rev" is a keyword
+msgid "rev requires one argument"
+msgstr ""
+
+#. i18n: "rev" is a keyword
+msgid "rev requires a number"
+msgstr ""
+
+#. i18n: "rev" is a keyword
+msgid "rev expects a number"
+msgstr ""
+
+msgid ""
+"``reverse(set)``\n"
+"    Reverse order of set."
+msgstr ""
+
+msgid ""
+"``roots(set)``\n"
+"    Changesets with no parent changeset in set."
+msgstr ""
+
+msgid ""
+"``sort(set[, [-]key...])``\n"
+"    Sort set by keys. The default sort order is ascending, specify a key\n"
+"    as ``-key`` to sort in descending order."
+msgstr ""
+
+msgid "    The keys can be:"
+msgstr ""
+
+msgid ""
+"    - ``rev`` for the revision number,\n"
+"    - ``branch`` for the branch name,\n"
+"    - ``desc`` for the commit message (description),\n"
+"    - ``user`` for user name (``author`` can be used as an alias),\n"
+"    - ``date`` for the commit date"
+msgstr ""
+
+#. i18n: "sort" is a keyword
+msgid "sort requires one or two arguments"
+msgstr ""
+
+msgid "sort spec must be a string"
+msgstr ""
+
+#, python-format
+msgid "unknown sort key %r"
+msgstr ""
+
+msgid ""
+"``tag([name])``\n"
+"    The specified tag by name, or all tagged revisions if no name is given."
+msgstr ""
+
+#. i18n: "tag" is a keyword
+msgid "tag takes one or no arguments"
+msgstr ""
+
+#. i18n: "tag" is a keyword
+msgid "the argument to tag must be a string"
+msgstr ""
+
+msgid ""
+"``user(string)``\n"
+"    User name contains string. The match is case-insensitive."
+msgstr ""
+
+msgid "can't negate that"
+msgstr ""
+
+msgid "not a symbol"
+msgstr ""
+
+msgid "empty query"
+msgstr ""
+
+#, python-format
+msgid "ui.portablefilenames value is invalid ('%s')"
+msgstr ""
+
+#, python-format
+msgid "possible case-folding collision for %s"
+msgstr ""
+
+#, python-format
+msgid "path ends in directory separator: %s"
+msgstr ""
+
+#, python-format
+msgid "path contains illegal component: %s"
+msgstr ""
+
+#, python-format
+msgid "path %r is inside nested repo %r"
+msgstr ""
+
+#, python-format
+msgid "path %r traverses symbolic link %r"
+msgstr ""
+
+#, python-format
+msgid "could not symlink to %r: %s"
+msgstr ""
+
+#, python-format
+msgid "recording removal of %s as rename to %s (%d%% similar)\n"
+msgstr ""
+
+#, python-format
+msgid "%s has not been committed yet, so no copy data will be stored for %s.\n"
+msgstr ""
+
+msgid "searching for changes\n"
+msgstr ""
+
+msgid "queries"
+msgstr ""
+
+msgid "searching"
+msgstr ""
+
+msgid "repository is unrelated"
+msgstr ""
+
+msgid "warning: repository is unrelated\n"
+msgstr ""
+
+msgid "searching for exact renames"
+msgstr ""
+
+msgid "searching for similar files"
+msgstr ""
+
+#, python-format
+msgid "%s looks like a binary file."
+msgstr ""
+
+msgid "can only specify two labels."
+msgstr ""
+
+msgid "warning: conflicts during merge.\n"
+msgstr ""
+
+#, python-format
+msgid "couldn't parse location %s"
+msgstr ""
+
+msgid "password in URL not supported"
+msgstr ""
+
+msgid "could not create remote repo"
+msgstr ""
+
+msgid "no suitable response from remote hg"
+msgstr ""
+
+msgid "remote: "
+msgstr ""
+
+msgid "unexpected response:"
+msgstr ""
+
+#, python-format
+msgid "push refused: %s"
+msgstr ""
+
+msgid "certificate checking requires Python 2.6"
+msgstr ""
+
+msgid "no certificate received"
+msgstr ""
+
+#, python-format
+msgid "certificate is for %s"
+msgstr ""
+
+msgid "IDN in certificate not supported"
+msgstr ""
+
+msgid "no commonName or subjectAltName found in certificate"
+msgstr ""
+
+#, python-format
+msgid "could not find web.cacerts: %s"
+msgstr ""
+
+#, python-format
+msgid "%s certificate error: %s (use --insecure to connect insecurely)"
+msgstr ""
+
+#, python-format
+msgid "invalid certificate for %s with fingerprint %s"
+msgstr ""
+
+#, python-format
+msgid ""
+"warning: %s certificate with fingerprint %s not verified (check "
+"hostfingerprints or web.cacerts config setting)\n"
+msgstr ""
+
+#, python-format
+msgid "no certificate for %s with configured hostfingerprint"
+msgstr ""
+
+#, python-format
+msgid ""
+"warning: %s certificate not verified (check web.cacerts config setting)\n"
+msgstr ""
+
+#, python-format
+msgid "'%s' does not appear to be an hg repository"
+msgstr ""
+
+msgid "cannot lock static-http repository"
+msgstr ""
+
+msgid "cannot create new static-http repository"
+msgstr ""
+
+#, python-format
+msgid "invalid entry in fncache, line %s"
+msgstr ""
+
+#, python-format
+msgid "warning: subrepo spec file %s not found\n"
+msgstr ""
+
+#, python-format
+msgid "subrepo spec file %s not found"
+msgstr ""
+
+msgid "missing ] in subrepo source"
+msgstr ""
+
+#, python-format
+msgid "bad subrepository pattern in %s: %s"
+msgstr ""
+
+#, python-format
+msgid ""
+" subrepository sources for %s differ\n"
+"use (l)ocal source (%s) or (r)emote source (%s)?"
+msgstr ""
+
+msgid "&Remote"
+msgstr ""
+
+#, python-format
+msgid ""
+" local changed subrepository %s which remote removed\n"
+"use (c)hanged version or (d)elete?"
+msgstr ""
+
+#, python-format
+msgid ""
+" remote changed subrepository %s which local removed\n"
+"use (c)hanged version or (d)elete?"
+msgstr ""
+
+#, python-format
+msgid ""
+" subrepository sources for %s differ\n"
+"use (l)ocal source (%s) or (r)emote source (%s)?\n"
+msgstr ""
+
+#, python-format
+msgid ""
+" subrepository sources for %s differ (in checked out version)\n"
+"use (l)ocal source (%s) or (r)emote source (%s)?\n"
+msgstr ""
+
+#, python-format
+msgid "default path for subrepository %s not found"
+msgstr ""
+
+#, python-format
+msgid "unknown subrepo type %s"
+msgstr ""
+
+#, python-format
+msgid "archiving (%s)"
+msgstr ""
+
+#, python-format
+msgid "warning: error \"%s\" in subrepository \"%s\"\n"
+msgstr ""
+
+#, python-format
+msgid "removing subrepo %s\n"
+msgstr ""
+
+#, python-format
+msgid "cloning subrepo %s from %s\n"
+msgstr ""
+
+#, python-format
+msgid "pulling subrepo %s from %s\n"
+msgstr ""
+
+#, python-format
+msgid "pushing subrepo %s to %s\n"
+msgstr ""
+
+msgid "cannot retrieve svn tool version"
+msgstr ""
+
+msgid "cannot commit svn externals"
+msgstr ""
+
+#, python-format
+msgid "not removing repo %s because it has changes.\n"
+msgstr ""
+
+#, python-format
+msgid "revision %s does not exist in subrepo %s\n"
+msgstr ""
+
+#, python-format
+msgid "checking out detached HEAD in subrepo %s\n"
+msgstr ""
+
+msgid "check out a git branch if you intend to make changes\n"
+msgstr ""
+
+#, python-format
+msgid "subrepo %s is missing"
+msgstr ""
+
+#, python-format
+msgid "unrelated git branch checked out in subrepo %s\n"
+msgstr ""
+
+#, python-format
+msgid "pushing branch %s of subrepo %s\n"
+msgstr ""
+
+#, python-format
+msgid ""
+"no branch checked out in subrepo %s\n"
+"cannot push revision %s"
+msgstr ""
+
+#, python-format
+msgid "%s, line %s: %s\n"
+msgstr ""
+
+msgid "cannot parse entry"
+msgstr ""
+
+#, python-format
+msgid "node '%s' is not well formed"
+msgstr ""
+
+msgid ".hg/cache/tags is corrupt, rebuilding it\n"
+msgstr ""
+
+#, python-format
+msgid "unknown method '%s'"
+msgstr ""
+
+msgid "expected a symbol"
+msgstr ""
+
+#, python-format
+msgid "unknown function '%s'"
+msgstr ""
+
+msgid "expected template specifier"
+msgstr ""
+
+#, python-format
+msgid "filter %s expects one argument"
+msgstr ""
+
+msgid "unmatched quotes"
+msgstr ""
+
+#, python-format
+msgid "style not found: %s"
+msgstr ""
+
+#, python-format
+msgid "\"%s\" not in template map"
+msgstr ""
+
+#, python-format
+msgid "template file %s: %s"
+msgstr ""
+
+msgid "cannot use transaction when it is already committed/aborted"
+msgstr ""
+
+#, python-format
+msgid "failed to truncate %s\n"
+msgstr ""
+
+msgid "transaction abort!\n"
+msgstr ""
+
+msgid "rollback completed\n"
+msgstr ""
+
+msgid "rollback failed - please run hg recover\n"
+msgstr ""
+
+msgid "already have changeset "
+msgstr ""
+
+#, python-format
+msgid "Not trusting file %s from untrusted user %s, group %s\n"
+msgstr ""
+
+#, python-format
+msgid "Ignored: %s\n"
+msgstr ""
+
+#, python-format
+msgid "(deprecated '%%' in path %s=%s from %s)\n"
+msgstr ""
+
+#, python-format
+msgid "ignoring untrusted configuration option %s.%s = %s\n"
+msgstr ""
+
+#, python-format
+msgid "%s.%s is not a boolean ('%s')"
+msgstr ""
+
+#, python-format
+msgid "%s.%s is not an integer ('%s')"
+msgstr ""
+
+msgid "enter a commit username:"
+msgstr ""
+
+#, python-format
+msgid "No username found, using '%s' instead\n"
+msgstr ""
+
+msgid "no username supplied (see \"hg help config\")"
+msgstr ""
+
+#, python-format
+msgid "username %s contains a newline\n"
+msgstr ""
+
+msgid "response expected"
+msgstr "ожидается ответ"
+
+msgid "unrecognized response\n"
+msgstr "не распознанный ответ\n"
+
+msgid "password: "
+msgstr "пароль: "
+
+msgid "edit failed"
+msgstr "неудача при редактировании"
+
+msgid "http authorization required"
+msgstr ""
+
+msgid "http authorization required\n"
+msgstr ""
+
+#, python-format
+msgid "realm: %s\n"
+msgstr ""
+
+#, python-format
+msgid "user: %s\n"
+msgstr ""
+
+msgid "user:"
+msgstr "пользователь:"
+
+#, python-format
+msgid "http auth: user %s, password %s\n"
+msgstr ""
+
+#, python-format
+msgid "command '%s' failed: %s"
+msgstr ""
+
+#, python-format
+msgid "filename contains '%s', which is reserved on Windows"
+msgstr ""
+
+#, python-format
+msgid "filename contains %r, which is invalid on Windows"
+msgstr ""
+
+#, python-format
+msgid "filename ends with '%s', which is not allowed on Windows"
+msgstr ""
+
+msgid "check your clock"
+msgstr ""
+
+#, python-format
+msgid "negative timestamp: %d"
+msgstr ""
+
+#, python-format
+msgid "invalid date: %r"
+msgstr ""
+
+#, python-format
+msgid "date exceeds 32 bits: %d"
+msgstr ""
+
+#, python-format
+msgid "negative date value: %d"
+msgstr ""
+
+#, python-format
+msgid "impossible time zone offset: %d"
+msgstr ""
+
+msgid "dates cannot consist entirely of whitespace"
+msgstr ""
+
+msgid "invalid day spec, use '<DATE'"
+msgstr ""
+
+msgid "invalid day spec, use '>DATE'"
+msgstr ""
+
+#, python-format
+msgid "invalid day spec: %s"
+msgstr ""
+
+#, python-format
+msgid "%s must be nonnegative (see 'hg help dates')"
+msgstr ""
+
+#, python-format
+msgid "%.0f GB"
+msgstr ""
+
+#, python-format
+msgid "%.1f GB"
+msgstr ""
+
+#, python-format
+msgid "%.2f GB"
+msgstr ""
+
+#, python-format
+msgid "%.0f MB"
+msgstr ""
+
+#, python-format
+msgid "%.1f MB"
+msgstr ""
+
+#, python-format
+msgid "%.2f MB"
+msgstr ""
+
+#, python-format
+msgid "%.0f KB"
+msgstr ""
+
+#, python-format
+msgid "%.1f KB"
+msgstr ""
+
+#, python-format
+msgid "%.2f KB"
+msgstr ""
+
+#, python-format
+msgid "%.0f bytes"
+msgstr ""
+
+#, python-format
+msgid "no port number associated with service '%s'"
+msgstr ""
+
+msgid "file:// URLs can only refer to localhost"
+msgstr ""
+
+msgid "cannot verify bundle or remote repos"
+msgstr ""
+
+msgid "interrupted"
+msgstr ""
+
+#, python-format
+msgid "empty or missing %s"
+msgstr ""
+
+#, python-format
+msgid "data length off by %d bytes"
+msgstr ""
+
+#, python-format
+msgid "index contains %d extra bytes"
+msgstr ""
+
+#, python-format
+msgid "warning: `%s' uses revlog format 1"
+msgstr ""
+
+#, python-format
+msgid "warning: `%s' uses revlog format 0"
+msgstr ""
+
+#, python-format
+msgid "rev %d points to nonexistent changeset %d"
+msgstr ""
+
+#, python-format
+msgid "rev %d points to unexpected changeset %d"
+msgstr ""
+
+#, python-format
+msgid " (expected %s)"
+msgstr ""
+
+#, python-format
+msgid "unknown parent 1 %s of %s"
+msgstr ""
+
+#, python-format
+msgid "unknown parent 2 %s of %s"
+msgstr ""
+
+#, python-format
+msgid "checking parents of %s"
+msgstr ""
+
+#, python-format
+msgid "duplicate revision %d (%d)"
+msgstr ""
+
+msgid "abandoned transaction found - run hg recover\n"
+msgstr ""
+
+#, python-format
+msgid "repository uses revlog format %d\n"
+msgstr ""
+
+msgid "checking changesets\n"
+msgstr ""
+
+msgid "checking"
+msgstr ""
+
+#, python-format
+msgid "unpacking changeset %s"
+msgstr ""
+
+msgid "checking manifests\n"
+msgstr ""
+
+#, python-format
+msgid "%s not in changesets"
+msgstr ""
+
+msgid "file without name in manifest"
+msgstr ""
+
+#, python-format
+msgid "reading manifest delta %s"
+msgstr ""
+
+msgid "crosschecking files in changesets and manifests\n"
+msgstr ""
+
+msgid "crosschecking"
+msgstr ""
+
+#, python-format
+msgid "changeset refers to unknown manifest %s"
+msgstr ""
+
+msgid "in changeset but not in manifest"
+msgstr ""
+
+msgid "in manifest but not in changeset"
+msgstr ""
+
+msgid "checking files\n"
+msgstr ""
+
+#, python-format
+msgid "cannot decode filename '%s'"
+msgstr ""
+
+#, python-format
+msgid "broken revlog! (%s)"
+msgstr ""
+
+msgid "missing revlog!"
+msgstr ""
+
+#, python-format
+msgid "%s not in manifests"
+msgstr ""
+
+#, python-format
+msgid "unpacked size is %s, %s expected"
+msgstr ""
+
+#, python-format
+msgid "unpacking %s"
+msgstr ""
+
+#, python-format
+msgid "warning: copy source of '%s' not in parents of %s"
+msgstr ""
+
+#, python-format
+msgid "empty or missing copy source revlog %s:%s"
+msgstr ""
+
+#, python-format
+msgid "warning: %s@%s: copy source revision is nullid %s:%s\n"
+msgstr ""
+
+#, python-format
+msgid "checking rename of %s"
+msgstr ""
+
+#, python-format
+msgid "%s in manifests not found"
+msgstr ""
+
+#, python-format
+msgid "warning: orphan revlog '%s'"
+msgstr ""
+
+#, python-format
+msgid "%d files, %d changesets, %d total revisions\n"
+msgstr ""
+
+#, python-format
+msgid "%d warnings encountered!\n"
+msgstr ""
+
+#, python-format
+msgid "%d integrity errors encountered!\n"
+msgstr ""
+
+#, python-format
+msgid "(first damaged changeset appears to be %d)\n"
+msgstr ""
+
+msgid "look up remote revision"
+msgstr ""
+
+msgid "push failed (unexpected response):"
+msgstr ""
+
+msgid "look up remote changes"
+msgstr ""
+
+msgid "push failed:"
+msgstr ""
+
+#~ msgid "specify merge tool for rebase"
+#~ msgstr "задать программу для слияния при перебазировании"
+
+#, fuzzy
+#~ msgid "can't specify a revision with --all"
+#~ msgstr "пожалуйста, укажите ревизию для отмены"
+
+#, fuzzy
+#~ msgid "Supported arguments:"
+#~ msgstr "несовместимые аргументы"
+
+#, fuzzy
+#~ msgid ""
+#~ "``git``\n"
+#~ "    Use git extended diff format."
+#~ msgstr "использовать расширенный формат git для diff'ов"
+
+#, fuzzy
+#~ msgid ""
+#~ "``showfunc``\n"
+#~ "    Show which function each change is in."
+#~ msgstr "для каждого изменения показать, в какой оно сделано функции"
+
+#, fuzzy
+#~ msgid ""
+#~ "``ignorews``\n"
+#~ "    Ignore white space when comparing lines."
+#~ msgstr "игнорировать пробельные символы при сравнении строк"
+
+#, fuzzy
+#~ msgid ""
+#~ "``ignorewsamount``\n"
+#~ "    Ignore changes in the amount of white space."
+#~ msgstr "игнорировать изменения в количестве пробельных символов"
+
+#, fuzzy
+#~ msgid ""
+#~ "``ignoreblanklines``\n"
+#~ "    Ignore changes whose lines are all blank."
+#~ msgstr "игнорировать пустые строки"
+
+#, fuzzy
+#~ msgid ""
+#~ "``unified``\n"
+#~ "    Number of lines of context to show."
+#~ msgstr "показываемое количество строк контекста"
+
+#, fuzzy
+#~ msgid "The full set of options is:"
+#~ msgstr "Первая хорошая ревизия:\n"
+
+#, fuzzy
+#~ msgid ""
+#~ "``prefix``\n"
+#~ "    Prefix path to serve from. Default is '' (server root)."
+#~ msgstr ""
+#~ "префикс пути для предоставления доступа (по умолчанию: в корне сервера)"
+
+#, fuzzy
+#~ msgid ""
+#~ "``style``\n"
+#~ "    Which template map style to use."
+#~ msgstr "используемый стиль шаблона"
+
+#, fuzzy
+#~ msgid "cannot patch %s: file is not tracked"
+#~ msgstr "%s не удален, он и так не отслеживается\n"
--- a/mercurial/ancestor.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/ancestor.py	Sat Jun 18 17:03:01 2011 -0500
@@ -9,9 +9,10 @@
 
 def ancestor(a, b, pfunc):
     """
-    return a minimal-distance ancestor of nodes a and b, or None if there is no
-    such ancestor. Note that there can be several ancestors with the same
-    (minimal) distance, and the one returned is arbitrary.
+    Returns the common ancestor of a and b that is furthest from a
+    root (as measured by longest path) or None if no ancestor is
+    found. If there are multiple common ancestors at the same
+    distance, the first one found is returned.
 
     pfunc must return a list of parent vertices for a given vertex
     """
@@ -22,6 +23,7 @@
     a, b = sorted([a, b])
 
     # find depth from root of all ancestors
+    # depth is stored as a negative for heapq
     parentcache = {}
     visit = [a, b]
     depth = {}
@@ -39,6 +41,7 @@
                 if p not in depth:
                     visit.append(p)
             if visit[-1] == vertex:
+                # -(maximum distance of parents + 1)
                 depth[vertex] = min([depth[p] for p in pl]) - 1
                 visit.pop()
 
@@ -73,7 +76,7 @@
     # increment each ancestor list until it is closer to root than
     # the other, or they match
     try:
-        while 1:
+        while True:
             if gx[0] == gy[0]:
                 for v in gx[1]:
                     if v in gy[1]:
--- a/mercurial/archival.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/archival.py	Sat Jun 18 17:03:01 2011 -0500
@@ -8,8 +8,8 @@
 from i18n import _
 from node import hex
 import cmdutil
-import util, encoding
-import cStringIO, os, stat, tarfile, time, zipfile
+import scmutil, util, encoding
+import cStringIO, os, tarfile, time, zipfile
 import zlib, gzip
 
 def tidyprefix(dest, kind, prefix):
@@ -172,10 +172,10 @@
         # unzip will not honor unix file modes unless file creator is
         # set to unix (id 3).
         i.create_system = 3
-        ftype = stat.S_IFREG
+        ftype = 0x8000 # UNX_IFREG in unzip source code
         if islink:
             mode = 0777
-            ftype = stat.S_IFLNK
+            ftype = 0xa000 # UNX_IFLNK in unzip source code
         i.external_attr = (mode | ftype) << 16L
         self.z.writestr(i, data)
 
@@ -187,7 +187,7 @@
 
     def __init__(self, name, mtime):
         self.basedir = name
-        self.opener = util.opener(self.basedir)
+        self.opener = scmutil.opener(self.basedir)
 
     def addfile(self, name, mode, islink, data):
         if islink:
--- a/mercurial/bdiff.c	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/bdiff.c	Sat Jun 18 17:03:01 2011 -0500
@@ -49,7 +49,7 @@
 #include "util.h"
 
 struct line {
-	int h, len, n, e;
+	int hash, len, n, e;
 	const char *l;
 };
 
@@ -63,9 +63,10 @@
 	struct hunk *next;
 };
 
-int splitlines(const char *a, int len, struct line **lr)
+static int splitlines(const char *a, int len, struct line **lr)
 {
-	int h, i;
+	unsigned hash;
+	int i;
 	const char *p, *b = a;
 	const char * const plast = a + len - 1;
 	struct line *l;
@@ -81,14 +82,14 @@
 		return -1;
 
 	/* build the line array and calculate hashes */
-	h = 0;
+	hash = 0;
 	for (p = a; p < a + len; p++) {
 		/* Leonid Yuriev's hash */
-		h = (h * 1664525) + *p + 1013904223;
+		hash = (hash * 1664525) + (unsigned char)*p + 1013904223;
 
 		if (*p == '\n' || p == plast) {
-			l->h = h;
-			h = 0;
+			l->hash = hash;
+			hash = 0;
 			l->len = p - b + 1;
 			l->l = b;
 			l->n = INT_MAX;
@@ -98,14 +99,15 @@
 	}
 
 	/* set up a sentinel */
-	l->h = l->len = 0;
+	l->hash = 0;
+	l->len = 0;
 	l->l = a + len;
 	return i - 1;
 }
 
-int inline cmp(struct line *a, struct line *b)
+static inline int cmp(struct line *a, struct line *b)
 {
-	return a->h != b->h || a->len != b->len || memcmp(a->l, b->l, a->len);
+	return a->hash != b->hash || a->len != b->len || memcmp(a->l, b->l, a->len);
 }
 
 static int equatelines(struct line *a, int an, struct line *b, int bn)
@@ -138,7 +140,7 @@
 	/* add lines to the hash table chains */
 	for (i = bn - 1; i >= 0; i--) {
 		/* find the equivalence class */
-		for (j = b[i].h & buckets; h[j].pos != INT_MAX;
+		for (j = b[i].hash & buckets; h[j].pos != INT_MAX;
 		     j = (j + 1) & buckets)
 			if (!cmp(b + i, b + h[j].pos))
 				break;
@@ -156,7 +158,7 @@
 	/* match items in a to their equivalence class in b */
 	for (i = 0; i < an; i++) {
 		/* find the equivalence class */
-		for (j = a[i].h & buckets; h[j].pos != INT_MAX;
+		for (j = a[i].hash & buckets; h[j].pos != INT_MAX;
 		     j = (j + 1) & buckets)
 			if (!cmp(a + i, b + h[j].pos))
 				break;
--- a/mercurial/bookmarks.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/bookmarks.py	Sat Jun 18 17:03:01 2011 -0500
@@ -6,9 +6,9 @@
 # GNU General Public License version 2 or any later version.
 
 from mercurial.i18n import _
-from mercurial.node import nullid, nullrev, bin, hex, short
-from mercurial import encoding, util
-import os
+from mercurial.node import hex
+from mercurial import encoding, error, util
+import errno, os
 
 def valid(mark):
     for c in (':', '\0', '\n', '\r'):
@@ -23,14 +23,18 @@
     in the .hg/bookmarks file.
     Read the file and return a (name=>nodeid) dictionary
     '''
+    bookmarks = {}
     try:
-        bookmarks = {}
         for line in repo.opener('bookmarks'):
             sha, refspec = line.strip().split(' ', 1)
             refspec = encoding.tolocal(refspec)
-            bookmarks[refspec] = repo.changelog.lookup(sha)
-    except:
-        pass
+            try:
+                bookmarks[refspec] = repo.changelog.lookup(sha)
+            except error.RepoLookupError:
+                pass
+    except IOError, inst:
+        if inst.errno != errno.ENOENT:
+            raise
     return bookmarks
 
 def readcurrent(repo):
@@ -41,12 +45,18 @@
     is stored in .hg/bookmarks.current
     '''
     mark = None
-    if os.path.exists(repo.join('bookmarks.current')):
+    try:
         file = repo.opener('bookmarks.current')
+    except IOError, inst:
+        if inst.errno != errno.ENOENT:
+            raise
+        return None
+    try:
         # No readline() in posixfile_nt, reading everything is cheap
         mark = encoding.tolocal((file.readlines() or [''])[0])
         if mark == '' or mark not in repo._bookmarks:
             mark = None
+    finally:
         file.close()
     return mark
 
@@ -95,13 +105,7 @@
     if current == mark:
         return
 
-    refs = repo._bookmarks
-
-    # do not update if we do update to a rev equal to the current bookmark
-    if (mark and mark not in refs and
-        current and refs[current] == repo.changectx('.').node()):
-        return
-    if mark not in refs:
+    if mark not in repo._bookmarks:
         mark = ''
     if not valid(mark):
         raise util.Abort(_("bookmark '%s' contains illegal "
@@ -110,12 +114,21 @@
     wlock = repo.wlock()
     try:
         file = repo.opener('bookmarks.current', 'w', atomictemp=True)
-        file.write(mark)
+        file.write(encoding.fromlocal(mark))
         file.rename()
     finally:
         wlock.release()
     repo._bookmarkcurrent = mark
 
+def updatecurrentbookmark(repo, oldnode, curbranch):
+    try:
+        update(repo, oldnode, repo.branchtags()[curbranch])
+    except KeyError:
+        if curbranch == "default": # no default branch!
+            update(repo, oldnode, repo.lookup("tip"))
+        else:
+            raise util.Abort(_("branch %s not found") % curbranch)
+
 def update(repo, parents, node):
     marks = repo._bookmarks
     update = False
@@ -157,6 +170,28 @@
     finally:
         w.release()
 
+def updatefromremote(ui, repo, remote):
+    ui.debug("checking for updated bookmarks\n")
+    rb = remote.listkeys('bookmarks')
+    changed = False
+    for k in rb.keys():
+        if k in repo._bookmarks:
+            nr, nl = rb[k], repo._bookmarks[k]
+            if nr in repo:
+                cr = repo[nr]
+                cl = repo[nl]
+                if cl.rev() >= cr.rev():
+                    continue
+                if cr in cl.descendants():
+                    repo._bookmarks[k] = cr.node()
+                    changed = True
+                    ui.status(_("updating bookmark %s\n") % k)
+                else:
+                    ui.warn(_("not updating divergent"
+                                   " bookmark %s\n") % k)
+    if changed:
+        write(repo)
+
 def diff(ui, repo, remote):
     ui.status(_("searching for changed bookmarks\n"))
 
--- a/mercurial/bundlerepo.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/bundlerepo.py	Sat Jun 18 17:03:01 2011 -0500
@@ -13,13 +13,12 @@
 
 from node import nullid
 from i18n import _
-import os, struct, tempfile, shutil
+import os, tempfile, shutil
 import changegroup, util, mdiff, discovery
 import localrepo, changelog, manifest, filelog, revlog, error
 
 class bundlerevlog(revlog.revlog):
-    def __init__(self, opener, indexfile, bundle,
-                 linkmapper=None):
+    def __init__(self, opener, indexfile, bundle, linkmapper):
         # How it works:
         # to retrieve a revision, we need to know the offset of
         # the revision in the bundle (an unbundle object).
@@ -32,43 +31,39 @@
         revlog.revlog.__init__(self, opener, indexfile)
         self.bundle = bundle
         self.basemap = {}
-        def chunkpositer():
-            while 1:
-                chunk = bundle.chunk()
-                if not chunk:
-                    break
-                pos = bundle.tell()
-                yield chunk, pos - len(chunk)
         n = len(self)
-        prev = None
-        for chunk, start in chunkpositer():
-            size = len(chunk)
-            if size < 80:
-                raise util.Abort(_("invalid changegroup"))
-            start += 80
-            size -= 80
-            node, p1, p2, cs = struct.unpack("20s20s20s20s", chunk[:80])
+        chain = None
+        while True:
+            chunkdata = bundle.deltachunk(chain)
+            if not chunkdata:
+                break
+            node = chunkdata['node']
+            p1 = chunkdata['p1']
+            p2 = chunkdata['p2']
+            cs = chunkdata['cs']
+            deltabase = chunkdata['deltabase']
+            delta = chunkdata['delta']
+
+            size = len(delta)
+            start = bundle.tell() - size
+
+            link = linkmapper(cs)
             if node in self.nodemap:
-                prev = node
+                # this can happen if two branches make the same change
+                chain = node
                 continue
+
             for p in (p1, p2):
                 if not p in self.nodemap:
                     raise error.LookupError(p, self.indexfile,
                                             _("unknown parent"))
-            if linkmapper is None:
-                link = n
-            else:
-                link = linkmapper(cs)
-
-            if not prev:
-                prev = p1
             # start, size, full unc. size, base (unused), link, p1, p2, node
             e = (revlog.offset_type(start, 0), size, -1, -1, link,
                  self.rev(p1), self.rev(p2), node)
-            self.basemap[n] = prev
+            self.basemap[n] = deltabase
             self.index.insert(-1, e)
             self.nodemap[node] = n
-            prev = node
+            chain = node
             n += 1
 
     def inbundle(self, rev):
@@ -144,7 +139,9 @@
 class bundlechangelog(bundlerevlog, changelog.changelog):
     def __init__(self, opener, bundle):
         changelog.changelog.__init__(self, opener)
-        bundlerevlog.__init__(self, opener, self.indexfile, bundle)
+        linkmapper = lambda x: x
+        bundlerevlog.__init__(self, opener, self.indexfile, bundle,
+                              linkmapper)
 
 class bundlemanifest(bundlerevlog, manifest.manifest):
     def __init__(self, opener, bundle, linkmapper):
@@ -153,10 +150,14 @@
                               linkmapper)
 
 class bundlefilelog(bundlerevlog, filelog.filelog):
-    def __init__(self, opener, path, bundle, linkmapper):
+    def __init__(self, opener, path, bundle, linkmapper, repo):
         filelog.filelog.__init__(self, opener, path)
         bundlerevlog.__init__(self, opener, self.indexfile, bundle,
                               linkmapper)
+        self._repo = repo
+
+    def _file(self, f):
+        self._repo.file(f)
 
 class bundlerepository(localrepo.localrepository):
     def __init__(self, ui, path, bundlename):
@@ -184,7 +185,7 @@
 
             try:
                 fptemp.write("HG10UN")
-                while 1:
+                while True:
                     chunk = self.bundle.read(2**18)
                     if not chunk:
                         break
@@ -200,6 +201,8 @@
 
     @util.propertycache
     def changelog(self):
+        # consume the header if it exists
+        self.bundle.changelogheader()
         c = bundlechangelog(self.sopener, self.bundle)
         self.manstart = self.bundle.tell()
         return c
@@ -207,6 +210,8 @@
     @util.propertycache
     def manifest(self):
         self.bundle.seek(self.manstart)
+        # consume the header if it exists
+        self.bundle.manifestheader()
         m = bundlemanifest(self.sopener, self.bundle, self.changelog.rev)
         self.filestart = self.bundle.tell()
         return m
@@ -227,13 +232,14 @@
     def file(self, f):
         if not self.bundlefilespos:
             self.bundle.seek(self.filestart)
-            while 1:
-                chunk = self.bundle.chunk()
-                if not chunk:
+            while True:
+                chunkdata = self.bundle.filelogheader()
+                if not chunkdata:
                     break
-                self.bundlefilespos[chunk] = self.bundle.tell()
-                while 1:
-                    c = self.bundle.chunk()
+                fname = chunkdata['filename']
+                self.bundlefilespos[fname] = self.bundle.tell()
+                while True:
+                    c = self.bundle.deltachunk(None)
                     if not c:
                         break
 
@@ -242,7 +248,7 @@
         if f in self.bundlefilespos:
             self.bundle.seek(self.bundlefilespos[f])
             return bundlefilelog(self.sopener, f, self.bundle,
-                                 self.changelog.rev)
+                                 self.changelog.rev, self)
         else:
             return filelog.filelog(self.sopener, f)
 
@@ -274,9 +280,9 @@
             cwd = os.path.join(cwd,'')
             if parentpath.startswith(cwd):
                 parentpath = parentpath[len(cwd):]
-    path = util.drop_scheme('file', path)
-    if path.startswith('bundle:'):
-        path = util.drop_scheme('bundle', path)
+    u = util.url(path)
+    path = u.localpath()
+    if u.scheme == 'bundle':
         s = path.split("+", 1)
         if len(s) == 1:
             repopath, bundlename = parentpath, s[0]
@@ -286,27 +292,48 @@
         repopath, bundlename = parentpath, path
     return bundlerepository(ui, repopath, bundlename)
 
-def getremotechanges(ui, repo, other, revs=None, bundlename=None, force=False):
-    tmp = discovery.findcommonincoming(repo, other, heads=revs, force=force)
+def getremotechanges(ui, repo, other, onlyheads=None, bundlename=None,
+                     force=False):
+    '''obtains a bundle of changes incoming from other
+
+    "onlyheads" restricts the returned changes to those reachable from the
+      specified heads.
+    "bundlename", if given, stores the bundle to this file path permanently;
+      otherwise it's stored to a temp file and gets deleted again when you call
+      the returned "cleanupfn".
+    "force" indicates whether to proceed on unrelated repos.
+
+    Returns a tuple (local, csets, cleanupfn):
+
+    "local" is a local repo from which to obtain the actual incoming changesets; it
+      is a bundlerepo for the obtained bundle when the original "other" is remote.
+    "csets" lists the incoming changeset node ids.
+    "cleanupfn" must be called without arguments when you're done processing the
+      changes; it closes both the original "other" and the one returned here.
+    '''
+    tmp = discovery.findcommonincoming(repo, other, heads=onlyheads, force=force)
     common, incoming, rheads = tmp
     if not incoming:
         try:
             os.unlink(bundlename)
-        except:
+        except OSError:
             pass
-        return other, None, None
+        return other, [], other.close
 
     bundle = None
+    bundlerepo = None
+    localrepo = other
     if bundlename or not other.local():
         # create a bundle (uncompressed if other repo is not local)
 
-        if revs is None and other.capable('changegroupsubset'):
-            revs = rheads
-
-        if revs is None:
+        if other.capable('getbundle'):
+            cg = other.getbundle('incoming', common=common, heads=rheads)
+        elif onlyheads is None and not other.capable('changegroupsubset'):
+            # compat with older servers when pulling all remote heads
             cg = other.changegroup(incoming, "incoming")
+            rheads = None
         else:
-            cg = other.changegroupsubset(incoming, revs, 'incoming')
+            cg = other.changegroupsubset(incoming, rheads, 'incoming')
         bundletype = other.local() and "HG10BZ" or "HG10UN"
         fname = bundle = changegroup.writebundle(cg, bundlename, bundletype)
         # keep written bundle?
@@ -314,6 +341,18 @@
             bundle = None
         if not other.local():
             # use the created uncompressed bundlerepo
-            other = bundlerepository(ui, repo.root, fname)
-    return (other, incoming, bundle)
+            localrepo = bundlerepo = bundlerepository(ui, repo.root, fname)
+            # this repo contains local and other now, so filter out local again
+            common = repo.heads()
+
+    csets = localrepo.changelog.findmissing(common, rheads)
 
+    def cleanup():
+        if bundlerepo:
+            bundlerepo.close()
+        if bundle:
+            os.unlink(bundle)
+        other.close()
+
+    return (localrepo, csets, cleanup)
+
--- a/mercurial/changegroup.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/changegroup.py	Sat Jun 18 17:03:01 2011 -0500
@@ -6,9 +6,12 @@
 # GNU General Public License version 2 or any later version.
 
 from i18n import _
-import util
+from node import nullrev
+import mdiff, util
 import struct, os, bz2, zlib, tempfile
 
+_BUNDLE10_DELTA_HEADER = "20s20s20s20s"
+
 def readexactly(stream, n):
     '''read n bytes from stream.read and abort if less was available'''
     s = stream.read(n)
@@ -43,21 +46,14 @@
         return ""
 
 bundletypes = {
-    "": ("", nocompress),
+    "": ("", nocompress), # only when using unbundle on ssh and old http servers
+                          # since the unification ssh accepts a header but there
+                          # is no capability signaling it.
     "HG10UN": ("HG10UN", nocompress),
     "HG10BZ": ("HG10", lambda: bz2.BZ2Compressor()),
     "HG10GZ": ("HG10GZ", lambda: zlib.compressobj()),
 }
 
-def collector(cl, mmfs, files):
-    # Gather information about changeset nodes going out in a bundle.
-    # We want to gather manifests needed and filelogs affected.
-    def collect(node):
-        c = cl.read(node)
-        files.update(c[3])
-        mmfs.setdefault(c[0], node)
-    return collect
-
 # hgweb uses this list to communicate its preferred type
 bundlepriority = ['HG10GZ', 'HG10BZ', 'HG10UN']
 
@@ -95,7 +91,7 @@
         while not empty or count <= 2:
             empty = True
             count += 1
-            while 1:
+            while True:
                 chunk = getchunk(cg)
                 if not chunk:
                     break
@@ -135,6 +131,8 @@
     return util.chunkbuffer(generator(fh))
 
 class unbundle10(object):
+    deltaheader = _BUNDLE10_DELTA_HEADER
+    deltaheadersize = struct.calcsize(deltaheader)
     def __init__(self, fh, alg):
         self._stream = decompressor(fh, alg)
         self._type = alg
@@ -161,19 +159,40 @@
             self.callback()
         return l - 4
 
-    def chunk(self):
-        """return the next chunk from changegroup 'source' as a string"""
-        l = self.chunklength()
-        return readexactly(self._stream, l)
+    def changelogheader(self):
+        """v10 does not have a changelog header chunk"""
+        return {}
 
-    def parsechunk(self):
+    def manifestheader(self):
+        """v10 does not have a manifest header chunk"""
+        return {}
+
+    def filelogheader(self):
+        """return the header of the filelogs chunk, v10 only has the filename"""
         l = self.chunklength()
         if not l:
             return {}
-        h = readexactly(self._stream, 80)
-        node, p1, p2, cs = struct.unpack("20s20s20s20s", h)
-        data = readexactly(self._stream, l - 80)
-        return dict(node=node, p1=p1, p2=p2, cs=cs, data=data)
+        fname = readexactly(self._stream, l)
+        return dict(filename=fname)
+
+    def _deltaheader(self, headertuple, prevnode):
+        node, p1, p2, cs = headertuple
+        if prevnode is None:
+            deltabase = p1
+        else:
+            deltabase = prevnode
+        return node, p1, p2, deltabase, cs
+
+    def deltachunk(self, prevnode):
+        l = self.chunklength()
+        if not l:
+            return {}
+        headerdata = readexactly(self._stream, self.deltaheadersize)
+        header = struct.unpack(self.deltaheader, headerdata)
+        delta = readexactly(self._stream, l - self.deltaheadersize)
+        node, p1, p2, deltabase, cs = self._deltaheader(header, prevnode)
+        return dict(node=node, p1=p1, p2=p2, cs=cs,
+                    deltabase=deltabase, delta=delta)
 
 class headerlessfixup(object):
     def __init__(self, fh, h):
@@ -203,3 +222,35 @@
     if version != '10':
         raise util.Abort(_('%s: unknown bundle version %s') % (fname, version))
     return unbundle10(fh, alg)
+
+class bundle10(object):
+    deltaheader = _BUNDLE10_DELTA_HEADER
+    def __init__(self, lookup):
+        self._lookup = lookup
+    def close(self):
+        return closechunk()
+    def fileheader(self, fname):
+        return chunkheader(len(fname)) + fname
+    def revchunk(self, revlog, rev, prev):
+        node = revlog.node(rev)
+        p1, p2 = revlog.parentrevs(rev)
+        base = prev
+
+        prefix = ''
+        if base == nullrev:
+            delta = revlog.revision(node)
+            prefix = mdiff.trivialdiffheader(len(delta))
+        else:
+            delta = revlog.revdiff(base, rev)
+        linknode = self._lookup(revlog, node)
+        p1n, p2n = revlog.parents(node)
+        basenode = revlog.node(base)
+        meta = self.builddeltaheader(node, p1n, p2n, basenode, linknode)
+        meta += prefix
+        l = len(meta) + len(delta)
+        yield chunkheader(l)
+        yield meta
+        yield delta
+    def builddeltaheader(self, node, p1n, p2n, basenode, linknode):
+        # do nothing with basenode, it is implicitly the previous one in HG10
+        return struct.pack(self.deltaheader, node, p1n, p2n, linknode)
--- a/mercurial/changelog.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/changelog.py	Sat Jun 18 17:03:01 2011 -0500
@@ -100,9 +100,15 @@
 class changelog(revlog.revlog):
     def __init__(self, opener):
         revlog.revlog.__init__(self, opener, "00changelog.i")
+        if self._initempty:
+            # changelogs don't benefit from generaldelta
+            self.version &= ~revlog.REVLOGGENERALDELTA
+            self._generaldelta = False
         self._realopener = opener
         self._delayed = False
         self._divert = False
+        # hiddenrevs: revs that should be hidden by command and tools
+        self.hiddenrevs = set()
 
     def delayupdate(self):
         "delay visibility of index updates to other readers"
@@ -118,7 +124,9 @@
         self.opener = self._realopener
         # move redirected index data back into place
         if self._divert:
-            n = self.opener(self.indexfile + ".a").name
+            nfile = self.opener(self.indexfile + ".a")
+            n = nfile.name
+            nfile.close()
             util.rename(n, n[:-2])
         elif self._delaybuf:
             fp = self.opener(self.indexfile, 'a')
@@ -185,7 +193,7 @@
             try:
                 # various tools did silly things with the time zone field.
                 timezone = int(extra_data[0])
-            except:
+            except ValueError:
                 timezone = 0
             extra = {}
         else:
--- a/mercurial/cmdutil.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/cmdutil.py	Sat Jun 18 17:03:01 2011 -0500
@@ -7,12 +7,10 @@
 
 from node import hex, nullid, nullrev, short
 from i18n import _
-import os, sys, errno, re, glob, tempfile
-import util, templater, patch, error, encoding, templatekw
+import os, sys, errno, re, tempfile
+import util, scmutil, templater, patch, error, templatekw, revlog
 import match as matchmod
-import similar, revset, subrepo
-
-revrangesep = ':'
+import subrepo
 
 def parsealiases(cmd):
     return cmd.lstrip("^").split("|")
@@ -71,14 +69,14 @@
 
     return p
 
-def bail_if_changed(repo):
-    if repo.dirstate.parents()[1] != nullid:
+def bailifchanged(repo):
+    if repo.dirstate.p2() != nullid:
         raise util.Abort(_('outstanding uncommitted merge'))
     modified, added, removed, deleted = repo.status()[:4]
     if modified or added or removed or deleted:
         raise util.Abort(_("outstanding uncommitted changes"))
 
-def logmessage(opts):
+def logmessage(ui, opts):
     """ get the log message according to -m and -l option """
     message = opts.get('message')
     logfile = opts.get('logfile')
@@ -89,9 +87,9 @@
     if not message and logfile:
         try:
             if logfile == '-':
-                message = sys.stdin.read()
+                message = ui.fin.read()
             else:
-                message = open(logfile).read()
+                message = '\n'.join(util.readfile(logfile).splitlines())
         except IOError, inst:
             raise util.Abort(_("can't read commit message '%s': %s") %
                              (logfile, inst.strerror))
@@ -111,78 +109,7 @@
         limit = None
     return limit
 
-def revsingle(repo, revspec, default='.'):
-    if not revspec:
-        return repo[default]
-
-    l = revrange(repo, [revspec])
-    if len(l) < 1:
-        raise util.Abort(_('empty revision set'))
-    return repo[l[-1]]
-
-def revpair(repo, revs):
-    if not revs:
-        return repo.dirstate.parents()[0], None
-
-    l = revrange(repo, revs)
-
-    if len(l) == 0:
-        return repo.dirstate.parents()[0], None
-
-    if len(l) == 1:
-        return repo.lookup(l[0]), None
-
-    return repo.lookup(l[0]), repo.lookup(l[-1])
-
-def revrange(repo, revs):
-    """Yield revision as strings from a list of revision specifications."""
-
-    def revfix(repo, val, defval):
-        if not val and val != 0 and defval is not None:
-            return defval
-        return repo.changelog.rev(repo.lookup(val))
-
-    seen, l = set(), []
-    for spec in revs:
-        # attempt to parse old-style ranges first to deal with
-        # things like old-tag which contain query metacharacters
-        try:
-            if isinstance(spec, int):
-                seen.add(spec)
-                l.append(spec)
-                continue
-
-            if revrangesep in spec:
-                start, end = spec.split(revrangesep, 1)
-                start = revfix(repo, start, 0)
-                end = revfix(repo, end, len(repo) - 1)
-                step = start > end and -1 or 1
-                for rev in xrange(start, end + step, step):
-                    if rev in seen:
-                        continue
-                    seen.add(rev)
-                    l.append(rev)
-                continue
-            elif spec and spec in repo: # single unquoted rev
-                rev = revfix(repo, spec, None)
-                if rev in seen:
-                    continue
-                seen.add(rev)
-                l.append(rev)
-                continue
-        except error.RepoLookupError:
-            pass
-
-        # fall through to new-style queries if old-style fails
-        m = revset.match(spec)
-        for r in m(repo, range(len(repo))):
-            if r not in seen:
-                l.append(r)
-        seen.update(l)
-
-    return l
-
-def make_filename(repo, pat, node,
+def makefilename(repo, pat, node,
                   total=None, seqno=None, revwidth=None, pathname=None):
     node_expander = {
         'H': lambda: hex(node),
@@ -227,172 +154,71 @@
         raise util.Abort(_("invalid format spec '%%%s' in output filename") %
                          inst.args[0])
 
-def make_file(repo, pat, node=None,
-              total=None, seqno=None, revwidth=None, mode='wb', pathname=None):
+def makefileobj(repo, pat, node=None, total=None,
+                seqno=None, revwidth=None, mode='wb', pathname=None):
 
-    writable = 'w' in mode or 'a' in mode
+    writable = mode not in ('r', 'rb')
 
     if not pat or pat == '-':
-        fp = writable and sys.stdout or sys.stdin
-        return os.fdopen(os.dup(fp.fileno()), mode)
+        fp = writable and repo.ui.fout or repo.ui.fin
+        if hasattr(fp, 'fileno'):
+            return os.fdopen(os.dup(fp.fileno()), mode)
+        else:
+            # if this fp can't be duped properly, return
+            # a dummy object that can be closed
+            class wrappedfileobj(object):
+                noop = lambda x: None
+                def __init__(self, f):
+                    self.f = f
+                def __getattr__(self, attr):
+                    if attr == 'close':
+                        return self.noop
+                    else:
+                        return getattr(self.f, attr)
+
+            return wrappedfileobj(fp)
     if hasattr(pat, 'write') and writable:
         return pat
     if hasattr(pat, 'read') and 'r' in mode:
         return pat
-    return open(make_filename(repo, pat, node, total, seqno, revwidth,
+    return open(makefilename(repo, pat, node, total, seqno, revwidth,
                               pathname),
                 mode)
 
-def expandpats(pats):
-    if not util.expandglobs:
-        return list(pats)
-    ret = []
-    for p in pats:
-        kind, name = matchmod._patsplit(p, None)
-        if kind is None:
-            try:
-                globbed = glob.glob(name)
-            except re.error:
-                globbed = [name]
-            if globbed:
-                ret.extend(globbed)
-                continue
-        ret.append(p)
-    return ret
-
-def match(repo, pats=[], opts={}, globbed=False, default='relpath'):
-    if pats == ("",):
-        pats = []
-    if not globbed and default == 'relpath':
-        pats = expandpats(pats or [])
-    m = matchmod.match(repo.root, repo.getcwd(), pats,
-                       opts.get('include'), opts.get('exclude'), default,
-                       auditor=repo.auditor)
-    def badfn(f, msg):
-        repo.ui.warn("%s: %s\n" % (m.rel(f), msg))
-    m.bad = badfn
-    return m
-
-def matchall(repo):
-    return matchmod.always(repo.root, repo.getcwd())
-
-def matchfiles(repo, files):
-    return matchmod.exact(repo.root, repo.getcwd(), files)
+def openrevlog(repo, cmd, file_, opts):
+    """opens the changelog, manifest, a filelog or a given revlog"""
+    cl = opts['changelog']
+    mf = opts['manifest']
+    msg = None
+    if cl and mf:
+        msg = _('cannot specify --changelog and --manifest at the same time')
+    elif cl or mf:
+        if file_:
+            msg = _('cannot specify filename with --changelog or --manifest')
+        elif not repo:
+            msg = _('cannot specify --changelog or --manifest '
+                    'without a repository')
+    if msg:
+        raise util.Abort(msg)
 
-def addremove(repo, pats=[], opts={}, dry_run=None, similarity=None):
-    if dry_run is None:
-        dry_run = opts.get('dry_run')
-    if similarity is None:
-        similarity = float(opts.get('similarity') or 0)
-    # we'd use status here, except handling of symlinks and ignore is tricky
-    added, unknown, deleted, removed = [], [], [], []
-    audit_path = util.path_auditor(repo.root)
-    m = match(repo, pats, opts)
-    for abs in repo.walk(m):
-        target = repo.wjoin(abs)
-        good = True
-        try:
-            audit_path(abs)
-        except:
-            good = False
-        rel = m.rel(abs)
-        exact = m.exact(abs)
-        if good and abs not in repo.dirstate:
-            unknown.append(abs)
-            if repo.ui.verbose or not exact:
-                repo.ui.status(_('adding %s\n') % ((pats and rel) or abs))
-        elif repo.dirstate[abs] != 'r' and (not good or not os.path.lexists(target)
-            or (os.path.isdir(target) and not os.path.islink(target))):
-            deleted.append(abs)
-            if repo.ui.verbose or not exact:
-                repo.ui.status(_('removing %s\n') % ((pats and rel) or abs))
-        # for finding renames
-        elif repo.dirstate[abs] == 'r':
-            removed.append(abs)
-        elif repo.dirstate[abs] == 'a':
-            added.append(abs)
-    copies = {}
-    if similarity > 0:
-        for old, new, score in similar.findrenames(repo,
-                added + unknown, removed + deleted, similarity):
-            if repo.ui.verbose or not m.exact(old) or not m.exact(new):
-                repo.ui.status(_('recording removal of %s as rename to %s '
-                                 '(%d%% similar)\n') %
-                               (m.rel(old), m.rel(new), score * 100))
-            copies[new] = old
-
-    if not dry_run:
-        wctx = repo[None]
-        wlock = repo.wlock()
-        try:
-            wctx.remove(deleted)
-            wctx.add(unknown)
-            for new, old in copies.iteritems():
-                wctx.copy(old, new)
-        finally:
-            wlock.release()
-
-def updatedir(ui, repo, patches, similarity=0):
-    '''Update dirstate after patch application according to metadata'''
-    if not patches:
-        return
-    copies = []
-    removes = set()
-    cfiles = patches.keys()
-    cwd = repo.getcwd()
-    if cwd:
-        cfiles = [util.pathto(repo.root, cwd, f) for f in patches.keys()]
-    for f in patches:
-        gp = patches[f]
-        if not gp:
-            continue
-        if gp.op == 'RENAME':
-            copies.append((gp.oldpath, gp.path))
-            removes.add(gp.oldpath)
-        elif gp.op == 'COPY':
-            copies.append((gp.oldpath, gp.path))
-        elif gp.op == 'DELETE':
-            removes.add(gp.path)
-
-    wctx = repo[None]
-    for src, dst in copies:
-        dirstatecopy(ui, repo, wctx, src, dst, cwd=cwd)
-    if (not similarity) and removes:
-        wctx.remove(sorted(removes), True)
-
-    for f in patches:
-        gp = patches[f]
-        if gp and gp.mode:
-            islink, isexec = gp.mode
-            dst = repo.wjoin(gp.path)
-            # patch won't create empty files
-            if gp.op == 'ADD' and not os.path.lexists(dst):
-                flags = (isexec and 'x' or '') + (islink and 'l' or '')
-                repo.wwrite(gp.path, '', flags)
-            util.set_flags(dst, islink, isexec)
-    addremove(repo, cfiles, similarity=similarity)
-    files = patches.keys()
-    files.extend([r for r in removes if r not in files])
-    return sorted(files)
-
-def dirstatecopy(ui, repo, wctx, src, dst, dryrun=False, cwd=None):
-    """Update the dirstate to reflect the intent of copying src to dst. For
-    different reasons it might not end with dst being marked as copied from src.
-    """
-    origsrc = repo.dirstate.copied(src) or src
-    if dst == origsrc: # copying back a copy?
-        if repo.dirstate[dst] not in 'mn' and not dryrun:
-            repo.dirstate.normallookup(dst)
-    else:
-        if repo.dirstate[origsrc] == 'a' and origsrc == src:
-            if not ui.quiet:
-                ui.warn(_("%s has not been committed yet, so no copy "
-                          "data will be stored for %s.\n")
-                        % (repo.pathto(origsrc, cwd), repo.pathto(dst, cwd)))
-            if repo.dirstate[dst] in '?r' and not dryrun:
-                wctx.add([dst])
-        elif not dryrun:
-            wctx.copy(origsrc, dst)
+    r = None
+    if repo:
+        if cl:
+            r = repo.changelog
+        elif mf:
+            r = repo.manifest
+        elif file_:
+            filelog = repo.file(file_)
+            if len(filelog):
+                r = filelog
+    if not r:
+        if not file_:
+            raise error.CommandError(cmd, _('invalid arguments'))
+        if not os.path.isfile(file_):
+            raise util.Abort(_("revlog '%s' not found") % file_)
+        r = revlog.revlog(scmutil.opener(os.getcwd(), audit=False),
+                          file_[:-2] + ".i")
+    return r
 
 def copy(ui, repo, pats, opts, rename=False):
     # called with the repo lock held
@@ -408,7 +234,7 @@
     def walkpat(pat):
         srcs = []
         badstates = after and '?' or '?r'
-        m = match(repo, [pat], opts, globbed=True)
+        m = scmutil.match(repo[None], [pat], opts, globbed=True)
         for abs in repo.walk(m):
             state = repo.dirstate[abs]
             rel = m.rel(abs)
@@ -429,12 +255,14 @@
     # relsrc: ossep
     # otarget: ossep
     def copyfile(abssrc, relsrc, otarget, exact):
-        abstarget = util.canonpath(repo.root, cwd, otarget)
+        abstarget = scmutil.canonpath(repo.root, cwd, otarget)
         reltarget = repo.pathto(abstarget, cwd)
         target = repo.wjoin(abstarget)
         src = repo.wjoin(abssrc)
         state = repo.dirstate[abstarget]
 
+        scmutil.checkportable(ui, abstarget)
+
         # check for collisions
         prevsrc = targets.get(abstarget)
         if prevsrc is not None:
@@ -468,9 +296,11 @@
                 if not os.path.isdir(targetdir):
                     os.makedirs(targetdir)
                 util.copyfile(src, target)
+                srcexists = True
             except IOError, inst:
                 if inst.errno == errno.ENOENT:
                     ui.warn(_('%s: deleted in working copy\n') % relsrc)
+                    srcexists = False
                 else:
                     ui.warn(_('%s: cannot copy - %s\n') %
                             (relsrc, inst.strerror))
@@ -485,9 +315,12 @@
         targets[abstarget] = abssrc
 
         # fix up dirstate
-        dirstatecopy(ui, repo, wctx, abssrc, abstarget, dryrun=dryrun, cwd=cwd)
+        scmutil.dirstatecopy(ui, repo, wctx, abssrc, abstarget,
+                             dryrun=dryrun, cwd=cwd)
         if rename and not dryrun:
-            wctx.remove([abssrc], not after)
+            if not after and srcexists:
+                util.unlinkpath(repo.wjoin(abssrc))
+            wctx.forget([abssrc])
 
     # pat: ossep
     # dest ossep
@@ -495,7 +328,7 @@
     # return: function that takes hgsep and returns ossep
     def targetpathfn(pat, dest, srcs):
         if os.path.isdir(pat):
-            abspfx = util.canonpath(repo.root, cwd, pat)
+            abspfx = scmutil.canonpath(repo.root, cwd, pat)
             abspfx = util.localpath(abspfx)
             if destdirexists:
                 striplen = len(os.path.split(abspfx)[0])
@@ -521,7 +354,7 @@
             res = lambda p: os.path.join(dest,
                                          os.path.basename(util.localpath(p)))
         else:
-            abspfx = util.canonpath(repo.root, cwd, pat)
+            abspfx = scmutil.canonpath(repo.root, cwd, pat)
             if len(abspfx) < len(srcs[0][0]):
                 # A directory. Either the target path contains the last
                 # component of the source path or it does not.
@@ -556,7 +389,7 @@
         return res
 
 
-    pats = expandpats(pats)
+    pats = scmutil.expandpats(pats)
     if not pats:
         raise util.Abort(_('no source or destination specified'))
     if len(pats) == 1:
@@ -683,8 +516,8 @@
 
         shouldclose = False
         if not fp:
-            fp = make_file(repo, template, node, total=total, seqno=seqno,
-                           revwidth=revwidth, mode='ab')
+            fp = makefileobj(repo, template, node, total=total, seqno=seqno,
+                             revwidth=revwidth, mode='ab')
             if fp != template:
                 shouldclose = True
         if fp != sys.stdout and hasattr(fp, 'name'):
@@ -1020,7 +853,7 @@
     # options
     patch = False
     if opts.get('patch') or opts.get('stat'):
-        patch = matchall(repo)
+        patch = scmutil.matchall(repo)
 
     tmpl = opts.get('template')
     style = None
@@ -1061,7 +894,7 @@
     """Find the tipmost changeset that matches the given date spec"""
 
     df = util.matchdate(date)
-    m = matchall(repo)
+    m = scmutil.matchall(repo)
     results = {}
 
     def prep(ctx, fns):
@@ -1116,7 +949,7 @@
         defrange = '%s:0' % repo['.'].rev()
     else:
         defrange = '-1:0'
-    revs = revrange(repo, opts['rev'] or [defrange])
+    revs = scmutil.revrange(repo, opts['rev'] or [defrange])
     if not revs:
         return []
     wanted = set()
@@ -1312,9 +1145,15 @@
     match.bad = lambda x, y: bad.append(x) or oldbad(x, y)
     names = []
     wctx = repo[None]
+    cca = None
+    abort, warn = scmutil.checkportabilityalert(ui)
+    if abort or warn:
+        cca = scmutil.casecollisionauditor(ui, abort, wctx)
     for f in repo.walk(match):
         exact = match.exact(f)
         if exact or f not in repo.dirstate:
+            if cca:
+                cca(f)
             names.append(f)
             if ui.verbose or not exact:
                 ui.status(_('adding %s\n') % match.rel(join(f)))
@@ -1339,14 +1178,15 @@
     date = opts.get('date')
     if date:
         opts['date'] = util.parsedate(date)
-    message = logmessage(opts)
+    message = logmessage(ui, opts)
 
     # extract addremove carefully -- this function can be called from a command
     # that doesn't support addremove
     if opts.get('addremove'):
-        addremove(repo, pats, opts)
+        scmutil.addremove(repo, pats, opts)
 
-    return commitfunc(ui, repo, message, match(repo, pats, opts), opts)
+    return commitfunc(ui, repo, message,
+                      scmutil.match(repo[None], pats, opts), opts)
 
 def commiteditor(repo, ctx, subs):
     if ctx.description():
@@ -1387,3 +1227,18 @@
         raise util.Abort(_("empty commit message"))
 
     return text
+
+def command(table):
+    '''returns a function object bound to table which can be used as
+    a decorator for populating table as a command table'''
+
+    def cmd(name, options, synopsis=None):
+        def decorator(func):
+            if synopsis:
+                table[name] = func, options[:], synopsis
+            else:
+                table[name] = func, options[:]
+            return func
+        return decorator
+
+    return cmd
--- a/mercurial/commands.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/commands.py	Sat Jun 18 17:03:01 2011 -0500
@@ -5,19 +5,135 @@
 # This software may be used and distributed according to the terms of the
 # GNU General Public License version 2 or any later version.
 
-from node import hex, nullid, nullrev, short
+from node import hex, bin, nullid, nullrev, short
 from lock import release
 from i18n import _, gettext
-import os, re, sys, difflib, time, tempfile
-import hg, util, revlog, extensions, copies, error, bookmarks
-import patch, help, mdiff, url, encoding, templatekw, discovery
-import archival, changegroup, cmdutil, sshserver, hbisect, hgweb, hgweb.server
+import os, re, difflib, time, tempfile, errno
+import hg, scmutil, util, revlog, extensions, copies, error, bookmarks
+import patch, help, url, encoding, templatekw, discovery
+import archival, changegroup, cmdutil, hbisect
+import sshserver, hgweb, hgweb.server, commandserver
 import merge as mergemod
-import minirst, revset
-import dagparser
+import minirst, revset, fileset
+import dagparser, context, simplemerge
+import random, setdiscovery, treediscovery, dagutil
+
+table = {}
+
+command = cmdutil.command(table)
+
+# common command options
+
+globalopts = [
+    ('R', 'repository', '',
+     _('repository root directory or name of overlay bundle file'),
+     _('REPO')),
+    ('', 'cwd', '',
+     _('change working directory'), _('DIR')),
+    ('y', 'noninteractive', None,
+     _('do not prompt, assume \'yes\' for any required answers')),
+    ('q', 'quiet', None, _('suppress output')),
+    ('v', 'verbose', None, _('enable additional output')),
+    ('', 'config', [],
+     _('set/override config option (use \'section.name=value\')'),
+     _('CONFIG')),
+    ('', 'debug', None, _('enable debugging output')),
+    ('', 'debugger', None, _('start debugger')),
+    ('', 'encoding', encoding.encoding, _('set the charset encoding'),
+     _('ENCODE')),
+    ('', 'encodingmode', encoding.encodingmode,
+     _('set the charset encoding mode'), _('MODE')),
+    ('', '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')),
+    ('h', 'help', None, _('display help and exit')),
+]
+
+dryrunopts = [('n', 'dry-run', None,
+               _('do not perform actions, just print output'))]
+
+remoteopts = [
+    ('e', 'ssh', '',
+     _('specify ssh command to use'), _('CMD')),
+    ('', 'remotecmd', '',
+     _('specify hg command to run on the remote side'), _('CMD')),
+    ('', 'insecure', None,
+     _('do not verify server certificate (ignoring web.cacerts config)')),
+]
+
+walkopts = [
+    ('I', 'include', [],
+     _('include names matching the given patterns'), _('PATTERN')),
+    ('X', 'exclude', [],
+     _('exclude names matching the given patterns'), _('PATTERN')),
+]
+
+commitopts = [
+    ('m', 'message', '',
+     _('use text as commit message'), _('TEXT')),
+    ('l', 'logfile', '',
+     _('read commit message from file'), _('FILE')),
+]
+
+commitopts2 = [
+    ('d', 'date', '',
+     _('record the specified date as commit date'), _('DATE')),
+    ('u', 'user', '',
+     _('record the specified user as committer'), _('USER')),
+]
+
+templateopts = [
+    ('', 'style', '',
+     _('display using template map file'), _('STYLE')),
+    ('', 'template', '',
+     _('display with template'), _('TEMPLATE')),
+]
+
+logopts = [
+    ('p', 'patch', None, _('show patch')),
+    ('g', 'git', None, _('use git extended diff format')),
+    ('l', 'limit', '',
+     _('limit number of changes displayed'), _('NUM')),
+    ('M', 'no-merges', None, _('do not show merges')),
+    ('', 'stat', None, _('output diffstat-style summary of changes')),
+] + templateopts
+
+diffopts = [
+    ('a', 'text', None, _('treat all files as text')),
+    ('g', 'git', None, _('use git extended diff format')),
+    ('', 'nodates', None, _('omit dates from diff headers'))
+]
+
+diffopts2 = [
+    ('p', 'show-function', None, _('show which function each change is in')),
+    ('', 'reverse', None, _('produce a diff that undoes the changes')),
+    ('w', 'ignore-all-space', None,
+     _('ignore white space when comparing lines')),
+    ('b', 'ignore-space-change', None,
+     _('ignore changes in the amount of white space')),
+    ('B', 'ignore-blank-lines', None,
+     _('ignore changes whose lines are all blank')),
+    ('U', 'unified', '',
+     _('number of lines of context to show'), _('NUM')),
+    ('', 'stat', None, _('output diffstat-style summary of changes')),
+]
+
+similarityopts = [
+    ('s', 'similarity', '',
+     _('guess renamed files by similarity (0<=s<=100)'), _('SIMILARITY'))
+]
+
+subrepoopts = [
+    ('S', 'subrepos', None,
+     _('recurse into subrepositories'))
+]
 
 # Commands start here, listed alphabetically
 
+@command('^add',
+    walkopts + subrepoopts + dryrunopts,
+    _('[OPTION]... [FILE]...'))
 def add(ui, repo, *pats, **opts):
     """add the specified files on the next commit
 
@@ -46,11 +162,14 @@
     Returns 0 if all files are successfully added.
     """
 
-    m = cmdutil.match(repo, pats, opts)
+    m = scmutil.match(repo[None], pats, opts)
     rejected = cmdutil.add(ui, repo, m, opts.get('dry_run'),
                            opts.get('subrepos'), prefix="")
     return rejected and 1 or 0
 
+@command('addremove',
+    similarityopts + walkopts + dryrunopts,
+    _('[OPTION]... [FILE]...'))
 def addremove(ui, repo, *pats, **opts):
     """add all new files, delete all missing files
 
@@ -77,8 +196,22 @@
         raise util.Abort(_('similarity must be a number'))
     if sim < 0 or sim > 100:
         raise util.Abort(_('similarity must be between 0 and 100'))
-    return cmdutil.addremove(repo, pats, opts, similarity=sim / 100.0)
-
+    return scmutil.addremove(repo, pats, opts, similarity=sim / 100.0)
+
+@command('^annotate|blame',
+    [('r', 'rev', '', _('annotate the specified revision'), _('REV')),
+    ('', 'follow', None,
+     _('follow copies/renames and list the filename (DEPRECATED)')),
+    ('', 'no-follow', None, _("don't follow copies and renames")),
+    ('a', 'text', None, _('treat all files as text')),
+    ('u', 'user', None, _('list the author (long with -v)')),
+    ('f', 'file', None, _('list the filename')),
+    ('d', 'date', None, _('list the date (short with -q)')),
+    ('n', 'number', None, _('list the revision number (default)')),
+    ('c', 'changeset', None, _('list the changeset')),
+    ('l', 'line-number', None, _('show line number at the first appearance'))
+    ] + walkopts,
+    _('[-r REV] [-f] [-a] [-u] [-d] [-n] [-c] [-l] FILE...'))
 def annotate(ui, repo, *pats, **opts):
     """show changeset information by line for each file
 
@@ -98,7 +231,7 @@
     if opts.get('follow'):
         # --follow is deprecated and now just an alias for -f/--file
         # to mimic the behavior of Mercurial before version 1.5
-        opts['file'] = 1
+        opts['file'] = True
 
     datefunc = ui.quiet and util.shortdate or util.datestr
     getdate = util.cachefunc(lambda x: datefunc(x[0].date()))
@@ -106,28 +239,31 @@
     if not pats:
         raise util.Abort(_('at least one filename or pattern is required'))
 
-    opmap = [('user', lambda x: ui.shortuser(x[0].user())),
-             ('number', lambda x: str(x[0].rev())),
-             ('changeset', lambda x: short(x[0].node())),
-             ('date', getdate),
-             ('file', lambda x: x[0].path()),
+    opmap = [('user', ' ', lambda x: ui.shortuser(x[0].user())),
+             ('number', ' ', lambda x: str(x[0].rev())),
+             ('changeset', ' ', lambda x: short(x[0].node())),
+             ('date', ' ', getdate),
+             ('file', ' ', lambda x: x[0].path()),
+             ('line_number', ':', lambda x: str(x[1])),
             ]
 
     if (not opts.get('user') and not opts.get('changeset')
         and not opts.get('date') and not opts.get('file')):
-        opts['number'] = 1
+        opts['number'] = True
 
     linenumber = opts.get('line_number') is not None
     if linenumber and (not opts.get('changeset')) and (not opts.get('number')):
         raise util.Abort(_('at least one of -n/-c is required for -l'))
 
-    funcmap = [func for op, func in opmap if opts.get(op)]
-    if linenumber:
-        lastfunc = funcmap[-1]
-        funcmap[-1] = lambda x: "%s:%s" % (lastfunc(x), x[1])
-
-    ctx = cmdutil.revsingle(repo, opts.get('rev'))
-    m = cmdutil.match(repo, pats, opts)
+    funcmap = [(func, sep) for op, sep, func in opmap if opts.get(op)]
+    funcmap[0] = (funcmap[0][0], '') # no separator in front of first column
+
+    def bad(x, y):
+        raise util.Abort("%s: %s" % (x, y))
+
+    ctx = scmutil.revsingle(repo, opts.get('rev'))
+    m = scmutil.match(ctx, pats, opts)
+    m.bad = bad
     follow = not opts.get('no_follow')
     for abs in ctx.walk(m):
         fctx = ctx[abs]
@@ -138,17 +274,26 @@
         lines = fctx.annotate(follow=follow, linenumber=linenumber)
         pieces = []
 
-        for f in funcmap:
+        for f, sep in funcmap:
             l = [f(n) for n, dummy in lines]
             if l:
                 sized = [(x, encoding.colwidth(x)) for x in l]
                 ml = max([w for x, w in sized])
-                pieces.append(["%s%s" % (' ' * (ml - w), x) for x, w in sized])
+                pieces.append(["%s%s%s" % (sep, ' ' * (ml - w), x)
+                               for x, w in sized])
 
         if pieces:
             for p, l in zip(zip(*pieces), lines):
-                ui.write("%s: %s" % (" ".join(p), l[1]))
-
+                ui.write("%s: %s" % ("".join(p), l[1]))
+
+@command('archive',
+    [('', 'no-decode', None, _('do not pass files through decoders')),
+    ('p', 'prefix', '', _('directory prefix for files in archive'),
+     _('PREFIX')),
+    ('r', 'rev', '', _('revision to distribute'), _('REV')),
+    ('t', 'type', '', _('type of distribution to create'), _('TYPE')),
+    ] + subrepoopts + walkopts,
+    _('[OPTION]... DEST'))
 def archive(ui, repo, dest, **opts):
     '''create an unversioned archive of a repository revision
 
@@ -178,11 +323,11 @@
     Returns 0 on success.
     '''
 
-    ctx = cmdutil.revsingle(repo, opts.get('rev'))
+    ctx = scmutil.revsingle(repo, opts.get('rev'))
     if not ctx:
         raise util.Abort(_('no working directory: please specify a revision'))
     node = ctx.node()
-    dest = cmdutil.make_filename(repo, dest, node)
+    dest = cmdutil.makefilename(repo, dest, node)
     if os.path.realpath(dest) == repo.root:
         raise util.Abort(_('repository root cannot be destination'))
 
@@ -192,15 +337,22 @@
     if dest == '-':
         if kind == 'files':
             raise util.Abort(_('cannot archive plain files to stdout'))
-        dest = sys.stdout
+        dest = ui.fout
         if not prefix:
             prefix = os.path.basename(repo.root) + '-%h'
 
-    prefix = cmdutil.make_filename(repo, prefix, node)
-    matchfn = cmdutil.match(repo, [], opts)
+    prefix = cmdutil.makefilename(repo, prefix, node)
+    matchfn = scmutil.match(ctx, [], opts)
     archival.archive(repo, dest, node, kind, not opts.get('no_decode'),
                      matchfn, prefix, subrepos=opts.get('subrepos'))
 
+@command('backout',
+    [('', 'merge', None, _('merge with old dirstate parent after backout')),
+    ('', 'parent', '', _('parent to choose when backing out merge'), _('REV')),
+    ('t', 'tool', '', _('specify merge tool')),
+    ('r', 'rev', '', _('revision to backout'), _('REV')),
+    ] + walkopts + commitopts + commitopts2,
+    _('[OPTION]... [-r] REV'))
 def backout(ui, repo, node=None, rev=None, **opts):
     '''reverse effect of earlier changeset
 
@@ -238,8 +390,8 @@
     if date:
         opts['date'] = util.parsedate(date)
 
-    cmdutil.bail_if_changed(repo)
-    node = cmdutil.revsingle(repo, rev).node()
+    cmdutil.bailifchanged(repo)
+    node = scmutil.revsingle(repo, rev).node()
 
     op1, op2 = repo.dirstate.parents()
     a = repo.changelog.ancestor(op1, node)
@@ -302,8 +454,18 @@
             ui.setconfig('ui', 'forcemerge', '')
     return 0
 
+@command('bisect',
+    [('r', 'reset', False, _('reset bisect state')),
+    ('g', 'good', False, _('mark changeset good')),
+    ('b', 'bad', False, _('mark changeset bad')),
+    ('s', 'skip', False, _('skip testing changeset')),
+    ('e', 'extend', False, _('extend the bisect range')),
+    ('c', 'command', '', _('use command to check changeset state'), _('CMD')),
+    ('U', 'noupdate', False, _('do not update to target'))],
+    _("[-gbsr] [-U] [-c CMD] [REV]"))
 def bisect(ui, repo, rev=None, extra=None, command=None,
-               reset=None, good=None, bad=None, skip=None, noupdate=None):
+               reset=None, good=None, bad=None, skip=None, extend=None,
+               noupdate=None):
     """subdivision search of changesets
 
     This command helps to find changesets which introduce problems. To
@@ -326,6 +488,17 @@
 
     Returns 0 on success.
     """
+    def extendbisectrange(nodes, good):
+        # bisect is incomplete when it ends on a merge node and
+        # one of the parent was not checked.
+        parents = repo[nodes[0]].parents()
+        if len(parents) > 1:
+            side = good and state['bad'] or state['good']
+            num = len(set(i.node() for i in parents) & set(side))
+            if num == 1:
+                return parents[0].ancestor(parents[1])
+        return None
+
     def print_result(nodes, good):
         displayer = cmdutil.show_changeset(ui, repo, {})
         if len(nodes) == 1:
@@ -335,15 +508,12 @@
             else:
                 ui.write(_("The first bad revision is:\n"))
             displayer.show(repo[nodes[0]])
-            parents = repo[nodes[0]].parents()
-            if len(parents) > 1:
-                side = good and state['bad'] or state['good']
-                num = len(set(i.node() for i in parents) & set(side))
-                if num == 1:
-                    common = parents[0].ancestor(parents[1])
-                    ui.write(_('Not all ancestors of this changeset have been'
-                               ' checked.\nTo check the other ancestors, start'
-                               ' from the common ancestor, %s.\n' % common))
+            extendnode = extendbisectrange(nodes, good)
+            if extendnode is not None:
+                ui.write(_('Not all ancestors of this changeset have been'
+                           ' checked.\nUse bisect --extend to continue the '
+                           'bisection from\nthe common ancestor, %s.\n')
+                         % extendnode)
         else:
             # multiple possible revisions
             if good:
@@ -376,7 +546,7 @@
             bad = True
         else:
             reset = True
-    elif extra or good + bad + skip + reset + bool(command) > 1:
+    elif extra or good + bad + skip + reset + extend + bool(command) > 1:
         raise util.Abort(_('incompatible arguments'))
 
     if reset:
@@ -404,7 +574,7 @@
                     raise util.Abort(_("%s killed") % command)
                 else:
                     transition = "bad"
-                ctx = cmdutil.revsingle(repo, rev)
+                ctx = scmutil.revsingle(repo, rev)
                 rev = None # clear for future iterations
                 state[transition].append(ctx.node())
                 ui.status(_('Changeset %d:%s: %s\n') % (ctx, ctx, transition))
@@ -412,7 +582,7 @@
                 # bisect
                 nodes, changesets, good = hbisect.bisect(repo.changelog, state)
                 # update to next check
-                cmdutil.bail_if_changed(repo)
+                cmdutil.bailifchanged(repo)
                 hg.clean(repo, nodes[0], show_stats=False)
         finally:
             hbisect.save_state(repo, state)
@@ -422,7 +592,7 @@
     # update state
 
     if rev:
-        nodes = [repo.lookup(i) for i in cmdutil.revrange(repo, [rev])]
+        nodes = [repo.lookup(i) for i in scmutil.revrange(repo, [rev])]
     else:
         nodes = [repo.lookup('.')]
 
@@ -440,6 +610,18 @@
 
     # actually bisect
     nodes, changesets, good = hbisect.bisect(repo.changelog, state)
+    if extend:
+        if not changesets:
+            extendnode = extendbisectrange(nodes, good)
+            if extendnode is not None:
+                ui.write(_("Extending search to changeset %d:%s\n"
+                         % (extendnode.rev(), extendnode)))
+                if noupdate:
+                    return
+                cmdutil.bailifchanged(repo)
+                return hg.clean(repo, extendnode.node())
+        raise util.Abort(_("nothing to extend"))
+
     if changesets == 0:
         print_result(nodes, good)
     else:
@@ -454,10 +636,18 @@
                    "(%d changesets remaining, ~%d tests)\n")
                  % (rev, short(node), changesets, tests))
         if not noupdate:
-            cmdutil.bail_if_changed(repo)
+            cmdutil.bailifchanged(repo)
             return hg.clean(repo, node)
 
-def bookmark(ui, repo, mark=None, rev=None, force=False, delete=False, rename=None):
+@command('bookmarks',
+    [('f', 'force', False, _('force')),
+    ('r', 'rev', '', _('revision'), _('REV')),
+    ('d', 'delete', False, _('delete a given bookmark')),
+    ('m', 'rename', '', _('rename a given bookmark'), _('NAME')),
+    ('i', 'inactive', False, _('do not mark a new bookmark active'))],
+    _('hg bookmarks [-f] [-d] [-i] [-m NAME] [-r REV] [NAME]'))
+def bookmark(ui, repo, mark=None, rev=None, force=False, delete=False,
+             rename=None, inactive=False):
     '''track a line of development with movable markers
 
     Bookmarks are pointers to certain commits that move when
@@ -481,13 +671,14 @@
 
     if rename:
         if rename not in marks:
-            raise util.Abort(_("a bookmark of this name does not exist"))
+            raise util.Abort(_("bookmark '%s' does not exist") % rename)
         if mark in marks and not force:
-            raise util.Abort(_("a bookmark of the same name already exists"))
+            raise util.Abort(_("bookmark '%s' already exists "
+                               "(use -f to force)") % mark)
         if mark is None:
             raise util.Abort(_("new bookmark name required"))
         marks[mark] = marks[rename]
-        if repo._bookmarkcurrent == rename:
+        if repo._bookmarkcurrent == rename and not inactive:
             bookmarks.setcurrent(repo, mark)
         del marks[rename]
         bookmarks.write(repo)
@@ -497,7 +688,7 @@
         if mark is None:
             raise util.Abort(_("bookmark name required"))
         if mark not in marks:
-            raise util.Abort(_("a bookmark of this name does not exist"))
+            raise util.Abort(_("bookmark '%s' does not exist") % mark)
         if mark == repo._bookmarkcurrent:
             bookmarks.setcurrent(repo, None)
         del marks[mark]
@@ -511,8 +702,12 @@
         if not mark:
             raise util.Abort(_("bookmark names cannot consist entirely of "
                                "whitespace"))
+        if inactive and mark == repo._bookmarkcurrent:
+            bookmarks.setcurrent(repo, None)
+            return
         if mark in marks and not force:
-            raise util.Abort(_("a bookmark of the same name already exists"))
+            raise util.Abort(_("bookmark '%s' already exists "
+                               "(use -f to force)") % mark)
         if ((mark in repo.branchtags() or mark == repo.dirstate.branch())
             and not force):
             raise util.Abort(
@@ -521,7 +716,7 @@
             marks[mark] = repo.lookup(rev)
         else:
             marks[mark] = repo.changectx('.').node()
-        if repo.changectx('.').node() == marks[mark]:
+        if not inactive and repo.changectx('.').node() == marks[mark]:
             bookmarks.setcurrent(repo, mark)
         bookmarks.write(repo)
         return
@@ -547,6 +742,11 @@
                         label=label)
         return
 
+@command('branch',
+    [('f', 'force', None,
+     _('set branch name even if it shadows an existing branch')),
+    ('C', 'clean', None, _('reset branch name to parent branch name'))],
+    _('[-fC] [NAME]'))
 def branch(ui, repo, label=None, **opts):
     """set or show the current branch name
 
@@ -566,23 +766,34 @@
     Use the command :hg:`update` to switch to an existing branch. Use
     :hg:`commit --close-branch` to mark this branch as closed.
 
+    .. note::
+
+       Branch names are permanent. Use :hg:`bookmark` to create a
+       light-weight bookmark instead. See :hg:`help glossary` for more
+       information about named branches and bookmarks.
+
     Returns 0 on success.
     """
 
     if opts.get('clean'):
-        label = repo[None].parents()[0].branch()
+        label = repo[None].p1().branch()
         repo.dirstate.setbranch(label)
         ui.status(_('reset working directory to branch %s\n') % label)
     elif label:
         if not opts.get('force') and label in repo.branchtags():
             if label not in [p.branch() for p in repo.parents()]:
-                raise util.Abort(_('a branch of the same name already exists'
-                                   " (use 'hg update' to switch to it)"))
+                raise util.Abort(_('a branch of the same name already exists'),
+                                 # i18n: "it" refers to an existing branch
+                                 hint=_("use 'hg update' to switch to it"))
         repo.dirstate.setbranch(label)
         ui.status(_('marked working directory as branch %s\n') % label)
     else:
         ui.write("%s\n" % repo.dirstate.branch())
 
+@command('branches',
+    [('a', 'active', False, _('show only branches that have unmerged heads')),
+    ('c', 'closed', False, _('show normal and closed branches'))],
+    _('[-ac]'))
 def branches(ui, repo, active=False, closed=False):
     """list repository named branches
 
@@ -632,6 +843,19 @@
                 tag = ui.label(tag, label)
                 ui.write("%s %s%s\n" % (tag, rev, notice))
 
+@command('bundle',
+    [('f', 'force', None, _('run even when the destination is unrelated')),
+    ('r', 'rev', [], _('a changeset intended to be added to the destination'),
+     _('REV')),
+    ('b', 'branch', [], _('a specific branch you would like to bundle'),
+     _('BRANCH')),
+    ('', 'base', [],
+     _('a base changeset assumed to be available at the destination'),
+     _('REV')),
+    ('a', 'all', None, _('bundle all changesets in the repository')),
+    ('t', 'type', 'bzip2', _('bundle compression type to use'), _('TYPE')),
+    ] + remoteopts,
+    _('[-f] [-t TYPE] [-a] [-r REV]... [--base REV]... FILE [DEST]'))
 def bundle(ui, repo, fname, dest=None, **opts):
     """create a changegroup file
 
@@ -659,59 +883,33 @@
     """
     revs = None
     if 'rev' in opts:
-        revs = cmdutil.revrange(repo, opts['rev'])
+        revs = scmutil.revrange(repo, opts['rev'])
 
     if opts.get('all'):
         base = ['null']
     else:
-        base = cmdutil.revrange(repo, opts.get('base'))
+        base = scmutil.revrange(repo, opts.get('base'))
     if base:
         if dest:
             raise util.Abort(_("--base is incompatible with specifying "
                                "a destination"))
-        base = [repo.lookup(rev) for rev in base]
-        # create the right base
-        # XXX: nodesbetween / changegroup* should be "fixed" instead
-        o = []
-        has = set((nullid,))
-        for n in base:
-            has.update(repo.changelog.reachable(n))
-        if revs:
-            revs = [repo.lookup(rev) for rev in revs]
-            visit = revs[:]
-            has.difference_update(visit)
-        else:
-            visit = repo.changelog.heads()
-        seen = {}
-        while visit:
-            n = visit.pop(0)
-            parents = [p for p in repo.changelog.parents(n) if p not in has]
-            if len(parents) == 0:
-                if n not in has:
-                    o.append(n)
-            else:
-                for p in parents:
-                    if p not in seen:
-                        seen[p] = 1
-                        visit.append(p)
+        common = [repo.lookup(rev) for rev in base]
+        heads = revs and map(repo.lookup, revs) or revs
     else:
         dest = ui.expandpath(dest or 'default-push', dest or 'default')
         dest, branches = hg.parseurl(dest, opts.get('branch'))
-        other = hg.repository(hg.remoteui(repo, opts), dest)
+        other = hg.peer(repo, opts, dest)
         revs, checkout = hg.addbranchrevs(repo, other, branches, revs)
-        if revs:
-            revs = [repo.lookup(rev) for rev in revs]
-        o = discovery.findoutgoing(repo, other, force=opts.get('force'))
-
-    if not o:
+        heads = revs and map(repo.lookup, revs) or revs
+        common, outheads = discovery.findcommonoutgoing(repo, other,
+                                                        onlyheads=heads,
+                                                        force=opts.get('force'))
+
+    cg = repo.getbundle('bundle', common=common, heads=heads)
+    if not cg:
         ui.status(_("no changes found\n"))
         return 1
 
-    if revs:
-        cg = repo.changegroupsubset(o, revs, 'bundle')
-    else:
-        cg = repo.changegroup(o, 'bundle')
-
     bundletype = opts.get('type', 'bzip2').lower()
     btypes = {'none': 'HG10UN', 'bzip2': 'HG10BZ', 'gzip': 'HG10GZ'}
     bundletype = btypes.get(bundletype)
@@ -720,6 +918,13 @@
 
     changegroup.writebundle(cg, fname, bundletype)
 
+@command('cat',
+    [('o', 'output', '',
+     _('print output to file with formatted name'), _('FORMAT')),
+    ('r', 'rev', '', _('print the given revision'), _('REV')),
+    ('', 'decode', None, _('apply any matching decode filter')),
+    ] + walkopts,
+    _('[OPTION]... FILE...'))
 def cat(ui, repo, file1, *pats, **opts):
     """output the current or given revision of files
 
@@ -737,11 +942,12 @@
 
     Returns 0 on success.
     """
-    ctx = cmdutil.revsingle(repo, opts.get('rev'))
+    ctx = scmutil.revsingle(repo, opts.get('rev'))
     err = 1
-    m = cmdutil.match(repo, (file1,) + pats, opts)
+    m = scmutil.match(ctx, (file1,) + pats, opts)
     for abs in ctx.walk(m):
-        fp = cmdutil.make_file(repo, opts.get('output'), ctx.node(), pathname=abs)
+        fp = cmdutil.makefileobj(repo, opts.get('output'), ctx.node(),
+                                 pathname=abs)
         data = ctx[abs].data()
         if opts.get('decode'):
             data = repo.wwritedata(abs, data)
@@ -750,6 +956,16 @@
         err = 0
     return err
 
+@command('^clone',
+    [('U', 'noupdate', None,
+     _('the clone will include an empty working copy (only a repository)')),
+    ('u', 'updaterev', '', _('revision, tag or branch to check out'), _('REV')),
+    ('r', 'rev', [], _('include the specified changeset'), _('REV')),
+    ('b', 'branch', [], _('clone only the specified branch'), _('BRANCH')),
+    ('', 'pull', None, _('use pull protocol to copy metadata')),
+    ('', 'uncompressed', None, _('use uncompressed transfer (fast over LAN)')),
+    ] + remoteopts,
+    _('[OPTION]... SOURCE [DEST]'))
 def clone(ui, source, dest=None, **opts):
     """make a copy of an existing repository
 
@@ -817,7 +1033,7 @@
     if opts.get('noupdate') and opts.get('updaterev'):
         raise util.Abort(_("cannot specify both --noupdate and --updaterev"))
 
-    r = hg.clone(hg.remoteui(ui, opts), source, dest,
+    r = hg.clone(ui, opts, source, dest,
                  pull=opts.get('pull'),
                  stream=opts.get('uncompressed'),
                  rev=opts.get('rev'),
@@ -826,6 +1042,13 @@
 
     return r is None
 
+@command('^commit|ci',
+    [('A', 'addremove', None,
+     _('mark new/missing files as added/removed before committing')),
+    ('', 'close-branch', None,
+     _('mark a branch as closed, hiding it from the branch list')),
+    ] + walkopts + commitopts + commitopts2,
+    _('[OPTION]... [FILE]...'))
 def commit(ui, repo, *pats, **opts):
     """commit the specified files or all outstanding changes
 
@@ -868,7 +1091,12 @@
 
     node = cmdutil.commit(ui, repo, commitfunc, pats, opts)
     if not node:
-        ui.status(_("nothing changed\n"))
+        stat = repo.status(match=scmutil.match(repo[None], pats, opts))
+        if stat[3]:
+            ui.status(_("nothing changed (%d missing files, see 'hg status')\n")
+                      % len(stat[3]))
+        else:
+            ui.status(_("nothing changed\n"))
         return 1
 
     ctx = repo[node]
@@ -916,6 +1144,11 @@
     elif ui.verbose:
         ui.write(_('committed changeset %d:%s\n') % (int(ctx), ctx))
 
+@command('copy|cp',
+    [('A', 'after', None, _('record a copy that has already occurred')),
+    ('f', 'force', None, _('forcibly copy over an existing managed file')),
+    ] + walkopts + dryrunopts,
+    _('[OPTION]... [SOURCE]... DEST'))
 def copy(ui, repo, *pats, **opts):
     """mark files as copied for the next commit
 
@@ -938,11 +1171,12 @@
     finally:
         wlock.release()
 
+@command('debugancestor', [], _('[INDEX] REV1 REV2'))
 def debugancestor(ui, repo, *args):
     """find the ancestor revision of two revisions in a given index"""
     if len(args) == 3:
         index, rev1, rev2 = args
-        r = revlog.revlog(util.opener(os.getcwd(), audit=False), index)
+        r = revlog.revlog(scmutil.opener(os.getcwd(), audit=False), index)
         lookup = r.lookup
     elif len(args) == 2:
         if not repo:
@@ -956,12 +1190,19 @@
     a = r.ancestor(lookup(rev1), lookup(rev2))
     ui.write("%d:%s\n" % (r.rev(a), hex(a)))
 
-def debugbuilddag(ui, repo, text,
+@command('debugbuilddag',
+    [('m', 'mergeable-file', None, _('add single file mergeable changes')),
+    ('o', 'overwritten-file', None, _('add single file all revs overwrite')),
+    ('n', 'new-file', None, _('add new file at each rev'))],
+    _('[OPTION]... [TEXT]'))
+def debugbuilddag(ui, repo, text=None,
                   mergeable_file=False,
-                  appended_file=False,
                   overwritten_file=False,
                   new_file=False):
-    """builds a repo with a given dag from scratch in the current empty repo
+    """builds a repo with a given DAG from scratch in the current empty repo
+
+    The description of the DAG is read from stdin if not given on the
+    command line.
 
     Elements:
 
@@ -975,8 +1216,6 @@
      - "/p2" is a merge of the preceding node and p2
      - ":tag" defines a local tag for the preceding node
      - "@branch" sets the named branch for subsequent nodes
-     - "!command" runs the command using your shell
-     - "!!my command\\n" is like "!", but to the end of the line
      - "#...\\n" is a comment up to the end of the line
 
     Whitespace between the above elements is ignored.
@@ -990,138 +1229,165 @@
 
     All string valued-elements are either strictly alphanumeric, or must
     be enclosed in double quotes ("..."), with "\\" as escape character.
-
-    Note that the --overwritten-file and --appended-file options imply the
-    use of "HGMERGE=internal:local" during DAG buildup.
     """
 
-    if not (mergeable_file or appended_file or overwritten_file or new_file):
-        raise util.Abort(_('need at least one of -m, -a, -o, -n'))
-
-    if len(repo.changelog) > 0:
+    if text is None:
+        ui.status(_("reading DAG from stdin\n"))
+        text = ui.fin.read()
+
+    cl = repo.changelog
+    if len(cl) > 0:
         raise util.Abort(_('repository is not empty'))
 
-    if overwritten_file or appended_file:
-        # we don't want to fail in merges during buildup
-        os.environ['HGMERGE'] = 'internal:local'
-
-    def writefile(fname, text, fmode="wb"):
-        f = open(fname, fmode)
-        try:
-            f.write(text)
-        finally:
-            f.close()
+    # determine number of revs in DAG
+    total = 0
+    for type, data in dagparser.parsedag(text):
+        if type == 'n':
+            total += 1
 
     if mergeable_file:
         linesperrev = 2
-        # determine number of revs in DAG
-        n = 0
+        # make a file with k lines per rev
+        initialmergedlines = [str(i) for i in xrange(0, total * linesperrev)]
+        initialmergedlines.append("")
+
+    tags = []
+
+    tr = repo.transaction("builddag")
+    try:
+
+        at = -1
+        atbranch = 'default'
+        nodeids = []
+        ui.progress(_('building'), 0, unit=_('revisions'), total=total)
         for type, data in dagparser.parsedag(text):
             if type == 'n':
-                n += 1
-        # make a file with k lines per rev
-        writefile("mf", "\n".join(str(i) for i in xrange(0, n * linesperrev))
-                  + "\n")
-
-    at = -1
-    atbranch = 'default'
-    for type, data in dagparser.parsedag(text):
-        if type == 'n':
-            ui.status('node %s\n' % str(data))
-            id, ps = data
-            p1 = ps[0]
-            if p1 != at:
-                update(ui, repo, node=str(p1), clean=True)
-                at = p1
-            if repo.dirstate.branch() != atbranch:
-                branch(ui, repo, atbranch, force=True)
-            if len(ps) > 1:
-                p2 = ps[1]
-                merge(ui, repo, node=p2)
-
-            if mergeable_file:
-                f = open("mf", "rb+")
-                try:
-                    lines = f.read().split("\n")
-                    lines[id * linesperrev] += " r%i" % id
-                    f.seek(0)
-                    f.write("\n".join(lines))
-                finally:
-                    f.close()
-
-            if appended_file:
-                writefile("af", "r%i\n" % id, "ab")
-
-            if overwritten_file:
-                writefile("of", "r%i\n" % id)
-
-            if new_file:
-                writefile("nf%i" % id, "r%i\n" % id)
-
-            commit(ui, repo, addremove=True, message="r%i" % id, date=(id, 0))
-            at = id
-        elif type == 'l':
-            id, name = data
-            ui.status('tag %s\n' % name)
-            tag(ui, repo, name, local=True)
-        elif type == 'a':
-            ui.status('branch %s\n' % data)
-            atbranch = data
-        elif type in 'cC':
-            r = util.system(data, cwd=repo.root)
-            if r:
-                desc, r = util.explain_exit(r)
-                raise util.Abort(_('%s command %s') % (data, desc))
-
-def debugcommands(ui, cmd='', *args):
-    """list all available commands and options"""
-    for cmd, vals in sorted(table.iteritems()):
-        cmd = cmd.split('|')[0].strip('^')
-        opts = ', '.join([i[1] for i in vals[1]])
-        ui.write('%s: %s\n' % (cmd, opts))
-
-def debugcomplete(ui, cmd='', **opts):
-    """returns the completion list associated with the given command"""
-
-    if opts.get('options'):
-        options = []
-        otables = [globalopts]
-        if cmd:
-            aliases, entry = cmdutil.findcmd(cmd, table, False)
-            otables.append(entry[1])
-        for t in otables:
-            for o in t:
-                if "(DEPRECATED)" in o[3]:
-                    continue
-                if o[0]:
-                    options.append('-%s' % o[0])
-                options.append('--%s' % o[1])
-        ui.write("%s\n" % "\n".join(options))
-        return
-
-    cmdlist = cmdutil.findpossible(cmd, table)
-    if ui.verbose:
-        cmdlist = [' '.join(c[0]) for c in cmdlist.values()]
-    ui.write("%s\n" % "\n".join(sorted(cmdlist)))
-
-def debugfsinfo(ui, path = "."):
-    """show information detected about current filesystem"""
-    open('.debugfsinfo', 'w').write('')
-    ui.write('exec: %s\n' % (util.checkexec(path) and 'yes' or 'no'))
-    ui.write('symlink: %s\n' % (util.checklink(path) and 'yes' or 'no'))
-    ui.write('case-sensitive: %s\n' % (util.checkcase('.debugfsinfo')
-                                and 'yes' or 'no'))
-    os.unlink('.debugfsinfo')
-
-def debugrebuildstate(ui, repo, rev="tip"):
-    """rebuild the dirstate as it would look like for the given revision"""
-    ctx = cmdutil.revsingle(repo, rev)
-    wlock = repo.wlock()
+                ui.note('node %s\n' % str(data))
+                id, ps = data
+
+                files = []
+                fctxs = {}
+
+                p2 = None
+                if mergeable_file:
+                    fn = "mf"
+                    p1 = repo[ps[0]]
+                    if len(ps) > 1:
+                        p2 = repo[ps[1]]
+                        pa = p1.ancestor(p2)
+                        base, local, other = [x[fn].data() for x in pa, p1, p2]
+                        m3 = simplemerge.Merge3Text(base, local, other)
+                        ml = [l.strip() for l in m3.merge_lines()]
+                        ml.append("")
+                    elif at > 0:
+                        ml = p1[fn].data().split("\n")
+                    else:
+                        ml = initialmergedlines
+                    ml[id * linesperrev] += " r%i" % id
+                    mergedtext = "\n".join(ml)
+                    files.append(fn)
+                    fctxs[fn] = context.memfilectx(fn, mergedtext)
+
+                if overwritten_file:
+                    fn = "of"
+                    files.append(fn)
+                    fctxs[fn] = context.memfilectx(fn, "r%i\n" % id)
+
+                if new_file:
+                    fn = "nf%i" % id
+                    files.append(fn)
+                    fctxs[fn] = context.memfilectx(fn, "r%i\n" % id)
+                    if len(ps) > 1:
+                        if not p2:
+                            p2 = repo[ps[1]]
+                        for fn in p2:
+                            if fn.startswith("nf"):
+                                files.append(fn)
+                                fctxs[fn] = p2[fn]
+
+                def fctxfn(repo, cx, path):
+                    return fctxs.get(path)
+
+                if len(ps) == 0 or ps[0] < 0:
+                    pars = [None, None]
+                elif len(ps) == 1:
+                    pars = [nodeids[ps[0]], None]
+                else:
+                    pars = [nodeids[p] for p in ps]
+                cx = context.memctx(repo, pars, "r%i" % id, files, fctxfn,
+                                    date=(id, 0),
+                                    user="debugbuilddag",
+                                    extra={'branch': atbranch})
+                nodeid = repo.commitctx(cx)
+                nodeids.append(nodeid)
+                at = id
+            elif type == 'l':
+                id, name = data
+                ui.note('tag %s\n' % name)
+                tags.append("%s %s\n" % (hex(repo.changelog.node(id)), name))
+            elif type == 'a':
+                ui.note('branch %s\n' % data)
+                atbranch = data
+            ui.progress(_('building'), id, unit=_('revisions'), total=total)
+        tr.close()
+    finally:
+        ui.progress(_('building'), None)
+        tr.release()
+
+    if tags:
+        repo.opener.write("localtags", "".join(tags))
+
+@command('debugbundle', [('a', 'all', None, _('show all details'))], _('FILE'))
+def debugbundle(ui, bundlepath, all=None, **opts):
+    """lists the contents of a bundle"""
+    f = url.open(ui, bundlepath)
     try:
-        repo.dirstate.rebuild(ctx.node(), ctx.manifest())
+        gen = changegroup.readbundle(f, bundlepath)
+        if all:
+            ui.write("format: id, p1, p2, cset, delta base, len(delta)\n")
+
+            def showchunks(named):
+                ui.write("\n%s\n" % named)
+                chain = None
+                while True:
+                    chunkdata = gen.deltachunk(chain)
+                    if not chunkdata:
+                        break
+                    node = chunkdata['node']
+                    p1 = chunkdata['p1']
+                    p2 = chunkdata['p2']
+                    cs = chunkdata['cs']
+                    deltabase = chunkdata['deltabase']
+                    delta = chunkdata['delta']
+                    ui.write("%s %s %s %s %s %s\n" %
+                             (hex(node), hex(p1), hex(p2),
+                              hex(cs), hex(deltabase), len(delta)))
+                    chain = node
+
+            chunkdata = gen.changelogheader()
+            showchunks("changelog")
+            chunkdata = gen.manifestheader()
+            showchunks("manifest")
+            while True:
+                chunkdata = gen.filelogheader()
+                if not chunkdata:
+                    break
+                fname = chunkdata['filename']
+                showchunks(fname)
+        else:
+            chunkdata = gen.changelogheader()
+            chain = None
+            while True:
+                chunkdata = gen.deltachunk(chain)
+                if not chunkdata:
+                    break
+                node = chunkdata['node']
+                ui.write("%s\n" % hex(node))
+                chain = node
     finally:
-        wlock.release()
-
+        f.close()
+
+@command('debugcheckstate', [], '')
 def debugcheckstate(ui, repo):
     """validate the correctness of the current dirstate"""
     parent1, parent2 = repo.dirstate.parents()
@@ -1149,126 +1415,47 @@
         error = _(".hg/dirstate inconsistent with current parent's manifest")
         raise util.Abort(error)
 
-def showconfig(ui, repo, *values, **opts):
-    """show combined config settings from all hgrc files
-
-    With no arguments, print names and values of all config items.
-
-    With one argument of the form section.name, print just the value
-    of that config item.
-
-    With multiple arguments, print names and values of all config
-    items with matching section names.
-
-    With --debug, the source (filename and line number) is printed
-    for each config item.
-
-    Returns 0 on success.
-    """
-
-    for f in util.rcpath():
-        ui.debug(_('read config from: %s\n') % f)
-    untrusted = bool(opts.get('untrusted'))
-    if values:
-        sections = [v for v in values if '.' not in v]
-        items = [v for v in values if '.' in v]
-        if len(items) > 1 or items and sections:
-            raise util.Abort(_('only one config item permitted'))
-    for section, name, value in ui.walkconfig(untrusted=untrusted):
-        sectname = section + '.' + name
-        if values:
-            for v in values:
-                if v == section:
-                    ui.debug('%s: ' %
-                             ui.configsource(section, name, untrusted))
-                    ui.write('%s=%s\n' % (sectname, value))
-                elif v == sectname:
-                    ui.debug('%s: ' %
-                             ui.configsource(section, name, untrusted))
-                    ui.write(value, '\n')
-        else:
-            ui.debug('%s: ' %
-                     ui.configsource(section, name, untrusted))
-            ui.write('%s=%s\n' % (sectname, value))
-
-def debugpushkey(ui, repopath, namespace, *keyinfo):
-    '''access the pushkey key/value protocol
-
-    With two args, list the keys in the given namespace.
-
-    With five args, set a key to new if it currently is set to old.
-    Reports success or failure.
-    '''
-
-    target = hg.repository(ui, repopath)
-    if keyinfo:
-        key, old, new = keyinfo
-        r = target.pushkey(namespace, key, old, new)
-        ui.status(str(r) + '\n')
-        return not r
-    else:
-        for k, v in target.listkeys(namespace).iteritems():
-            ui.write("%s\t%s\n" % (k.encode('string-escape'),
-                                   v.encode('string-escape')))
-
-def debugrevspec(ui, repo, expr):
-    '''parse and apply a revision specification'''
+@command('debugcommands', [], _('[COMMAND]'))
+def debugcommands(ui, cmd='', *args):
+    """list all available commands and options"""
+    for cmd, vals in sorted(table.iteritems()):
+        cmd = cmd.split('|')[0].strip('^')
+        opts = ', '.join([i[1] for i in vals[1]])
+        ui.write('%s: %s\n' % (cmd, opts))
+
+@command('debugcomplete',
+    [('o', 'options', None, _('show the command options'))],
+    _('[-o] CMD'))
+def debugcomplete(ui, cmd='', **opts):
+    """returns the completion list associated with the given command"""
+
+    if opts.get('options'):
+        options = []
+        otables = [globalopts]
+        if cmd:
+            aliases, entry = cmdutil.findcmd(cmd, table, False)
+            otables.append(entry[1])
+        for t in otables:
+            for o in t:
+                if "(DEPRECATED)" in o[3]:
+                    continue
+                if o[0]:
+                    options.append('-%s' % o[0])
+                options.append('--%s' % o[1])
+        ui.write("%s\n" % "\n".join(options))
+        return
+
+    cmdlist = cmdutil.findpossible(cmd, table)
     if ui.verbose:
-        tree = revset.parse(expr)[0]
-        ui.note(tree, "\n")
-    func = revset.match(expr)
-    for c in func(repo, range(len(repo))):
-        ui.write("%s\n" % c)
-
-def debugsetparents(ui, repo, rev1, rev2=None):
-    """manually set the parents of the current working directory
-
-    This is useful for writing repository conversion tools, but should
-    be used with care.
-
-    Returns 0 on success.
-    """
-
-    r1 = cmdutil.revsingle(repo, rev1).node()
-    r2 = cmdutil.revsingle(repo, rev2, 'null').node()
-
-    wlock = repo.wlock()
-    try:
-        repo.dirstate.setparents(r1, r2)
-    finally:
-        wlock.release()
-
-def debugstate(ui, repo, nodates=None):
-    """show the contents of the current dirstate"""
-    timestr = ""
-    showdate = not nodates
-    for file_, ent in sorted(repo.dirstate._map.iteritems()):
-        if showdate:
-            if ent[3] == -1:
-                # Pad or slice to locale representation
-                locale_len = len(time.strftime("%Y-%m-%d %H:%M:%S ",
-                                               time.localtime(0)))
-                timestr = 'unset'
-                timestr = (timestr[:locale_len] +
-                           ' ' * (locale_len - len(timestr)))
-            else:
-                timestr = time.strftime("%Y-%m-%d %H:%M:%S ",
-                                        time.localtime(ent[3]))
-        if ent[1] & 020000:
-            mode = 'lnk'
-        else:
-            mode = '%3o' % (ent[1] & 0777)
-        ui.write("%c %s %10d %s%s\n" % (ent[0], mode, ent[2], timestr, file_))
-    for f in repo.dirstate.copies():
-        ui.write(_("copy: %s -> %s\n") % (repo.dirstate.copied(f), f))
-
-def debugsub(ui, repo, rev=None):
-    ctx = cmdutil.revsingle(repo, rev, None)
-    for k, v in sorted(ctx.substate.items()):
-        ui.write('path %s\n' % k)
-        ui.write(' source   %s\n' % v[0])
-        ui.write(' revision %s\n' % v[1])
-
+        cmdlist = [' '.join(c[0]) for c in cmdlist.values()]
+    ui.write("%s\n" % "\n".join(sorted(cmdlist)))
+
+@command('debugdag',
+    [('t', 'tags', None, _('use tags as labels')),
+    ('b', 'branches', None, _('annotate with branch names')),
+    ('', 'dots', None, _('use dots for runs')),
+    ('s', 'spaces', None, _('separate elements by spaces'))],
+    _('[OPTION]... [FILE [REV]...]'))
 def debugdag(ui, repo, file_=None, *revs, **opts):
     """format the changelog or an index DAG as a concise textual description
 
@@ -1280,7 +1467,7 @@
     spaces = opts.get('spaces')
     dots = opts.get('dots')
     if file_:
-        rlog = revlog.revlog(util.opener(os.getcwd(), audit=False), file_)
+        rlog = revlog.revlog(scmutil.opener(os.getcwd(), audit=False), file_)
         revs = set((int(r) for r in revs))
         def events():
             for r in rlog:
@@ -1322,20 +1509,25 @@
         ui.write(line)
         ui.write("\n")
 
-def debugdata(ui, repo, file_, rev):
+@command('debugdata',
+    [('c', 'changelog', False, _('open changelog')),
+     ('m', 'manifest', False, _('open manifest'))],
+    _('-c|-m|FILE REV'))
+def debugdata(ui, repo, file_, rev = None, **opts):
     """dump the contents of a data file revision"""
-    r = None
-    if repo:
-        filelog = repo.file(file_)
-        if len(filelog):
-            r = filelog
-    if not r:
-        r = revlog.revlog(util.opener(os.getcwd(), audit=False), file_[:-2] + ".i")
+    if opts.get('changelog') or opts.get('manifest'):
+        file_, rev = None, file_
+    elif rev is None:
+        raise error.CommandError('debugdata', _('invalid arguments'))
+    r = cmdutil.openrevlog(repo, 'debugdata', file_, opts)
     try:
         ui.write(r.revision(r.lookup(rev)))
     except KeyError:
         raise util.Abort(_('invalid revision identifier %s') % rev)
 
+@command('debugdate',
+    [('e', 'extended', None, _('try extended date formats'))],
+    _('[-e] DATE [RANGE]'))
 def debugdate(ui, date, range=None, **opts):
     """parse and display a date"""
     if opts["extended"]:
@@ -1348,6 +1540,119 @@
         m = util.matchdate(range)
         ui.write("match: %s\n" % m(d[0]))
 
+@command('debugdiscovery',
+    [('', 'old', None, _('use old-style discovery')),
+    ('', 'nonheads', None,
+     _('use old-style discovery with non-heads included')),
+    ] + remoteopts,
+    _('[-l REV] [-r REV] [-b BRANCH]... [OTHER]'))
+def debugdiscovery(ui, repo, remoteurl="default", **opts):
+    """runs the changeset discovery protocol in isolation"""
+    remoteurl, branches = hg.parseurl(ui.expandpath(remoteurl), opts.get('branch'))
+    remote = hg.peer(repo, opts, remoteurl)
+    ui.status(_('comparing with %s\n') % util.hidepassword(remoteurl))
+
+    # make sure tests are repeatable
+    random.seed(12323)
+
+    def doit(localheads, remoteheads):
+        if opts.get('old'):
+            if localheads:
+                raise util.Abort('cannot use localheads with old style discovery')
+            common, _in, hds = treediscovery.findcommonincoming(repo, remote,
+                                                                force=True)
+            common = set(common)
+            if not opts.get('nonheads'):
+                ui.write("unpruned common: %s\n" % " ".join([short(n)
+                                                            for n in common]))
+                dag = dagutil.revlogdag(repo.changelog)
+                all = dag.ancestorset(dag.internalizeall(common))
+                common = dag.externalizeall(dag.headsetofconnecteds(all))
+        else:
+            common, any, hds = setdiscovery.findcommonheads(ui, repo, remote)
+        common = set(common)
+        rheads = set(hds)
+        lheads = set(repo.heads())
+        ui.write("common heads: %s\n" % " ".join([short(n) for n in common]))
+        if lheads <= common:
+            ui.write("local is subset\n")
+        elif rheads <= common:
+            ui.write("remote is subset\n")
+
+    serverlogs = opts.get('serverlog')
+    if serverlogs:
+        for filename in serverlogs:
+            logfile = open(filename, 'r')
+            try:
+                line = logfile.readline()
+                while line:
+                    parts = line.strip().split(';')
+                    op = parts[1]
+                    if op == 'cg':
+                        pass
+                    elif op == 'cgss':
+                        doit(parts[2].split(' '), parts[3].split(' '))
+                    elif op == 'unb':
+                        doit(parts[3].split(' '), parts[2].split(' '))
+                    line = logfile.readline()
+            finally:
+                logfile.close()
+
+    else:
+        remoterevs, _checkout = hg.addbranchrevs(repo, remote, branches,
+                                                 opts.get('remote_head'))
+        localrevs = opts.get('local_head')
+        doit(localrevs, remoterevs)
+
+@command('debugfileset', [], ('REVSPEC'))
+def debugfileset(ui, repo, expr):
+    '''parse and apply a fileset specification'''
+    if ui.verbose:
+        tree = fileset.parse(expr)[0]
+        ui.note(tree, "\n")
+
+    for f in fileset.getfileset(repo[None], expr):
+        ui.write("%s\n" % f)
+
+@command('debugfsinfo', [], _('[PATH]'))
+def debugfsinfo(ui, path = "."):
+    """show information detected about current filesystem"""
+    util.writefile('.debugfsinfo', '')
+    ui.write('exec: %s\n' % (util.checkexec(path) and 'yes' or 'no'))
+    ui.write('symlink: %s\n' % (util.checklink(path) and 'yes' or 'no'))
+    ui.write('case-sensitive: %s\n' % (util.checkcase('.debugfsinfo')
+                                and 'yes' or 'no'))
+    os.unlink('.debugfsinfo')
+
+@command('debuggetbundle',
+    [('H', 'head', [], _('id of head node'), _('ID')),
+    ('C', 'common', [], _('id of common node'), _('ID')),
+    ('t', 'type', 'bzip2', _('bundle compression type to use'), _('TYPE'))],
+    _('REPO FILE [-H|-C ID]...'))
+def debuggetbundle(ui, repopath, bundlepath, head=None, common=None, **opts):
+    """retrieves a bundle from a repo
+
+    Every ID must be a full-length hex node id string. Saves the bundle to the
+    given file.
+    """
+    repo = hg.peer(ui, opts, repopath)
+    if not repo.capable('getbundle'):
+        raise util.Abort("getbundle() not supported by target repository")
+    args = {}
+    if common:
+        args['common'] = [bin(s) for s in common]
+    if head:
+        args['heads'] = [bin(s) for s in head]
+    bundle = repo.getbundle('debug', **args)
+
+    bundletype = opts.get('type', 'bzip2').lower()
+    btypes = {'none': 'HG10UN', 'bzip2': 'HG10BZ', 'gzip': 'HG10GZ'}
+    bundletype = btypes.get(bundletype)
+    if bundletype not in changegroup.bundletypes:
+        raise util.Abort(_('unknown bundle type specified with --type'))
+    changegroup.writebundle(bundle, bundlepath, bundletype)
+
+@command('debugignore', [], '')
 def debugignore(ui, repo, *values, **opts):
     """display the combined ignore pattern"""
     ignore = repo.dirstate._ignore
@@ -1356,44 +1661,52 @@
     else:
         raise util.Abort(_("no ignore patterns found"))
 
-def debugindex(ui, repo, file_, **opts):
+@command('debugindex',
+    [('c', 'changelog', False, _('open changelog')),
+     ('m', 'manifest', False, _('open manifest')),
+     ('f', 'format', 0, _('revlog format'), _('FORMAT'))],
+    _('[-f FORMAT] -c|-m|FILE'))
+def debugindex(ui, repo, file_ = None, **opts):
     """dump the contents of an index file"""
-    r = None
-    if repo:
-        filelog = repo.file(file_)
-        if len(filelog):
-            r = filelog
-
+    r = cmdutil.openrevlog(repo, 'debugindex', file_, opts)
     format = opts.get('format', 0)
     if format not in (0, 1):
         raise util.Abort(_("unknown format %d") % format)
 
-    if not r:
-        r = revlog.revlog(util.opener(os.getcwd(), audit=False), file_)
+    generaldelta = r.version & revlog.REVLOGGENERALDELTA
+    if generaldelta:
+        basehdr = ' delta'
+    else:
+        basehdr = '  base'
 
     if format == 0:
-        ui.write("   rev    offset  length   base linkrev"
+        ui.write("   rev    offset  length " + basehdr + " linkrev"
                  " nodeid       p1           p2\n")
     elif format == 1:
         ui.write("   rev flag   offset   length"
-                 "     size   base   link     p1     p2       nodeid\n")
+                 "     size " + basehdr + "   link     p1     p2       nodeid\n")
 
     for i in r:
         node = r.node(i)
+        if generaldelta:
+            base = r.deltaparent(i)
+        else:
+            base = r.chainbase(i)
         if format == 0:
             try:
                 pp = r.parents(node)
             except:
                 pp = [nullid, nullid]
             ui.write("% 6d % 9d % 7d % 6d % 7d %s %s %s\n" % (
-                    i, r.start(i), r.length(i), r.base(i), r.linkrev(i),
+                    i, r.start(i), r.length(i), base, r.linkrev(i),
                     short(node), short(pp[0]), short(pp[1])))
         elif format == 1:
             pr = r.parentrevs(i)
             ui.write("% 6d %04x % 8d % 8d % 8d % 6d % 6d % 6d % 6d %s\n" % (
                     i, r.flags(i), r.start(i), r.length(i), r.rawsize(i),
-                    r.base(i), r.linkrev(i), pr[0], pr[1], short(node)))
-
+                    base, r.linkrev(i), pr[0], pr[1], short(node)))
+
+@command('debugindexdot', [], _('FILE'))
 def debugindexdot(ui, repo, file_):
     """dump an index DAG as a graphviz dot file"""
     r = None
@@ -1402,7 +1715,7 @@
         if len(filelog):
             r = filelog
     if not r:
-        r = revlog.revlog(util.opener(os.getcwd(), audit=False), file_)
+        r = revlog.revlog(scmutil.opener(os.getcwd(), audit=False), file_)
     ui.write("digraph G {\n")
     for i in r:
         node = r.node(i)
@@ -1412,6 +1725,7 @@
             ui.write("\t%d -> %d\n" % (r.rev(pp[1]), i))
     ui.write("}\n")
 
+@command('debuginstall', [], '')
 def debuginstall(ui):
     '''test Mercurial installation
 
@@ -1457,49 +1771,10 @@
         ui.write(_(" (templates seem to have been installed incorrectly)\n"))
         problems += 1
 
-    # patch
-    ui.status(_("Checking patch...\n"))
-    patchproblems = 0
-    a = "1\n2\n3\n4\n"
-    b = "1\n2\n3\ninsert\n4\n"
-    fa = writetemp(a)
-    d = mdiff.unidiff(a, None, b, None, os.path.basename(fa),
-        os.path.basename(fa))
-    fd = writetemp(d)
-
-    files = {}
-    try:
-        patch.patch(fd, ui, cwd=os.path.dirname(fa), files=files)
-    except util.Abort, e:
-        ui.write(_(" patch call failed:\n"))
-        ui.write(" " + str(e) + "\n")
-        patchproblems += 1
-    else:
-        if list(files) != [os.path.basename(fa)]:
-            ui.write(_(" unexpected patch output!\n"))
-            patchproblems += 1
-        a = open(fa).read()
-        if a != b:
-            ui.write(_(" patch test failed!\n"))
-            patchproblems += 1
-
-    if patchproblems:
-        if ui.config('ui', 'patch'):
-            ui.write(_(" (Current patch tool may be incompatible with patch,"
-                       " or misconfigured. Please check your configuration"
-                       " file)\n"))
-        else:
-            ui.write(_(" Internal patcher failure, please report this error"
-                       " to http://mercurial.selenic.com/wiki/BugTracker\n"))
-    problems += patchproblems
-
-    os.unlink(fa)
-    os.unlink(fd)
-
     # editor
     ui.status(_("Checking commit editor...\n"))
     editor = ui.geteditor()
-    cmdpath = util.find_exe(editor) or util.find_exe(editor.split()[0])
+    cmdpath = util.findexe(editor) or util.findexe(editor.split()[0])
     if not cmdpath:
         if editor == 'vi':
             ui.write(_(" No commit editor set and can't find vi in PATH\n"))
@@ -1528,11 +1803,60 @@
 
     return problems
 
+@command('debugknown', [], _('REPO ID...'))
+def debugknown(ui, repopath, *ids, **opts):
+    """test whether node ids are known to a repo
+
+    Every ID must be a full-length hex node id string. Returns a list of 0s and 1s
+    indicating unknown/known.
+    """
+    repo = hg.peer(ui, opts, repopath)
+    if not repo.capable('known'):
+        raise util.Abort("known() not supported by target repository")
+    flags = repo.known([bin(s) for s in ids])
+    ui.write("%s\n" % ("".join([f and "1" or "0" for f in flags])))
+
+@command('debugpushkey', [], _('REPO NAMESPACE [KEY OLD NEW]'))
+def debugpushkey(ui, repopath, namespace, *keyinfo, **opts):
+    '''access the pushkey key/value protocol
+
+    With two args, list the keys in the given namespace.
+
+    With five args, set a key to new if it currently is set to old.
+    Reports success or failure.
+    '''
+
+    target = hg.peer(ui, {}, repopath)
+    if keyinfo:
+        key, old, new = keyinfo
+        r = target.pushkey(namespace, key, old, new)
+        ui.status(str(r) + '\n')
+        return not r
+    else:
+        for k, v in target.listkeys(namespace).iteritems():
+            ui.write("%s\t%s\n" % (k.encode('string-escape'),
+                                   v.encode('string-escape')))
+
+@command('debugrebuildstate',
+    [('r', 'rev', '', _('revision to rebuild to'), _('REV'))],
+    _('[-r REV] [REV]'))
+def debugrebuildstate(ui, repo, rev="tip"):
+    """rebuild the dirstate as it would look like for the given revision"""
+    ctx = scmutil.revsingle(repo, rev)
+    wlock = repo.wlock()
+    try:
+        repo.dirstate.rebuild(ctx.node(), ctx.manifest())
+    finally:
+        wlock.release()
+
+@command('debugrename',
+    [('r', 'rev', '', _('revision to debug'), _('REV'))],
+    _('[-r REV] FILE'))
 def debugrename(ui, repo, file1, *pats, **opts):
     """dump rename information"""
 
-    ctx = cmdutil.revsingle(repo, opts.get('rev'))
-    m = cmdutil.match(repo, (file1,) + pats, opts)
+    ctx = scmutil.revsingle(repo, opts.get('rev'))
+    m = scmutil.match(ctx, (file1,) + pats, opts)
     for abs in ctx.walk(m):
         fctx = ctx[abs]
         o = fctx.filelog().renamed(fctx.filenode())
@@ -1542,9 +1866,246 @@
         else:
             ui.write(_("%s not renamed\n") % rel)
 
+@command('debugrevlog',
+    [('c', 'changelog', False, _('open changelog')),
+     ('m', 'manifest', False, _('open manifest')),
+     ('d', 'dump', False, _('dump index data'))],
+     _('-c|-m|FILE'))
+def debugrevlog(ui, repo, file_ = None, **opts):
+    """show data and statistics about a revlog"""
+    r = cmdutil.openrevlog(repo, 'debugrevlog', file_, opts)
+
+    if opts.get("dump"):
+        numrevs = len(r)
+        ui.write("# rev p1rev p2rev start end deltastart base p1 p2"
+                 " rawsize totalsize compression heads\n")
+        ts = 0
+        heads = set()
+        for rev in xrange(numrevs):
+            dbase = r.deltaparent(rev)
+            if dbase == -1:
+                dbase = rev
+            cbase = r.chainbase(rev)
+            p1, p2 = r.parentrevs(rev)
+            rs = r.rawsize(rev)
+            ts = ts + rs
+            heads -= set(r.parentrevs(rev))
+            heads.add(rev)
+            ui.write("%d %d %d %d %d %d %d %d %d %d %d %d %d\n" %
+                     (rev, p1, p2, r.start(rev), r.end(rev),
+                      r.start(dbase), r.start(cbase),
+                      r.start(p1), r.start(p2),
+                      rs, ts, ts / r.end(rev), len(heads)))
+        return 0
+
+    v = r.version
+    format = v & 0xFFFF
+    flags = []
+    gdelta = False
+    if v & revlog.REVLOGNGINLINEDATA:
+        flags.append('inline')
+    if v & revlog.REVLOGGENERALDELTA:
+        gdelta = True
+        flags.append('generaldelta')
+    if not flags:
+        flags = ['(none)']
+
+    nummerges = 0
+    numfull = 0
+    numprev = 0
+    nump1 = 0
+    nump2 = 0
+    numother = 0
+    nump1prev = 0
+    nump2prev = 0
+    chainlengths = []
+
+    datasize = [None, 0, 0L]
+    fullsize = [None, 0, 0L]
+    deltasize = [None, 0, 0L]
+
+    def addsize(size, l):
+        if l[0] is None or size < l[0]:
+            l[0] = size
+        if size > l[1]:
+            l[1] = size
+        l[2] += size
+
+    numrevs = len(r)
+    for rev in xrange(numrevs):
+        p1, p2 = r.parentrevs(rev)
+        delta = r.deltaparent(rev)
+        if format > 0:
+            addsize(r.rawsize(rev), datasize)
+        if p2 != nullrev:
+            nummerges += 1
+        size = r.length(rev)
+        if delta == nullrev:
+            chainlengths.append(0)
+            numfull += 1
+            addsize(size, fullsize)
+        else:
+            chainlengths.append(chainlengths[delta] + 1)
+            addsize(size, deltasize)
+            if delta == rev - 1:
+                numprev += 1
+                if delta == p1:
+                    nump1prev += 1
+                elif delta == p2:
+                    nump2prev += 1
+            elif delta == p1:
+                nump1 += 1
+            elif delta == p2:
+                nump2 += 1
+            elif delta != nullrev:
+                numother += 1
+
+    numdeltas = numrevs - numfull
+    numoprev = numprev - nump1prev - nump2prev
+    totalrawsize = datasize[2]
+    datasize[2] /= numrevs
+    fulltotal = fullsize[2]
+    fullsize[2] /= numfull
+    deltatotal = deltasize[2]
+    deltasize[2] /= numrevs - numfull
+    totalsize = fulltotal + deltatotal
+    avgchainlen = sum(chainlengths) / numrevs
+    compratio = totalrawsize / totalsize
+
+    basedfmtstr = '%%%dd\n'
+    basepcfmtstr = '%%%dd %s(%%5.2f%%%%)\n'
+
+    def dfmtstr(max):
+        return basedfmtstr % len(str(max))
+    def pcfmtstr(max, padding=0):
+        return basepcfmtstr % (len(str(max)), ' ' * padding)
+
+    def pcfmt(value, total):
+        return (value, 100 * float(value) / total)
+
+    ui.write('format : %d\n' % format)
+    ui.write('flags  : %s\n' % ', '.join(flags))
+
+    ui.write('\n')
+    fmt = pcfmtstr(totalsize)
+    fmt2 = dfmtstr(totalsize)
+    ui.write('revisions     : ' + fmt2 % numrevs)
+    ui.write('    merges    : ' + fmt % pcfmt(nummerges, numrevs))
+    ui.write('    normal    : ' + fmt % pcfmt(numrevs - nummerges, numrevs))
+    ui.write('revisions     : ' + fmt2 % numrevs)
+    ui.write('    full      : ' + fmt % pcfmt(numfull, numrevs))
+    ui.write('    deltas    : ' + fmt % pcfmt(numdeltas, numrevs))
+    ui.write('revision size : ' + fmt2 % totalsize)
+    ui.write('    full      : ' + fmt % pcfmt(fulltotal, totalsize))
+    ui.write('    deltas    : ' + fmt % pcfmt(deltatotal, totalsize))
+
+    ui.write('\n')
+    fmt = dfmtstr(max(avgchainlen, compratio))
+    ui.write('avg chain length  : ' + fmt % avgchainlen)
+    ui.write('compression ratio : ' + fmt % compratio)
+
+    if format > 0:
+        ui.write('\n')
+        ui.write('uncompressed data size (min/max/avg) : %d / %d / %d\n'
+                 % tuple(datasize))
+    ui.write('full revision size (min/max/avg)     : %d / %d / %d\n'
+             % tuple(fullsize))
+    ui.write('delta size (min/max/avg)             : %d / %d / %d\n'
+             % tuple(deltasize))
+
+    if numdeltas > 0:
+        ui.write('\n')
+        fmt = pcfmtstr(numdeltas)
+        fmt2 = pcfmtstr(numdeltas, 4)
+        ui.write('deltas against prev  : ' + fmt % pcfmt(numprev, numdeltas))
+        if numprev > 0:
+            ui.write('    where prev = p1  : ' + fmt2 % pcfmt(nump1prev, numprev))
+            ui.write('    where prev = p2  : ' + fmt2 % pcfmt(nump2prev, numprev))
+            ui.write('    other            : ' + fmt2 % pcfmt(numoprev, numprev))
+        if gdelta:
+            ui.write('deltas against p1    : ' + fmt % pcfmt(nump1, numdeltas))
+            ui.write('deltas against p2    : ' + fmt % pcfmt(nump2, numdeltas))
+            ui.write('deltas against other : ' + fmt % pcfmt(numother, numdeltas))
+
+@command('debugrevspec', [], ('REVSPEC'))
+def debugrevspec(ui, repo, expr):
+    '''parse and apply a revision specification'''
+    if ui.verbose:
+        tree = revset.parse(expr)[0]
+        ui.note(tree, "\n")
+        newtree = revset.findaliases(ui, tree)
+        if newtree != tree:
+            ui.note(newtree, "\n")
+    func = revset.match(ui, expr)
+    for c in func(repo, range(len(repo))):
+        ui.write("%s\n" % c)
+
+@command('debugsetparents', [], _('REV1 [REV2]'))
+def debugsetparents(ui, repo, rev1, rev2=None):
+    """manually set the parents of the current working directory
+
+    This is useful for writing repository conversion tools, but should
+    be used with care.
+
+    Returns 0 on success.
+    """
+
+    r1 = scmutil.revsingle(repo, rev1).node()
+    r2 = scmutil.revsingle(repo, rev2, 'null').node()
+
+    wlock = repo.wlock()
+    try:
+        repo.dirstate.setparents(r1, r2)
+    finally:
+        wlock.release()
+
+@command('debugstate',
+    [('', 'nodates', None, _('do not display the saved mtime')),
+    ('', 'datesort', None, _('sort by saved mtime'))],
+    _('[OPTION]...'))
+def debugstate(ui, repo, nodates=None, datesort=None):
+    """show the contents of the current dirstate"""
+    timestr = ""
+    showdate = not nodates
+    if datesort:
+        keyfunc = lambda x: (x[1][3], x[0]) # sort by mtime, then by filename
+    else:
+        keyfunc = None # sort by filename
+    for file_, ent in sorted(repo.dirstate._map.iteritems(), key=keyfunc):
+        if showdate:
+            if ent[3] == -1:
+                # Pad or slice to locale representation
+                locale_len = len(time.strftime("%Y-%m-%d %H:%M:%S ",
+                                               time.localtime(0)))
+                timestr = 'unset'
+                timestr = (timestr[:locale_len] +
+                           ' ' * (locale_len - len(timestr)))
+            else:
+                timestr = time.strftime("%Y-%m-%d %H:%M:%S ",
+                                        time.localtime(ent[3]))
+        if ent[1] & 020000:
+            mode = 'lnk'
+        else:
+            mode = '%3o' % (ent[1] & 0777)
+        ui.write("%c %s %10d %s%s\n" % (ent[0], mode, ent[2], timestr, file_))
+    for f in repo.dirstate.copies():
+        ui.write(_("copy: %s -> %s\n") % (repo.dirstate.copied(f), f))
+
+@command('debugsub',
+    [('r', 'rev', '',
+     _('revision to check'), _('REV'))],
+    _('[-r REV] [REV]'))
+def debugsub(ui, repo, rev=None):
+    ctx = scmutil.revsingle(repo, rev, None)
+    for k, v in sorted(ctx.substate.items()):
+        ui.write('path %s\n' % k)
+        ui.write(' source   %s\n' % v[0])
+        ui.write(' revision %s\n' % v[1])
+
+@command('debugwalk', walkopts, _('[OPTION]... [FILE]...'))
 def debugwalk(ui, repo, *pats, **opts):
     """show how files match on given patterns"""
-    m = cmdutil.match(repo, pats, opts)
+    m = scmutil.match(repo[None], pats, opts)
     items = list(repo.walk(m))
     if not items:
         return
@@ -1555,6 +2116,32 @@
         line = fmt % (abs, m.rel(abs), m.exact(abs) and 'exact' or '')
         ui.write("%s\n" % line.rstrip())
 
+@command('debugwireargs',
+    [('', 'three', '', 'three'),
+    ('', 'four', '', 'four'),
+    ('', 'five', '', 'five'),
+    ] + remoteopts,
+    _('REPO [OPTIONS]... [ONE [TWO]]'))
+def debugwireargs(ui, repopath, *vals, **opts):
+    repo = hg.peer(ui, opts, repopath)
+    for opt in remoteopts:
+        del opts[opt[1]]
+    args = {}
+    for k, v in opts.iteritems():
+        if v:
+            args[k] = v
+    # run twice to check that we don't mess up the stream for the next command
+    res1 = repo.debugwireargs(*vals, **args)
+    res2 = repo.debugwireargs(*vals, **args)
+    ui.write("%s\n" % res1)
+    if res1 != res2:
+        ui.warn("%s\n" % res2)
+
+@command('^diff',
+    [('r', 'rev', [], _('revision'), _('REV')),
+    ('c', 'change', '', _('change made by revision'), _('REV'))
+    ] + diffopts + diffopts2 + walkopts + subrepoopts,
+    _('[OPTION]... ([-c REV] | [-r REV1 [-r REV2]]) [FILE]...'))
 def diff(ui, repo, *pats, **opts):
     """diff repository (or selected files)
 
@@ -1595,19 +2182,26 @@
         msg = _('cannot specify --rev and --change at the same time')
         raise util.Abort(msg)
     elif change:
-        node2 = repo.lookup(change)
-        node1 = repo[node2].parents()[0].node()
+        node2 = scmutil.revsingle(repo, change, None).node()
+        node1 = repo[node2].p1().node()
     else:
-        node1, node2 = cmdutil.revpair(repo, revs)
+        node1, node2 = scmutil.revpair(repo, revs)
 
     if reverse:
         node1, node2 = node2, node1
 
     diffopts = patch.diffopts(ui, opts)
-    m = cmdutil.match(repo, pats, opts)
+    m = scmutil.match(repo[node2], pats, opts)
     cmdutil.diffordiffstat(ui, repo, diffopts, node1, node2, m, stat=stat,
                            listsubrepos=opts.get('subrepos'))
 
+@command('^export',
+    [('o', 'output', '',
+     _('print output to file with formatted name'), _('FORMAT')),
+    ('', 'switch-parent', None, _('diff against the second parent')),
+    ('r', 'rev', [], _('revisions to export'), _('REV')),
+    ] + diffopts,
+    _('[OPTION]... [-o OUTFILESPEC] REV...'))
 def export(ui, repo, *changesets, **opts):
     """dump the header and diffs for one or more changesets
 
@@ -1649,7 +2243,7 @@
     changesets += tuple(opts.get('rev', []))
     if not changesets:
         raise util.Abort(_("export requires at least one changeset"))
-    revs = cmdutil.revrange(repo, changesets)
+    revs = scmutil.revrange(repo, changesets)
     if len(revs) > 1:
         ui.note(_('exporting patches:\n'))
     else:
@@ -1658,6 +2252,7 @@
                  switch_parent=opts.get('switch_parent'),
                  opts=patch.diffopts(ui, opts))
 
+@command('^forget', walkopts, _('[OPTION]... FILE...'))
 def forget(ui, repo, *pats, **opts):
     """forget the specified files on the next commit
 
@@ -1676,24 +2271,42 @@
     if not pats:
         raise util.Abort(_('no files specified'))
 
-    m = cmdutil.match(repo, pats, opts)
+    m = scmutil.match(repo[None], pats, opts)
     s = repo.status(match=m, clean=True)
     forget = sorted(s[0] + s[1] + s[3] + s[6])
     errs = 0
 
     for f in m.files():
         if f not in repo.dirstate and not os.path.isdir(m.rel(f)):
-            ui.warn(_('not removing %s: file is already untracked\n')
-                    % m.rel(f))
+            if os.path.exists(m.rel(f)):
+                ui.warn(_('not removing %s: file is already untracked\n')
+                        % m.rel(f))
             errs = 1
 
     for f in forget:
         if ui.verbose or not m.exact(f):
             ui.status(_('removing %s\n') % m.rel(f))
 
-    repo[None].remove(forget, unlink=False)
+    repo[None].forget(forget)
     return errs
 
+@command('grep',
+    [('0', 'print0', None, _('end fields with NUL')),
+    ('', 'all', None, _('print all revisions that match')),
+    ('a', 'text', None, _('treat all files as text')),
+    ('f', 'follow', None,
+     _('follow changeset history,'
+       ' or file history across copies and renames')),
+    ('i', 'ignore-case', None, _('ignore case when matching')),
+    ('l', 'files-with-matches', None,
+     _('print only filenames and revisions that match')),
+    ('n', 'line-number', None, _('print matching line numbers')),
+    ('r', 'rev', [],
+     _('only search files changed within revision range'), _('REV')),
+    ('u', 'user', None, _('list the author (long with -v)')),
+    ('d', 'date', None, _('list the date (short with -q)')),
+    ] + walkopts,
+    _('[OPTION]... PATTERN [FILE]...'))
 def grep(ui, repo, pattern, *pats, **opts):
     """search for a pattern in specified files and revisions
 
@@ -1782,6 +2395,10 @@
         datefunc = ui.quiet and util.shortdate or util.datestr
         found = False
         filerevmatches = {}
+        def binary():
+            flog = getfile(fn)
+            return util.binary(flog.read(ctx.filenode(fn)))
+
         if opts.get('all'):
             iter = difflinestates(pstates, states)
         else:
@@ -1808,22 +2425,25 @@
                 after = l.line[l.colend:]
             ui.write(sep.join(cols))
             if before is not None:
-                ui.write(sep + before)
-                ui.write(match, label='grep.match')
-                ui.write(after)
+                if not opts.get('text') and binary():
+                    ui.write(sep + " Binary file matches")
+                else:
+                    ui.write(sep + before)
+                    ui.write(match, label='grep.match')
+                    ui.write(after)
             ui.write(eol)
             found = True
         return found
 
     skip = {}
     revfiles = {}
-    matchfn = cmdutil.match(repo, pats, opts)
+    matchfn = scmutil.match(repo[None], pats, opts)
     found = False
     follow = opts.get('follow')
 
     def prep(ctx, fns):
         rev = ctx.rev()
-        pctx = ctx.parents()[0]
+        pctx = ctx.p1()
         parent = pctx.rev()
         matches.setdefault(rev, {})
         matches.setdefault(parent, {})
@@ -1858,7 +2478,7 @@
 
     for ctx in cmdutil.walkchangerevs(repo, matchfn, opts, prep):
         rev = ctx.rev()
-        parent = ctx.parents()[0].rev()
+        parent = ctx.p1().rev()
         for fn in sorted(revfiles.get(rev, [])):
             states = matches[rev][fn]
             copy = copies.get(rev, {}).get(fn)
@@ -1879,6 +2499,14 @@
 
     return not found
 
+@command('heads',
+    [('r', 'rev', '',
+     _('show only heads which are descendants of STARTREV'), _('STARTREV')),
+    ('t', 'topo', False, _('show topological heads only')),
+    ('a', 'active', False, _('show active branchheads only (DEPRECATED)')),
+    ('c', 'closed', False, _('show normal and closed branch heads')),
+    ] + templateopts,
+    _('[-ac] [-r STARTREV] [REV]...'))
 def heads(ui, repo, *branchrevs, **opts):
     """show current repository heads or show branch heads
 
@@ -1906,29 +2534,20 @@
 
     start = None
     if 'rev' in opts:
-        start = cmdutil.revsingle(repo, opts['rev'], None).node()
+        start = scmutil.revsingle(repo, opts['rev'], None).node()
 
     if opts.get('topo'):
         heads = [repo[h] for h in repo.heads(start)]
     else:
         heads = []
-        for b, ls in repo.branchmap().iteritems():
-            if start is None:
-                heads += [repo[h] for h in ls]
-                continue
-            startrev = repo.changelog.rev(start)
-            descendants = set(repo.changelog.descendants(startrev))
-            descendants.add(startrev)
-            rev = repo.changelog.rev
-            heads += [repo[h] for h in ls if rev(h) in descendants]
+        for branch in repo.branchmap():
+            heads += repo.branchheads(branch, start, opts.get('closed'))
+        heads = [repo[h] for h in heads]
 
     if branchrevs:
         branches = set(repo[br].branch() for br in branchrevs)
         heads = [h for h in heads if h.branch() in branches]
 
-    if not opts.get('closed'):
-        heads = [h for h in heads if not h.extra().get('close')]
-
     if opts.get('active') and branchrevs:
         dagheads = repo.heads(start)
         heads = [h for h in heads if h.node() in dagheads]
@@ -1951,7 +2570,11 @@
         displayer.show(ctx)
     displayer.close()
 
-def help_(ui, name=None, with_version=False, unknowncmd=False):
+@command('help',
+    [('e', 'extension', None, _('show only help for extensions')),
+     ('c', 'command', None, _('show only help for commands'))],
+    _('[-ec] [TOPIC]'))
+def help_(ui, name=None, with_version=False, unknowncmd=False, full=True, **opts):
     """show help for a given topic or a help overview
 
     With no arguments, print a list of commands with short help messages.
@@ -1962,7 +2585,7 @@
     Returns 0 if successful.
     """
     option_lists = []
-    textwidth = ui.termwidth() - 2
+    textwidth = min(ui.termwidth(), 80) - 2
 
     def addglobalopts(aliases):
         if ui.verbose:
@@ -1974,6 +2597,8 @@
             if name == 'shortlist':
                 msg = _('use "hg help" for the full list of commands '
                         'or "hg -v" for details')
+            elif name and not full:
+                msg = _('use "hg help %s" to show the full help text' % name)
             elif aliases:
                 msg = _('use "hg -v help%s" to show builtin aliases and '
                         'global options') % (name and " " + name or "")
@@ -2012,7 +2637,7 @@
             ui.write('hg %s\n' % aliases[0])
 
         # aliases
-        if not ui.quiet and len(aliases) > 1:
+        if full and not ui.quiet and len(aliases) > 1:
             ui.write(_("\naliases: %s\n") % ', '.join(aliases[1:]))
 
         # description
@@ -2024,7 +2649,7 @@
                 doc = _('shell alias for::\n\n    %s') % entry[0].definition[1:]
             else:
                 doc = _('alias for: hg %s\n\n%s') % (entry[0].definition, doc)
-        if ui.quiet:
+        if ui.quiet or not full:
             doc = doc.splitlines()[0]
         keep = ui.verbose and ['verbose'] or []
         formatted, pruned = minirst.format(doc, textwidth, keep=keep)
@@ -2039,6 +2664,18 @@
 
             addglobalopts(False)
 
+        # check if this command shadows a non-trivial (multi-line)
+        # extension help text
+        try:
+            mod = extensions.find(name)
+            doc = gettext(mod.__doc__) or ''
+            if '\n' in doc.strip():
+                msg = _('use "hg help -e %s" to show help for '
+                        'the %s extension') % (name, name)
+                ui.write('\n%s\n' % msg)
+        except KeyError:
+            pass
+
     def helplist(header, select=None):
         h = {}
         cmds = {}
@@ -2097,6 +2734,12 @@
 
         ui.write("%s\n\n" % header)
         ui.write("%s\n" % minirst.format(doc, textwidth, indent=4))
+        try:
+            cmdutil.findcmd(name, table)
+            ui.write(_('\nuse "hg help -c %s" to see help for '
+                       'the %s command\n') % (name, name))
+        except error.UnknownCommand:
+            pass
 
     def helpext(name):
         try:
@@ -2133,19 +2776,20 @@
         doc = gettext(mod.__doc__).splitlines()[0]
 
         msg = help.listexts(_("'%s' is provided by the following "
-                              "extension:") % cmd, {ext: doc}, len(ext),
-                            indent=4)
+                              "extension:") % cmd, {ext: doc}, indent=4)
         ui.write(minirst.format(msg, textwidth))
         ui.write('\n\n')
         ui.write(_('use "hg help extensions" for information on enabling '
                    'extensions\n'))
 
-    help.addtopichook('revsets', revset.makedoc)
-
     if name and name != 'shortlist':
         i = None
         if unknowncmd:
             queries = (helpextcmd,)
+        elif opts.get('extension'):
+            queries = (helpext,)
+        elif opts.get('command'):
+            queries = (helpcmd,)
         else:
             queries = (helptopic, helpcmd, helpext, helpextcmd)
         for f in queries:
@@ -2174,8 +2818,7 @@
 
         helplist(header)
         if name != 'shortlist':
-            exts, maxlength = extensions.enabled()
-            text = help.listexts(_('enabled extensions:'), exts, maxlength)
+            text = help.listexts(_('enabled extensions:'), extensions.enabled())
             if text:
                 ui.write("\n%s\n" % minirst.format(text, textwidth))
 
@@ -2240,6 +2883,15 @@
             else:
                 ui.write("%s\n" % opt)
 
+@command('identify|id',
+    [('r', 'rev', '',
+     _('identify the specified revision'), _('REV')),
+    ('n', 'num', None, _('show local revision number')),
+    ('i', 'id', None, _('show global revision id')),
+    ('b', 'branch', None, _('show branch')),
+    ('t', 'tags', None, _('show tags')),
+    ('B', 'bookmarks', None, _('show bookmarks'))],
+    _('[-nibtB] [-r REV] [SOURCE]'))
 def identify(ui, repo, source=None, rev=None,
              num=None, id=None, branch=None, tags=None, bookmarks=None):
     """identify the working copy or specified revision
@@ -2265,67 +2917,105 @@
     hexfunc = ui.debugflag and hex or short
     default = not (num or id or branch or tags or bookmarks)
     output = []
-
     revs = []
+
     if source:
         source, branches = hg.parseurl(ui.expandpath(source))
-        repo = hg.repository(ui, source)
+        repo = hg.peer(ui, {}, source)
         revs, checkout = hg.addbranchrevs(repo, repo, branches, None)
 
     if not repo.local():
+        if num or branch or tags:
+            raise util.Abort(
+                _("can't query remote revision number, branch, or tags"))
         if not rev and revs:
             rev = revs[0]
         if not rev:
             rev = "tip"
-        if num or branch or tags or bookmarks:
-            raise util.Abort(_("can't query remote revision number,"
-                             " branch, tags, or bookmarks"))
-        output = [hexfunc(repo.lookup(rev))]
-    elif not rev:
-        ctx = repo[None]
-        parents = ctx.parents()
-        changed = False
-        if default or id or num:
-            changed = util.any(repo.status())
-        if default or id:
-            output = ["%s%s" % ('+'.join([hexfunc(p.node()) for p in parents]),
-                                (changed) and "+" or "")]
-        if num:
-            output.append("%s%s" % ('+'.join([str(p.rev()) for p in parents]),
-                                    (changed) and "+" or ""))
-    else:
-        ctx = cmdutil.revsingle(repo, rev)
+
+        remoterev = repo.lookup(rev)
         if default or id:
-            output = [hexfunc(ctx.node())]
-        if num:
-            output.append(str(ctx.rev()))
-
-    if repo.local() and default and not ui.quiet:
-        b = ctx.branch()
-        if b != 'default':
-            output.append("(%s)" % b)
-
-        # multiple tags for a single parent separated by '/'
-        t = "/".join(ctx.tags())
-        if t:
-            output.append(t)
-
-        # multiple bookmarks for a single parent separated by '/'
-        bm = '/'.join(ctx.bookmarks())
-        if bm:
-            output.append(bm)
-
-    if branch:
-        output.append(ctx.branch())
-
-    if tags:
-        output.extend(ctx.tags())
-
-    if bookmarks:
-        output.extend(ctx.bookmarks())
+            output = [hexfunc(remoterev)]
+
+        def getbms():
+            bms = []
+
+            if 'bookmarks' in repo.listkeys('namespaces'):
+                hexremoterev = hex(remoterev)
+                bms = [bm for bm, bmr in repo.listkeys('bookmarks').iteritems()
+                       if bmr == hexremoterev]
+
+            return bms
+
+        if bookmarks:
+            output.extend(getbms())
+        elif default and not ui.quiet:
+            # multiple bookmarks for a single parent separated by '/'
+            bm = '/'.join(getbms())
+            if bm:
+                output.append(bm)
+    else:
+        if not rev:
+            ctx = repo[None]
+            parents = ctx.parents()
+            changed = ""
+            if default or id or num:
+                changed = util.any(repo.status()) and "+" or ""
+            if default or id:
+                output = ["%s%s" %
+                  ('+'.join([hexfunc(p.node()) for p in parents]), changed)]
+            if num:
+                output.append("%s%s" %
+                  ('+'.join([str(p.rev()) for p in parents]), changed))
+        else:
+            ctx = scmutil.revsingle(repo, rev)
+            if default or id:
+                output = [hexfunc(ctx.node())]
+            if num:
+                output.append(str(ctx.rev()))
+
+        if default and not ui.quiet:
+            b = ctx.branch()
+            if b != 'default':
+                output.append("(%s)" % b)
+
+            # multiple tags for a single parent separated by '/'
+            t = '/'.join(ctx.tags())
+            if t:
+                output.append(t)
+
+            # multiple bookmarks for a single parent separated by '/'
+            bm = '/'.join(ctx.bookmarks())
+            if bm:
+                output.append(bm)
+        else:
+            if branch:
+                output.append(ctx.branch())
+
+            if tags:
+                output.extend(ctx.tags())
+
+            if bookmarks:
+                output.extend(ctx.bookmarks())
 
     ui.write("%s\n" % ' '.join(output))
 
+@command('import|patch',
+    [('p', 'strip', 1,
+     _('directory strip option for patch. This has the same '
+       'meaning as the corresponding patch option'), _('NUM')),
+    ('b', 'base', '', _('base path (DEPRECATED)'), _('PATH')),
+    ('f', 'force', None, _('skip check for outstanding uncommitted changes')),
+    ('', 'no-commit', None,
+     _("don't commit, just update the working directory")),
+    ('', 'bypass', None,
+     _("apply patch without touching the working directory")),
+    ('', 'exact', None,
+     _('apply patch to the nodes from which it was generated')),
+    ('', 'import-branch', None,
+     _('use any branch information in patch (implied by --exact)'))] +
+    commitopts + commitopts2 + similarityopts,
+    _('[OPTION]... PATCH...'))
 def import_(ui, repo, patch1, *patches, **opts):
     """import an ordered set of patches
 
@@ -2353,6 +3043,11 @@
     the patch. This may happen due to character set problems or other
     deficiencies in the text patch format.
 
+    Use --bypass to apply and commit patches directly to the
+    repository, not touching the working directory. Without --exact,
+    patches will be applied on top of the working directory parent
+    revision.
+
     With -s/--similarity, hg will attempt to discover renames and
     copies in the patch in the same way as 'addremove'.
 
@@ -2368,22 +3063,32 @@
     if date:
         opts['date'] = util.parsedate(date)
 
+    update = not opts.get('bypass')
+    if not update and opts.get('no_commit'):
+        raise util.Abort(_('cannot use --no-commit with --bypass'))
     try:
         sim = float(opts.get('similarity') or 0)
     except ValueError:
         raise util.Abort(_('similarity must be a number'))
     if sim < 0 or sim > 100:
         raise util.Abort(_('similarity must be between 0 and 100'))
-
-    if opts.get('exact') or not opts.get('force'):
-        cmdutil.bail_if_changed(repo)
+    if sim and not update:
+        raise util.Abort(_('cannot use --similarity with --bypass'))
+
+    if (opts.get('exact') or not opts.get('force')) and update:
+        cmdutil.bailifchanged(repo)
 
     d = opts["base"]
     strip = opts["strip"]
     wlock = lock = None
     msgs = []
 
-    def tryone(ui, hunk):
+    def checkexact(repo, n, nodeid):
+        if opts.get('exact') and hex(n) != nodeid:
+            repo.rollback()
+            raise util.Abort(_('patch is damaged or loses information'))
+
+    def tryone(ui, hunk, parents):
         tmpname, message, user, date, branch, nodeid, p1, p2 = \
             patch.extract(ui, hunk)
 
@@ -2392,7 +3097,7 @@
         commitid = _('to working directory')
 
         try:
-            cmdline_message = cmdutil.logmessage(opts)
+            cmdline_message = cmdutil.logmessage(ui, opts)
             if cmdline_message:
                 # pickup the cmdline msg
                 message = cmdline_message
@@ -2404,56 +3109,77 @@
                 message = None
             ui.debug('message:\n%s\n' % message)
 
-            wp = repo.parents()
+            if len(parents) == 1:
+                parents.append(repo[nullid])
             if opts.get('exact'):
                 if not nodeid or not p1:
                     raise util.Abort(_('not a Mercurial patch'))
-                p1 = repo.lookup(p1)
-                p2 = repo.lookup(p2 or hex(nullid))
-
-                if p1 != wp[0].node():
-                    hg.clean(repo, p1)
-                repo.dirstate.setparents(p1, p2)
+                p1 = repo[p1]
+                p2 = repo[p2 or nullid]
             elif p2:
                 try:
-                    p1 = repo.lookup(p1)
-                    p2 = repo.lookup(p2)
-                    if p1 == wp[0].node():
-                        repo.dirstate.setparents(p1, p2)
+                    p1 = repo[p1]
+                    p2 = repo[p2]
                 except error.RepoError:
-                    pass
-            if opts.get('exact') or opts.get('import_branch'):
-                repo.dirstate.setbranch(branch or 'default')
-
-            files = {}
-            try:
-                patch.patch(tmpname, ui, strip=strip, cwd=repo.root,
-                            files=files, eolmode=None)
-            finally:
-                files = cmdutil.updatedir(ui, repo, files,
-                                          similarity=sim / 100.0)
-            if opts.get('no_commit'):
-                if message:
-                    msgs.append(message)
+                    p1, p2 = parents
             else:
-                if opts.get('exact'):
-                    m = None
+                p1, p2 = parents
+
+            n = None
+            if update:
+                if opts.get('exact') and p1 != parents[0]:
+                    hg.clean(repo, p1.node())
+                if p1 != parents[0] and p2 != parents[1]:
+                    repo.dirstate.setparents(p1.node(), p2.node())
+
+                if opts.get('exact') or opts.get('import_branch'):
+                    repo.dirstate.setbranch(branch or 'default')
+
+                files = set()
+                patch.patch(ui, repo, tmpname, strip=strip, files=files,
+                            eolmode=None, similarity=sim / 100.0)
+                files = list(files)
+                if opts.get('no_commit'):
+                    if message:
+                        msgs.append(message)
                 else:
-                    m = cmdutil.matchfiles(repo, files or [])
-                n = repo.commit(message, opts.get('user') or user,
-                                opts.get('date') or date, match=m,
-                                editor=cmdutil.commiteditor)
-                if opts.get('exact'):
-                    if hex(n) != nodeid:
-                        repo.rollback()
-                        raise util.Abort(_('patch is damaged'
-                                           ' or loses information'))
-                # Force a dirstate write so that the next transaction
-                # backups an up-do-date file.
-                repo.dirstate.write()
-                if n:
-                    commitid = short(n)
-
+                    if opts.get('exact'):
+                        m = None
+                    else:
+                        m = scmutil.matchfiles(repo, files or [])
+                    n = repo.commit(message, opts.get('user') or user,
+                                    opts.get('date') or date, match=m,
+                                    editor=cmdutil.commiteditor)
+                    checkexact(repo, n, nodeid)
+                    # Force a dirstate write so that the next transaction
+                    # backups an up-to-date file.
+                    repo.dirstate.write()
+            else:
+                if opts.get('exact') or opts.get('import_branch'):
+                    branch = branch or 'default'
+                else:
+                    branch = p1.branch()
+                store = patch.filestore()
+                try:
+                    files = set()
+                    try:
+                        patch.patchrepo(ui, repo, p1, store, tmpname, strip,
+                                        files, eolmode=None)
+                    except patch.PatchError, e:
+                        raise util.Abort(str(e))
+                    memctx = patch.makememctx(repo, (p1.node(), p2.node()),
+                                              message,
+                                              opts.get('user') or user,
+                                              opts.get('date') or date,
+                                              branch, files, store,
+                                              editor=cmdutil.commiteditor)
+                    repo.savecommitmessage(memctx.description())
+                    n = memctx.commit()
+                    checkexact(repo, n, nodeid)
+                finally:
+                    store.close()
+            if n:
+                commitid = short(n)
             return commitid
         finally:
             os.unlink(tmpname)
@@ -2461,34 +3187,51 @@
     try:
         wlock = repo.wlock()
         lock = repo.lock()
+        parents = repo.parents()
         lastcommit = None
         for p in patches:
             pf = os.path.join(d, p)
 
             if pf == '-':
                 ui.status(_("applying patch from stdin\n"))
-                pf = sys.stdin
+                pf = ui.fin
             else:
                 ui.status(_("applying %s\n") % p)
                 pf = url.open(ui, pf)
 
             haspatch = False
             for hunk in patch.split(pf):
-                commitid = tryone(ui, hunk)
+                commitid = tryone(ui, hunk, parents)
                 if commitid:
                     haspatch = True
                     if lastcommit:
                         ui.status(_('applied %s\n') % lastcommit)
                     lastcommit = commitid
+                if update or opts.get('exact'):
+                    parents = repo.parents()
+                else:
+                    parents = [repo[commitid]]
 
             if not haspatch:
                 raise util.Abort(_('no diffs found'))
 
         if msgs:
-            repo.opener('last-message.txt', 'wb').write('\n* * *\n'.join(msgs))
+            repo.savecommitmessage('\n* * *\n'.join(msgs))
     finally:
         release(lock, wlock)
 
+@command('incoming|in',
+    [('f', 'force', None,
+     _('run even if remote repository is unrelated')),
+    ('n', 'newest-first', None, _('show newest record first')),
+    ('', 'bundle', '',
+     _('file to store the bundles into'), _('FILE')),
+    ('r', 'rev', [], _('a remote changeset intended to be added'), _('REV')),
+    ('B', 'bookmarks', False, _("compare bookmarks")),
+    ('b', 'branch', [],
+     _('a specific branch you would like to pull'), _('BRANCH')),
+    ] + logopts + remoteopts + subrepoopts,
+    _('[-p] [-n] [-M] [-f] [-r REV]... [--bundle FILENAME] [SOURCE]'))
 def incoming(ui, repo, source="default", **opts):
     """show new changesets found in source
 
@@ -2509,21 +3252,21 @@
     if opts.get('bookmarks'):
         source, branches = hg.parseurl(ui.expandpath(source),
                                        opts.get('branch'))
-        other = hg.repository(hg.remoteui(repo, opts), source)
+        other = hg.peer(repo, opts, source)
         if 'bookmarks' not in other.listkeys('namespaces'):
             ui.warn(_("remote doesn't support bookmarks\n"))
             return 0
-        ui.status(_('comparing with %s\n') % url.hidepassword(source))
+        ui.status(_('comparing with %s\n') % util.hidepassword(source))
         return bookmarks.diff(ui, repo, other)
 
     repo._subtoppath = ui.expandpath(source)
     try:
-        ret = hg.incoming(ui, repo, source, opts)
-        return ret
+        return hg.incoming(ui, repo, source, opts)
     finally:
         del repo._subtoppath
 
 
+@command('^init', remoteopts, _('[-e CMD] [--remotecmd CMD] [DEST]'))
 def init(ui, dest=".", **opts):
     """create a new repository in the given directory
 
@@ -2537,8 +3280,14 @@
 
     Returns 0 on success.
     """
-    hg.repository(hg.remoteui(ui, opts), ui.expandpath(dest), create=1)
-
+    hg.peer(ui, opts, ui.expandpath(dest), create=True)
+
+@command('locate',
+    [('r', 'rev', '', _('search the repository as it is in REV'), _('REV')),
+    ('0', 'print0', None, _('end filenames with NUL, for use with xargs')),
+    ('f', 'fullpath', None, _('print complete paths from the filesystem root')),
+    ] + walkopts,
+    _('[OPTION]... [PATTERN]...'))
 def locate(ui, repo, *pats, **opts):
     """locate files matching specific patterns
 
@@ -2560,10 +3309,10 @@
     Returns 0 if a match is found, 1 otherwise.
     """
     end = opts.get('print0') and '\0' or '\n'
-    rev = cmdutil.revsingle(repo, opts.get('rev'), None).node()
+    rev = scmutil.revsingle(repo, opts.get('rev'), None).node()
 
     ret = 1
-    m = cmdutil.match(repo, pats, opts, default='relglob')
+    m = scmutil.match(repo[rev], pats, opts, default='relglob')
     m.bad = lambda x, y: False
     for abs in repo[rev].walk(m):
         if not rev and abs not in repo.dirstate:
@@ -2576,6 +3325,29 @@
 
     return ret
 
+@command('^log|history',
+    [('f', 'follow', None,
+     _('follow changeset history, or file history across copies and renames')),
+    ('', 'follow-first', None,
+     _('only follow the first parent of merge changesets')),
+    ('d', 'date', '', _('show revisions matching date spec'), _('DATE')),
+    ('C', 'copies', None, _('show copied files')),
+    ('k', 'keyword', [],
+     _('do case-insensitive search for a given text'), _('TEXT')),
+    ('r', 'rev', [], _('show the specified revision or range'), _('REV')),
+    ('', 'removed', None, _('include revisions where files were removed')),
+    ('m', 'only-merges', None, _('show only merges')),
+    ('u', 'user', [], _('revisions committed by user'), _('USER')),
+    ('', 'only-branch', [],
+     _('show only changesets within the given named branch (DEPRECATED)'),
+     _('BRANCH')),
+    ('b', 'branch', [],
+     _('show changesets within the given named branch'), _('BRANCH')),
+    ('P', 'prune', [],
+     _('do not display revision or any of its ancestors'), _('REV')),
+    ('h', 'hidden', False, _('show hidden changesets')),
+    ] + logopts + walkopts,
+    _('[OPTION]... [FILE]'))
 def log(ui, repo, *pats, **opts):
     """show revision history of entire repository or files
 
@@ -2609,13 +3381,13 @@
     Returns 0 on success.
     """
 
-    matchfn = cmdutil.match(repo, pats, opts)
+    matchfn = scmutil.match(repo[None], pats, opts)
     limit = cmdutil.loglimit(opts)
     count = 0
 
     endrev = None
     if opts.get('copies') and opts.get('rev'):
-        endrev = max(cmdutil.revrange(repo, opts.get('rev'))) + 1
+        endrev = max(scmutil.revrange(repo, opts.get('rev'))) + 1
 
     df = False
     if opts["date"]:
@@ -2635,6 +3407,8 @@
             return
         if opts.get('branch') and ctx.branch() not in opts['branch']:
             return
+        if not opts.get('hidden') and ctx.hidden():
+            return
         if df and not df(ctx.date()[0]):
             return
         if opts['user'] and not [k for k in opts['user']
@@ -2662,7 +3436,7 @@
         if opts.get('patch') or opts.get('stat'):
             if opts.get('follow') or opts.get('follow_first'):
                 # note: this might be wrong when following through merges
-                revmatchfn = cmdutil.match(repo, fns, default='path')
+                revmatchfn = scmutil.match(repo[None], fns, default='path')
             else:
                 revmatchfn = matchfn
 
@@ -2675,7 +3449,11 @@
             count += 1
     displayer.close()
 
-def manifest(ui, repo, node=None, rev=None):
+@command('manifest',
+    [('r', 'rev', '', _('revision to display'), _('REV')),
+     ('', 'all', False, _("list files from all revisions"))],
+    _('[-r REV]'))
+def manifest(ui, repo, node=None, rev=None, **opts):
     """output the current or given revision of the project manifest
 
     Print a list of version controlled files for the given revision.
@@ -2685,8 +3463,30 @@
     With -v, print file permissions, symlink and executable bits.
     With --debug, print file revision hashes.
 
+    If option --all is specified, the list of all files from all revisions
+    is printed. This includes deleted and renamed files.
+
     Returns 0 on success.
     """
+    if opts.get('all'):
+        if rev or node:
+            raise util.Abort(_("can't specify a revision with --all"))
+
+        res = []
+        prefix = "data/"
+        suffix = ".i"
+        plen = len(prefix)
+        slen = len(suffix)
+        lock = repo.lock()
+        try:
+            for fn, b, size in repo.store.datafiles():
+                if size != 0 and fn[-slen:] == suffix and fn[:plen] == prefix:
+                    res.append(fn[plen:-slen])
+        finally:
+            lock.release()
+        for f in sorted(res):
+            ui.write("%s\n" % f)
+        return
 
     if rev and node:
         raise util.Abort(_("please specify just one revision"))
@@ -2695,7 +3495,7 @@
         node = rev
 
     decor = {'l':'644 @ ', 'x':'755 * ', '':'644   '}
-    ctx = cmdutil.revsingle(repo, node)
+    ctx = scmutil.revsingle(repo, node)
     for f in ctx:
         if ui.debugflag:
             ui.write("%40s " % hex(ctx.manifest()[f]))
@@ -2703,6 +3503,13 @@
             ui.write(decor[ctx.flags(f)])
         ui.write("%s\n" % f)
 
+@command('^merge',
+    [('f', 'force', None, _('force a merge with outstanding changes')),
+    ('t', 'tool', '', _('specify merge tool')),
+    ('r', 'rev', '', _('revision to merge'), _('REV')),
+    ('P', 'preview', None,
+     _('review revisions to merge (no merge is performed)'))],
+    _('[-P] [-f] [[-r] REV]'))
 def merge(ui, repo, node=None, **opts):
     """merge working directory with another revision
 
@@ -2716,7 +3523,7 @@
 
     ``--tool`` can be used to specify the merge tool used for file
     merges. It overrides the HGMERGE environment variable and your
-    configuration files.
+    configuration files. See :hg:`help merge-tools` for options.
 
     If no revision is specified, the working directory's parent is a
     head revision, and the current branch contains exactly one other
@@ -2741,31 +3548,30 @@
         branch = repo[None].branch()
         bheads = repo.branchheads(branch)
         if len(bheads) > 2:
-            raise util.Abort(_(
-                'branch \'%s\' has %d heads - '
-                'please merge with an explicit rev\n'
-                '(run \'hg heads .\' to see heads)')
-                % (branch, len(bheads)))
-
-        parent = repo.dirstate.parents()[0]
+            raise util.Abort(_("branch '%s' has %d heads - "
+                               "please merge with an explicit rev")
+                             % (branch, len(bheads)),
+                             hint=_("run 'hg heads .' to see heads"))
+
+        parent = repo.dirstate.p1()
         if len(bheads) == 1:
             if len(repo.heads()) > 1:
-                raise util.Abort(_(
-                    'branch \'%s\' has one head - '
-                    'please merge with an explicit rev\n'
-                    '(run \'hg heads\' to see all heads)')
-                    % branch)
+                raise util.Abort(_("branch '%s' has one head - "
+                                   "please merge with an explicit rev")
+                                 % branch,
+                                 hint=_("run 'hg heads' to see all heads"))
             msg = _('there is nothing to merge')
             if parent != repo.lookup(repo[None].branch()):
                 msg = _('%s - use "hg update" instead') % msg
             raise util.Abort(msg)
 
         if parent not in bheads:
-            raise util.Abort(_('working dir not at a head rev - '
-                               'use "hg update" or merge with an explicit rev'))
+            raise util.Abort(_('working directory not at a head revision'),
+                             hint=_("use 'hg update' or merge with an "
+                                    "explicit revision"))
         node = parent == bheads[0] and bheads[-1] or bheads[0]
     else:
-        node = cmdutil.revsingle(repo, node).node()
+        node = scmutil.revsingle(repo, node).node()
 
     if opts.get('preview'):
         # find nodes that are ancestors of p2 but not of p1
@@ -2786,6 +3592,16 @@
     finally:
         ui.setconfig('ui', 'forcemerge', '')
 
+@command('outgoing|out',
+    [('f', 'force', None, _('run even when the destination is unrelated')),
+    ('r', 'rev', [],
+     _('a changeset intended to be included in the destination'), _('REV')),
+    ('n', 'newest-first', None, _('show newest record first')),
+    ('B', 'bookmarks', False, _('compare bookmarks')),
+    ('b', 'branch', [], _('a specific branch you would like to push'),
+     _('BRANCH')),
+    ] + logopts + remoteopts + subrepoopts,
+    _('[-M] [-p] [-n] [-f] [-r REV]... [DEST]'))
 def outgoing(ui, repo, dest=None, **opts):
     """show changesets not found in the destination
 
@@ -2801,20 +3617,23 @@
     if opts.get('bookmarks'):
         dest = ui.expandpath(dest or 'default-push', dest or 'default')
         dest, branches = hg.parseurl(dest, opts.get('branch'))
-        other = hg.repository(hg.remoteui(repo, opts), dest)
+        other = hg.peer(repo, opts, dest)
         if 'bookmarks' not in other.listkeys('namespaces'):
             ui.warn(_("remote doesn't support bookmarks\n"))
             return 0
-        ui.status(_('comparing with %s\n') % url.hidepassword(dest))
+        ui.status(_('comparing with %s\n') % util.hidepassword(dest))
         return bookmarks.diff(ui, other, repo)
 
     repo._subtoppath = ui.expandpath(dest or 'default-push', dest or 'default')
     try:
-        ret = hg.outgoing(ui, repo, dest, opts)
-        return ret
+        return hg.outgoing(ui, repo, dest, opts)
     finally:
         del repo._subtoppath
 
+@command('parents',
+    [('r', 'rev', '', _('show parents of the specified revision'), _('REV')),
+    ] + templateopts,
+    _('[-r REV] [FILE]'))
 def parents(ui, repo, file_=None, **opts):
     """show the parents of the working directory or revision
 
@@ -2827,10 +3646,10 @@
     Returns 0 on success.
     """
 
-    ctx = cmdutil.revsingle(repo, opts.get('rev'), None)
+    ctx = scmutil.revsingle(repo, opts.get('rev'), None)
 
     if file_:
-        m = cmdutil.match(repo, (file_,), opts)
+        m = scmutil.match(ctx, (file_,), opts)
         if m.anypats() or len(m.files()) != 1:
             raise util.Abort(_('can only specify an explicit filename'))
         file_ = m.files()[0]
@@ -2855,12 +3674,16 @@
             displayer.show(repo[n])
     displayer.close()
 
+@command('paths', [], _('[NAME]'))
 def paths(ui, repo, search=None):
     """show aliases for remote repositories
 
     Show definition of symbolic path name NAME. If no name is given,
     show definition of all available names.
 
+    Option -q/--quiet suppresses all output when searching for NAME
+    and shows only the path names when listing all definitions.
+
     Path names are defined in the [paths] section of your
     configuration file and in ``/etc/mercurial/hgrc``. If run inside a
     repository, ``.hg/hgrc`` is used, too.
@@ -2883,27 +3706,48 @@
     if search:
         for name, path in ui.configitems("paths"):
             if name == search:
-                ui.write("%s\n" % url.hidepassword(path))
+                ui.status("%s\n" % util.hidepassword(path))
                 return
-        ui.warn(_("not found!\n"))
+        if not ui.quiet:
+            ui.warn(_("not found!\n"))
         return 1
     else:
         for name, path in ui.configitems("paths"):
-            ui.write("%s = %s\n" % (name, url.hidepassword(path)))
+            if ui.quiet:
+                ui.write("%s\n" % name)
+            else:
+                ui.write("%s = %s\n" % (name, util.hidepassword(path)))
 
 def postincoming(ui, repo, modheads, optupdate, checkout):
     if modheads == 0:
         return
     if optupdate:
-        if (modheads <= 1 or len(repo.branchheads()) == 1) or checkout:
+        try:
             return hg.update(repo, checkout)
+        except util.Abort, inst:
+            ui.warn(_("not updating: %s\n" % str(inst)))
+            return 0
+    if modheads > 1:
+        currentbranchheads = len(repo.branchheads())
+        if currentbranchheads == modheads:
+            ui.status(_("(run 'hg heads' to see heads, 'hg merge' to merge)\n"))
+        elif currentbranchheads > 1:
+            ui.status(_("(run 'hg heads .' to see heads, 'hg merge' to merge)\n"))
         else:
-            ui.status(_("not updating, since new heads added\n"))
-    if modheads > 1:
-        ui.status(_("(run 'hg heads' to see heads, 'hg merge' to merge)\n"))
+            ui.status(_("(run 'hg heads' to see heads)\n"))
     else:
         ui.status(_("(run 'hg update' to get a working copy)\n"))
 
+@command('^pull',
+    [('u', 'update', None,
+     _('update to new branch head if changesets were pulled')),
+    ('f', 'force', None, _('run even when remote repository is unrelated')),
+    ('r', 'rev', [], _('a remote changeset intended to be added'), _('REV')),
+    ('B', 'bookmark', [], _("bookmark to pull"), _('BOOKMARK')),
+    ('b', 'branch', [], _('a specific branch you would like to pull'),
+     _('BRANCH')),
+    ] + remoteopts,
+    _('[-u] [-f] [-r REV]... [-e CMD] [--remotecmd CMD] [SOURCE]'))
 def pull(ui, repo, source="default", **opts):
     """pull changes from the specified source
 
@@ -2925,8 +3769,8 @@
     Returns 0 on success, 1 if an update had unresolved files.
     """
     source, branches = hg.parseurl(ui.expandpath(source), opts.get('branch'))
-    other = hg.repository(hg.remoteui(repo, opts), source)
-    ui.status(_('pulling from %s\n') % url.hidepassword(source))
+    other = hg.peer(repo, opts, source)
+    ui.status(_('pulling from %s\n') % util.hidepassword(source))
     revs, checkout = hg.addbranchrevs(repo, other, branches, opts.get('rev'))
 
     if opts.get('bookmark'):
@@ -2947,6 +3791,7 @@
             raise util.Abort(err)
 
     modheads = repo.pull(other, heads=revs, force=opts.get('force'))
+    bookmarks.updatefromremote(ui, repo, other)
     if checkout:
         checkout = str(repo.changelog.rev(other.lookup(checkout)))
     repo._subtoppath = source
@@ -2966,6 +3811,17 @@
 
     return ret
 
+@command('^push',
+    [('f', 'force', None, _('force push')),
+    ('r', 'rev', [],
+     _('a changeset intended to be included in the destination'),
+     _('REV')),
+    ('B', 'bookmark', [], _("bookmark to push"), _('BOOKMARK')),
+    ('b', 'branch', [],
+     _('a specific branch you would like to push'), _('BRANCH')),
+    ('', 'new-branch', False, _('allow pushing a new branch')),
+    ] + remoteopts,
+    _('[-f] [-r REV]... [-e CMD] [--remotecmd CMD] [DEST]'))
 def push(ui, repo, dest=None, **opts):
     """push changes to the specified destination
 
@@ -3008,9 +3864,9 @@
 
     dest = ui.expandpath(dest or 'default-push', dest or 'default')
     dest, branches = hg.parseurl(dest, opts.get('branch'))
-    ui.status(_('pushing to %s\n') % url.hidepassword(dest))
+    ui.status(_('pushing to %s\n') % util.hidepassword(dest))
     revs, checkout = hg.addbranchrevs(repo, repo, branches, opts.get('rev'))
-    other = hg.repository(hg.remoteui(repo, opts), dest)
+    other = hg.peer(repo, opts, dest)
     if revs:
         revs = [repo.lookup(rev) for rev in revs]
 
@@ -3052,6 +3908,7 @@
 
     return result
 
+@command('recover', [])
 def recover(ui, repo):
     """roll back an interrupted transaction
 
@@ -3067,6 +3924,12 @@
         return hg.verify(repo)
     return 1
 
+@command('^remove|rm',
+    [('A', 'after', None, _('record delete for missing files')),
+    ('f', 'force', None,
+     _('remove (and delete) file even if added or modified')),
+    ] + walkopts,
+    _('[OPTION]... FILE...'))
 def remove(ui, repo, *pats, **opts):
     """remove the specified files on the next commit
 
@@ -3090,6 +3953,9 @@
       -A     W  W  W  R
       -Af    R  R  R  R
 
+    Note that remove never deletes files in Added [A] state from the
+    working directory, not even if option --force is specified.
+
     This command schedules the files to be removed at the next commit.
     To undo a remove before that, see :hg:`revert`.
 
@@ -3101,25 +3967,26 @@
     if not pats and not after:
         raise util.Abort(_('no files specified'))
 
-    m = cmdutil.match(repo, pats, opts)
+    m = scmutil.match(repo[None], pats, opts)
     s = repo.status(match=m, clean=True)
     modified, added, deleted, clean = s[0], s[1], s[3], s[6]
 
     for f in m.files():
         if f not in repo.dirstate and not os.path.isdir(m.rel(f)):
-            ui.warn(_('not removing %s: file is untracked\n') % m.rel(f))
+            if os.path.exists(m.rel(f)):
+                ui.warn(_('not removing %s: file is untracked\n') % m.rel(f))
             ret = 1
 
     if force:
-        remove, forget = modified + deleted + clean, added
+        list = modified + deleted + clean + added
     elif after:
-        remove, forget = deleted, []
+        list = deleted
         for f in modified + added + clean:
             ui.warn(_('not removing %s: file still exists (use -f'
                       ' to force removal)\n') % m.rel(f))
             ret = 1
     else:
-        remove, forget = deleted + clean, []
+        list = deleted + clean
         for f in modified:
             ui.warn(_('not removing %s: file is modified (use -f'
                       ' to force removal)\n') % m.rel(f))
@@ -3129,14 +3996,32 @@
                       ' to force removal)\n') % m.rel(f))
             ret = 1
 
-    for f in sorted(remove + forget):
+    for f in sorted(list):
         if ui.verbose or not m.exact(f):
             ui.status(_('removing %s\n') % m.rel(f))
 
-    repo[None].forget(forget)
-    repo[None].remove(remove, unlink=not after)
+    wlock = repo.wlock()
+    try:
+        if not after:
+            for f in list:
+                if f in added:
+                    continue # we never unlink added files on remove
+                try:
+                    util.unlinkpath(repo.wjoin(f))
+                except OSError, inst:
+                    if inst.errno != errno.ENOENT:
+                        raise
+        repo[None].forget(list)
+    finally:
+        wlock.release()
+
     return ret
 
+@command('rename|move|mv',
+    [('A', 'after', None, _('record a rename that has already occurred')),
+    ('f', 'force', None, _('forcibly copy over an existing managed file')),
+    ] + walkopts + dryrunopts,
+    _('[OPTION]... SOURCE... DEST'))
 def rename(ui, repo, *pats, **opts):
     """rename files; equivalent of copy + remove
 
@@ -3159,6 +4044,15 @@
     finally:
         wlock.release()
 
+@command('resolve',
+    [('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, _('mark files as unresolved')),
+    ('t', 'tool', '', _('specify merge tool')),
+    ('n', 'no-status', None, _('hide status prefix'))]
+    + walkopts,
+    _('[OPTION]... [FILE]...'))
 def resolve(ui, repo, *pats, **opts):
     """redo merges or set/view the merge status of files
 
@@ -3207,7 +4101,7 @@
                            'use --all to remerge all files'))
 
     ms = mergemod.mergestate(repo)
-    m = cmdutil.match(repo, pats, opts)
+    m = scmutil.match(repo[None], pats, opts)
     ret = 0
 
     for f in ms:
@@ -3245,44 +4139,37 @@
     ms.commit()
     return ret
 
+@command('revert',
+    [('a', 'all', None, _('revert all changes when no arguments given')),
+    ('d', 'date', '', _('tipmost revision matching date'), _('DATE')),
+    ('r', 'rev', '', _('revert to the specified revision'), _('REV')),
+    ('', 'no-backup', None, _('do not save backup copies of files')),
+    ] + walkopts + dryrunopts,
+    _('[OPTION]... [-r REV] [NAME]...'))
 def revert(ui, repo, *pats, **opts):
-    """restore individual files or directories to an earlier state
+    """restore files to their checkout state
 
     .. note::
-       This command is most likely not what you are looking for.
-       Revert will partially overwrite content in the working
-       directory without changing the working directory parents. Use
-       :hg:`update -r rev` to check out earlier revisions, or
-       :hg:`update --clean .` to undo a merge which has added another
-       parent.
-
-    With no revision specified, revert the named files or directories
-    to the contents they had in the parent of the working directory.
-    This restores the contents of the affected files to an unmodified
-    state and unschedules adds, removes, copies, and renames. If the
-    working directory has two parents, you must explicitly specify a
-    revision.
-
-    Using the -r/--rev option, revert the given files or directories
-    to their contents as of a specific revision. This can be helpful
-    to "roll back" some or all of an earlier change. See :hg:`help
-    dates` for a list of formats valid for -d/--date.
-
-    Revert modifies the working directory. It does not commit any
-    changes, or change the parent of the working directory. If you
-    revert to a revision other than the parent of the working
-    directory, the reverted files will thus appear modified
-    afterwards.
-
-    If a file has been deleted, it is restored. If the executable mode
-    of a file was changed, it is reset.
-
-    If names are given, all files matching the names are reverted.
-    If no arguments are given, no files are reverted.
+       To check out earlier revisions, you should use :hg:`update REV`.
+       To cancel a merge (and lose your changes), use :hg:`update --clean .`.
+
+    With no revision specified, revert the specified files or directories
+    to the state they had in the first parent of the working directory.
+    This restores the contents of files to an unmodified
+    state and unschedules adds, removes, copies, and renames.
+
+    Using the -r/--rev or -d/--date options, revert the given files or
+    directories to their states as of a specific revision. Because
+    revert does not change the working directory parents, this will
+    cause these files to appear modified. This can be helpful to "back
+    out" some or all of an earlier change. See :hg:`backout` for a
+    related method.
 
     Modified files are saved with a .orig suffix before reverting.
     To disable these backups, use --no-backup.
 
+    See :hg:`help dates` for a list of formats valid for -d/--date.
+
     Returns 0 on success.
     """
 
@@ -3292,15 +4179,12 @@
         opts["rev"] = cmdutil.finddate(ui, repo, opts["date"])
 
     parent, p2 = repo.dirstate.parents()
-    if not opts.get('rev') and p2 != nullid:
-        raise util.Abort(_('uncommitted merge - '
-                           'use "hg update", see "hg help revert"'))
 
     if not pats and not opts.get('all'):
-        raise util.Abort(_('no files or directories specified; '
-                           'use --all to revert the whole repo'))
-
-    ctx = cmdutil.revsingle(repo, opts.get('rev'))
+        raise util.Abort(_('no files or directories specified'),
+                         hint=_('use --all to revert all files'))
+
+    ctx = scmutil.revsingle(repo, opts.get('rev'))
     node = ctx.node()
     mf = ctx.manifest()
     if node == parent:
@@ -3318,7 +4202,7 @@
     try:
         # walk dirstate.
 
-        m = cmdutil.match(repo, pats, opts)
+        m = scmutil.match(repo[None], pats, opts)
         m.bad = lambda x, y: False
         for abs in repo.walk(m):
             names[abs] = m.rel(abs), m.exact(abs)
@@ -3334,13 +4218,13 @@
                     return
             ui.warn("%s: %s\n" % (m.rel(path), msg))
 
-        m = cmdutil.match(repo, pats, opts)
+        m = scmutil.match(repo[node], pats, opts)
         m.bad = badfn
         for abs in repo[node].walk(m):
             if abs not in names:
                 names[abs] = m.rel(abs), m.exact(abs)
 
-        m = cmdutil.matchfiles(repo, names)
+        m = scmutil.matchfiles(repo, names)
         changes = repo.status(match=m)[:4]
         modified, added, removed, deleted = map(set, changes)
 
@@ -3432,10 +4316,10 @@
                 fc = ctx[f]
                 repo.wwrite(f, fc.data(), fc.flags())
 
-            audit_path = util.path_auditor(repo.root)
+            audit_path = scmutil.pathauditor(repo.root)
             for f in remove[0]:
                 if repo.dirstate[f] == 'a':
-                    repo.dirstate.forget(f)
+                    repo.dirstate.drop(f)
                     continue
                 audit_path(f)
                 try:
@@ -3472,6 +4356,7 @@
     finally:
         wlock.release()
 
+@command('rollback', dryrunopts)
 def rollback(ui, repo, **opts):
     """roll back the last transaction (dangerous)
 
@@ -3503,6 +4388,7 @@
     """
     return repo.rollback(opts.get('dry_run'))
 
+@command('root', [])
 def root(ui, repo):
     """print the root (top) of the current working directory
 
@@ -3512,6 +4398,32 @@
     """
     ui.write(repo.root + "\n")
 
+@command('^serve',
+    [('A', 'accesslog', '', _('name of access log file to write to'),
+     _('FILE')),
+    ('d', 'daemon', None, _('run server in background')),
+    ('', 'daemon-pipefds', '', _('used internally by daemon mode'), _('NUM')),
+    ('E', 'errorlog', '', _('name of error log file to write to'), _('FILE')),
+    # use string type, then we can check if something was passed
+    ('p', 'port', '', _('port to listen on (default: 8000)'), _('PORT')),
+    ('a', 'address', '', _('address to listen on (default: all interfaces)'),
+     _('ADDR')),
+    ('', 'prefix', '', _('prefix path to serve from (default: server root)'),
+     _('PREFIX')),
+    ('n', 'name', '',
+     _('name to show in web pages (default: working directory)'), _('NAME')),
+    ('', 'web-conf', '',
+     _('name of the hgweb config file (see "hg help hgweb")'), _('FILE')),
+    ('', 'webdir-conf', '', _('name of the hgweb config file (DEPRECATED)'),
+     _('FILE')),
+    ('', 'pid-file', '', _('name of file to write process ID to'), _('FILE')),
+    ('', 'stdio', None, _('for remote clients')),
+    ('', 'cmdserver', '', _('for remote clients'), _('MODE')),
+    ('t', 'templates', '', _('web templates to use'), _('TEMPLATE')),
+    ('', 'style', '', _('template style to use'), _('STYLE')),
+    ('6', 'ipv6', None, _('use IPv6 in addition to IPv4')),
+    ('', 'certificate', '', _('SSL certificate file'), _('FILE'))],
+    _('[OPTION]...'))
 def serve(ui, repo, **opts):
     """start stand-alone webserver
 
@@ -3537,13 +4449,24 @@
     Returns 0 on success.
     """
 
-    if opts["stdio"]:
+    if opts["stdio"] and opts["cmdserver"]:
+        raise util.Abort(_("cannot use --stdio with --cmdserver"))
+
+    def checkrepo():
         if repo is None:
             raise error.RepoError(_("There is no Mercurial repository here"
                               " (.hg not found)"))
+
+    if opts["stdio"]:
+        checkrepo()
         s = sshserver.sshserver(ui, repo)
         s.serve_forever()
 
+    if opts["cmdserver"]:
+        checkrepo()
+        s = commandserver.server(ui, repo, opts["cmdserver"])
+        return s.serve()
+
     # this way we can check if something was given in the command-line
     if opts.get('port'):
         opts['port'] = util.getport(opts.get('port'))
@@ -3570,7 +4493,7 @@
 
     class service(object):
         def init(self):
-            util.set_signal_handler()
+            util.setsignalhandler()
             self.httpd = hgweb.server.create_server(ui, app)
 
             if opts['port'] and not ui.verbose:
@@ -3608,6 +4531,68 @@
 
     cmdutil.service(opts, initfn=service.init, runfn=service.run)
 
+@command('showconfig|debugconfig',
+    [('u', 'untrusted', None, _('show untrusted configuration options'))],
+    _('[-u] [NAME]...'))
+def showconfig(ui, repo, *values, **opts):
+    """show combined config settings from all hgrc files
+
+    With no arguments, print names and values of all config items.
+
+    With one argument of the form section.name, print just the value
+    of that config item.
+
+    With multiple arguments, print names and values of all config
+    items with matching section names.
+
+    With --debug, the source (filename and line number) is printed
+    for each config item.
+
+    Returns 0 on success.
+    """
+
+    for f in scmutil.rcpath():
+        ui.debug(_('read config from: %s\n') % f)
+    untrusted = bool(opts.get('untrusted'))
+    if values:
+        sections = [v for v in values if '.' not in v]
+        items = [v for v in values if '.' in v]
+        if len(items) > 1 or items and sections:
+            raise util.Abort(_('only one config item permitted'))
+    for section, name, value in ui.walkconfig(untrusted=untrusted):
+        value = str(value).replace('\n', '\\n')
+        sectname = section + '.' + name
+        if values:
+            for v in values:
+                if v == section:
+                    ui.debug('%s: ' %
+                             ui.configsource(section, name, untrusted))
+                    ui.write('%s=%s\n' % (sectname, value))
+                elif v == sectname:
+                    ui.debug('%s: ' %
+                             ui.configsource(section, name, untrusted))
+                    ui.write(value, '\n')
+        else:
+            ui.debug('%s: ' %
+                     ui.configsource(section, name, untrusted))
+            ui.write('%s=%s\n' % (sectname, value))
+
+@command('^status|st',
+    [('A', 'all', None, _('show status of all files')),
+    ('m', 'modified', None, _('show only modified files')),
+    ('a', 'added', None, _('show only added files')),
+    ('r', 'removed', None, _('show only removed files')),
+    ('d', 'deleted', None, _('show only deleted (but tracked) files')),
+    ('c', 'clean', None, _('show only files without changes')),
+    ('u', 'unknown', None, _('show only unknown (not tracked) files')),
+    ('i', 'ignored', None, _('show only ignored files')),
+    ('n', 'no-status', None, _('hide status prefix')),
+    ('C', 'copies', None, _('show source of copied files')),
+    ('0', 'print0', None, _('end filenames with NUL, for use with xargs')),
+    ('', 'rev', [], _('show difference from revision'), _('REV')),
+    ('', 'change', '', _('list the changed files of a revision'), _('REV')),
+    ] + walkopts + subrepoopts,
+    _('[OPTION]... [FILE]...'))
 def status(ui, repo, *pats, **opts):
     """show changed files in the working directory
 
@@ -3654,9 +4639,9 @@
         raise util.Abort(msg)
     elif change:
         node2 = repo.lookup(change)
-        node1 = repo[node2].parents()[0].node()
+        node1 = repo[node2].p1().node()
     else:
-        node1, node2 = cmdutil.revpair(repo, revs)
+        node1, node2 = scmutil.revpair(repo, revs)
 
     cwd = (pats and repo.getcwd()) or ''
     end = opts.get('print0') and '\0' or '\n'
@@ -3668,7 +4653,7 @@
     if not show:
         show = ui.quiet and states[:4] or states[:5]
 
-    stat = repo.status(node1, node2, cmdutil.match(repo, pats, opts),
+    stat = repo.status(node1, node2, scmutil.match(repo[node2], pats, opts),
                        'ignored' in show, 'clean' in show, 'unknown' in show,
                        opts.get('subrepos'))
     changestates = zip(states, 'MAR!?IC', stat)
@@ -3700,6 +4685,8 @@
                     ui.write('  %s%s' % (repo.pathto(copy[f], cwd), end),
                              label='status.copied')
 
+@command('^summary|sum',
+    [('', 'remote', None, _('check for push and pull'))], '[--remote]')
 def summary(ui, repo, **opts):
     """summarize working directory state
 
@@ -3824,23 +4811,27 @@
     if opts.get('remote'):
         t = []
         source, branches = hg.parseurl(ui.expandpath('default'))
-        other = hg.repository(hg.remoteui(repo, {}), source)
+        other = hg.peer(repo, {}, source)
         revs, checkout = hg.addbranchrevs(repo, other, branches, opts.get('rev'))
-        ui.debug('comparing with %s\n' % url.hidepassword(source))
+        ui.debug('comparing with %s\n' % util.hidepassword(source))
         repo.ui.pushbuffer()
-        common, incoming, rheads = discovery.findcommonincoming(repo, other)
+        commoninc = discovery.findcommonincoming(repo, other)
+        _common, incoming, _rheads = commoninc
         repo.ui.popbuffer()
         if incoming:
             t.append(_('1 or more incoming'))
 
         dest, branches = hg.parseurl(ui.expandpath('default-push', 'default'))
         revs, checkout = hg.addbranchrevs(repo, repo, branches, None)
-        other = hg.repository(hg.remoteui(repo, {}), dest)
-        ui.debug('comparing with %s\n' % url.hidepassword(dest))
+        if source != dest:
+            other = hg.peer(repo, {}, dest)
+            commoninc = None
+            ui.debug('comparing with %s\n' % util.hidepassword(dest))
         repo.ui.pushbuffer()
-        o = discovery.findoutgoing(repo, other)
+        common, outheads = discovery.findcommonoutgoing(repo, other,
+                                                        commoninc=commoninc)
         repo.ui.popbuffer()
-        o = repo.changelog.nodesbetween(o, None)[0]
+        o = repo.changelog.findmissing(common=common, heads=outheads)
         if o:
             t.append(_('%d outgoing') % len(o))
         if 'bookmarks' in other.listkeys('namespaces'):
@@ -3858,6 +4849,16 @@
         else:
             ui.status(_('remote: (synced)\n'))
 
+@command('tag',
+    [('f', 'force', None, _('force tag')),
+    ('l', 'local', None, _('make the tag local')),
+    ('r', 'rev', '', _('revision to tag'), _('REV')),
+    ('', 'remove', None, _('remove a tag')),
+    # -l/--local is already there, commitopts cannot be used
+    ('e', 'edit', None, _('edit commit message')),
+    ('m', 'message', '', _('use <text> as commit message'), _('TEXT')),
+    ] + commitopts2,
+    _('[-f] [-l] [-m TEXT] [-d DATE] [-u USER] [-r REV] NAME...'))
 def tag(ui, repo, name1, *names, **opts):
     """add one or more tags for the current or given revision
 
@@ -3897,7 +4898,7 @@
         raise util.Abort(_('tag names must be unique'))
     for n in names:
         if n in ['tip', '.', 'null']:
-            raise util.Abort(_('the name \'%s\' is reserved') % n)
+            raise util.Abort(_("the name '%s' is reserved") % n)
         if not n:
             raise util.Abort(_('tag names cannot consist entirely of whitespace'))
     if opts.get('rev') and opts.get('remove'):
@@ -3909,12 +4910,12 @@
         expectedtype = opts.get('local') and 'local' or 'global'
         for n in names:
             if not repo.tagtype(n):
-                raise util.Abort(_('tag \'%s\' does not exist') % n)
+                raise util.Abort(_("tag '%s' does not exist") % n)
             if repo.tagtype(n) != expectedtype:
                 if expectedtype == 'global':
-                    raise util.Abort(_('tag \'%s\' is not a global tag') % n)
+                    raise util.Abort(_("tag '%s' is not a global tag") % n)
                 else:
-                    raise util.Abort(_('tag \'%s\' is not a local tag') % n)
+                    raise util.Abort(_("tag '%s' is not a local tag") % n)
         rev_ = nullid
         if not message:
             # we don't translate commit messages
@@ -3922,8 +4923,8 @@
     elif not opts.get('force'):
         for n in names:
             if n in repo.tags():
-                raise util.Abort(_('tag \'%s\' already exists '
-                                   '(use -f to force)') % n)
+                raise util.Abort(_("tag '%s' already exists "
+                                   "(use -f to force)") % n)
     if not opts.get('local'):
         p1, p2 = repo.dirstate.parents()
         if p2 != nullid:
@@ -3931,7 +4932,7 @@
         bheads = repo.branchheads()
         if not opts.get('force') and bheads and p1 not in bheads:
             raise util.Abort(_('not at a branch head (use -f to force)'))
-    r = cmdutil.revsingle(repo, rev_).node()
+    r = scmutil.revsingle(repo, rev_).node()
 
     if not message:
         # we don't translate commit messages
@@ -3947,6 +4948,7 @@
 
     repo.tag(names, r, message, opts.get('local'), opts.get('user'), date)
 
+@command('tags', [], '')
 def tags(ui, repo):
     """list repository tags
 
@@ -3964,20 +4966,22 @@
             ui.write("%s\n" % t)
             continue
 
-        try:
-            hn = hexfunc(n)
-            r = "%5d:%s" % (repo.changelog.rev(n), hn)
-        except error.LookupError:
-            r = "    ?:%s" % hn
-        else:
-            spaces = " " * (30 - encoding.colwidth(t))
-            if ui.verbose:
-                if repo.tagtype(t) == 'local':
-                    tagtype = " local"
-                else:
-                    tagtype = ""
-            ui.write("%s%s %s%s\n" % (t, spaces, r, tagtype))
-
+        hn = hexfunc(n)
+        r = "%5d:%s" % (repo.changelog.rev(n), hn)
+        spaces = " " * (30 - encoding.colwidth(t))
+
+        if ui.verbose:
+            if repo.tagtype(t) == 'local':
+                tagtype = " local"
+            else:
+                tagtype = ""
+        ui.write("%s%s %s%s\n" % (t, spaces, r, tagtype))
+
+@command('tip',
+    [('p', 'patch', None, _('show patch')),
+    ('g', 'git', None, _('use git extended diff format')),
+    ] + templateopts,
+    _('[-p] [-g]'))
 def tip(ui, repo, **opts):
     """show the tip revision
 
@@ -3996,6 +5000,10 @@
     displayer.show(repo[len(repo) - 1])
     displayer.close()
 
+@command('unbundle',
+    [('u', 'update', None,
+     _('update to new branch head if changesets were unbundled'))],
+    _('[-u] FILE...'))
 def unbundle(ui, repo, fname1, *fnames, **opts):
     """apply one or more changegroup files
 
@@ -4007,17 +5015,25 @@
     fnames = (fname1,) + fnames
 
     lock = repo.lock()
+    wc = repo['.']
     try:
         for fname in fnames:
             f = url.open(ui, fname)
             gen = changegroup.readbundle(f, fname)
             modheads = repo.addchangegroup(gen, 'unbundle', 'bundle:' + fname,
                                            lock=lock)
+        bookmarks.updatecurrentbookmark(repo, wc.node(), wc.branch())
     finally:
         lock.release()
-
     return postincoming(ui, repo, modheads, opts.get('update'), None)
 
+@command('^update|up|checkout|co',
+    [('C', 'clean', None, _('discard uncommitted changes (no backup)')),
+    ('c', 'check', None,
+     _('update across branches if no uncommitted changes')),
+    ('d', 'date', '', _('tipmost revision matching date'), _('DATE')),
+    ('r', 'rev', '', _('revision'), _('REV'))],
+    _('[-c] [-C] [-d DATE] [[-r] REV]'))
 def update(ui, repo, node=None, rev=None, clean=False, date=None, check=False):
     """update working directory (or switch revisions)
 
@@ -4062,12 +5078,12 @@
     if rev and node:
         raise util.Abort(_("please specify just one revision"))
 
-    if not rev:
+    if rev is None or rev == '':
         rev = node
 
     # if we defined a bookmark, we have to remember the original bookmark name
     brev = rev
-    rev = cmdutil.revsingle(repo, rev, rev).rev()
+    rev = scmutil.revsingle(repo, rev, rev).rev()
 
     if check and clean:
         raise util.Abort(_("cannot specify both -c/--check and -C/--clean"))
@@ -4079,7 +5095,7 @@
             raise util.Abort(_("uncommitted local changes"))
 
     if date:
-        if rev:
+        if rev is not None:
             raise util.Abort(_("you can't specify a revision and a date"))
         rev = cmdutil.finddate(ui, repo, date)
 
@@ -4093,6 +5109,7 @@
 
     return ret
 
+@command('verify', [])
 def verify(ui, repo):
     """verify the integrity of the repository
 
@@ -4107,6 +5124,7 @@
     """
     return hg.verify(repo)
 
+@command('version', [])
 def version_(ui):
     """output version and copyright information"""
     ui.write(_("Mercurial Distributed SCM (version %s)\n")
@@ -4119,639 +5137,8 @@
         "not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
     ))
 
-# Command options and aliases are listed here, alphabetically
-
-globalopts = [
-    ('R', 'repository', '',
-     _('repository root directory or name of overlay bundle file'),
-     _('REPO')),
-    ('', 'cwd', '',
-     _('change working directory'), _('DIR')),
-    ('y', 'noninteractive', None,
-     _('do not prompt, assume \'yes\' for any required answers')),
-    ('q', 'quiet', None, _('suppress output')),
-    ('v', 'verbose', None, _('enable additional output')),
-    ('', 'config', [],
-     _('set/override config option (use \'section.name=value\')'),
-     _('CONFIG')),
-    ('', 'debug', None, _('enable debugging output')),
-    ('', 'debugger', None, _('start debugger')),
-    ('', 'encoding', encoding.encoding, _('set the charset encoding'),
-     _('ENCODE')),
-    ('', 'encodingmode', encoding.encodingmode,
-     _('set the charset encoding mode'), _('MODE')),
-    ('', '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')),
-    ('h', 'help', None, _('display help and exit')),
-]
-
-dryrunopts = [('n', 'dry-run', None,
-               _('do not perform actions, just print output'))]
-
-remoteopts = [
-    ('e', 'ssh', '',
-     _('specify ssh command to use'), _('CMD')),
-    ('', 'remotecmd', '',
-     _('specify hg command to run on the remote side'), _('CMD')),
-    ('', 'insecure', None,
-     _('do not verify server certificate (ignoring web.cacerts config)')),
-]
-
-walkopts = [
-    ('I', 'include', [],
-     _('include names matching the given patterns'), _('PATTERN')),
-    ('X', 'exclude', [],
-     _('exclude names matching the given patterns'), _('PATTERN')),
-]
-
-commitopts = [
-    ('m', 'message', '',
-     _('use text as commit message'), _('TEXT')),
-    ('l', 'logfile', '',
-     _('read commit message from file'), _('FILE')),
-]
-
-commitopts2 = [
-    ('d', 'date', '',
-     _('record the specified date as commit date'), _('DATE')),
-    ('u', 'user', '',
-     _('record the specified user as committer'), _('USER')),
-]
-
-templateopts = [
-    ('', 'style', '',
-     _('display using template map file'), _('STYLE')),
-    ('', 'template', '',
-     _('display with template'), _('TEMPLATE')),
-]
-
-logopts = [
-    ('p', 'patch', None, _('show patch')),
-    ('g', 'git', None, _('use git extended diff format')),
-    ('l', 'limit', '',
-     _('limit number of changes displayed'), _('NUM')),
-    ('M', 'no-merges', None, _('do not show merges')),
-    ('', 'stat', None, _('output diffstat-style summary of changes')),
-] + templateopts
-
-diffopts = [
-    ('a', 'text', None, _('treat all files as text')),
-    ('g', 'git', None, _('use git extended diff format')),
-    ('', 'nodates', None, _('omit dates from diff headers'))
-]
-
-diffopts2 = [
-    ('p', 'show-function', None, _('show which function each change is in')),
-    ('', 'reverse', None, _('produce a diff that undoes the changes')),
-    ('w', 'ignore-all-space', None,
-     _('ignore white space when comparing lines')),
-    ('b', 'ignore-space-change', None,
-     _('ignore changes in the amount of white space')),
-    ('B', 'ignore-blank-lines', None,
-     _('ignore changes whose lines are all blank')),
-    ('U', 'unified', '',
-     _('number of lines of context to show'), _('NUM')),
-    ('', 'stat', None, _('output diffstat-style summary of changes')),
-]
-
-similarityopts = [
-    ('s', 'similarity', '',
-     _('guess renamed files by similarity (0<=s<=100)'), _('SIMILARITY'))
-]
-
-subrepoopts = [
-    ('S', 'subrepos', None,
-     _('recurse into subrepositories'))
-]
-
-table = {
-    "^add": (add, walkopts + subrepoopts + dryrunopts,
-             _('[OPTION]... [FILE]...')),
-    "addremove":
-        (addremove, similarityopts + walkopts + dryrunopts,
-         _('[OPTION]... [FILE]...')),
-    "^annotate|blame":
-        (annotate,
-         [('r', 'rev', '',
-           _('annotate the specified revision'), _('REV')),
-          ('', 'follow', None,
-           _('follow copies/renames and list the filename (DEPRECATED)')),
-          ('', 'no-follow', None, _("don't follow copies and renames")),
-          ('a', 'text', None, _('treat all files as text')),
-          ('u', 'user', None, _('list the author (long with -v)')),
-          ('f', 'file', None, _('list the filename')),
-          ('d', 'date', None, _('list the date (short with -q)')),
-          ('n', 'number', None, _('list the revision number (default)')),
-          ('c', 'changeset', None, _('list the changeset')),
-          ('l', 'line-number', None,
-           _('show line number at the first appearance'))
-         ] + walkopts,
-         _('[-r REV] [-f] [-a] [-u] [-d] [-n] [-c] [-l] FILE...')),
-    "archive":
-        (archive,
-         [('', 'no-decode', None, _('do not pass files through decoders')),
-          ('p', 'prefix', '',
-           _('directory prefix for files in archive'), _('PREFIX')),
-          ('r', 'rev', '',
-           _('revision to distribute'), _('REV')),
-          ('t', 'type', '',
-           _('type of distribution to create'), _('TYPE')),
-         ] + subrepoopts + walkopts,
-         _('[OPTION]... DEST')),
-    "backout":
-        (backout,
-         [('', 'merge', None,
-           _('merge with old dirstate parent after backout')),
-          ('', 'parent', '',
-           _('parent to choose when backing out merge'), _('REV')),
-          ('t', 'tool', '',
-           _('specify merge tool')),
-          ('r', 'rev', '',
-           _('revision to backout'), _('REV')),
-         ] + walkopts + commitopts + commitopts2,
-         _('[OPTION]... [-r] REV')),
-    "bisect":
-        (bisect,
-         [('r', 'reset', False, _('reset bisect state')),
-          ('g', 'good', False, _('mark changeset good')),
-          ('b', 'bad', False, _('mark changeset bad')),
-          ('s', 'skip', False, _('skip testing changeset')),
-          ('c', 'command', '',
-           _('use command to check changeset state'), _('CMD')),
-          ('U', 'noupdate', False, _('do not update to target'))],
-         _("[-gbsr] [-U] [-c CMD] [REV]")),
-    "bookmarks":
-        (bookmark,
-         [('f', 'force', False, _('force')),
-          ('r', 'rev', '', _('revision'), _('REV')),
-          ('d', 'delete', False, _('delete a given bookmark')),
-          ('m', 'rename', '', _('rename a given bookmark'), _('NAME'))],
-         _('hg bookmarks [-f] [-d] [-m NAME] [-r REV] [NAME]')),
-    "branch":
-        (branch,
-         [('f', 'force', None,
-           _('set branch name even if it shadows an existing branch')),
-          ('C', 'clean', None, _('reset branch name to parent branch name'))],
-         _('[-fC] [NAME]')),
-    "branches":
-        (branches,
-         [('a', 'active', False,
-           _('show only branches that have unmerged heads')),
-          ('c', 'closed', False,
-           _('show normal and closed branches'))],
-         _('[-ac]')),
-    "bundle":
-        (bundle,
-         [('f', 'force', None,
-           _('run even when the destination is unrelated')),
-          ('r', 'rev', [],
-           _('a changeset intended to be added to the destination'),
-           _('REV')),
-          ('b', 'branch', [],
-           _('a specific branch you would like to bundle'),
-           _('BRANCH')),
-          ('', 'base', [],
-           _('a base changeset assumed to be available at the destination'),
-           _('REV')),
-          ('a', 'all', None, _('bundle all changesets in the repository')),
-          ('t', 'type', 'bzip2',
-           _('bundle compression type to use'), _('TYPE')),
-         ] + remoteopts,
-         _('[-f] [-t TYPE] [-a] [-r REV]... [--base REV]... FILE [DEST]')),
-    "cat":
-        (cat,
-         [('o', 'output', '',
-          _('print output to file with formatted name'), _('FORMAT')),
-          ('r', 'rev', '',
-           _('print the given revision'), _('REV')),
-          ('', 'decode', None, _('apply any matching decode filter')),
-         ] + walkopts,
-         _('[OPTION]... FILE...')),
-    "^clone":
-        (clone,
-         [('U', 'noupdate', None,
-          _('the clone will include an empty working copy (only a repository)')),
-          ('u', 'updaterev', '',
-           _('revision, tag or branch to check out'), _('REV')),
-          ('r', 'rev', [],
-           _('include the specified changeset'), _('REV')),
-          ('b', 'branch', [],
-           _('clone only the specified branch'), _('BRANCH')),
-          ('', 'pull', None, _('use pull protocol to copy metadata')),
-          ('', 'uncompressed', None,
-           _('use uncompressed transfer (fast over LAN)')),
-         ] + remoteopts,
-         _('[OPTION]... SOURCE [DEST]')),
-    "^commit|ci":
-        (commit,
-         [('A', 'addremove', None,
-           _('mark new/missing files as added/removed before committing')),
-          ('', 'close-branch', None,
-           _('mark a branch as closed, hiding it from the branch list')),
-         ] + walkopts + commitopts + commitopts2,
-         _('[OPTION]... [FILE]...')),
-    "copy|cp":
-        (copy,
-         [('A', 'after', None, _('record a copy that has already occurred')),
-          ('f', 'force', None,
-           _('forcibly copy over an existing managed file')),
-         ] + walkopts + dryrunopts,
-         _('[OPTION]... [SOURCE]... DEST')),
-    "debugancestor": (debugancestor, [], _('[INDEX] REV1 REV2')),
-    "debugbuilddag":
-        (debugbuilddag,
-         [('m', 'mergeable-file', None, _('add single file mergeable changes')),
-          ('a', 'appended-file', None, _('add single file all revs append to')),
-          ('o', 'overwritten-file', None, _('add single file all revs overwrite')),
-          ('n', 'new-file', None, _('add new file at each rev')),
-         ],
-         _('[OPTION]... TEXT')),
-    "debugcheckstate": (debugcheckstate, [], ''),
-    "debugcommands": (debugcommands, [], _('[COMMAND]')),
-    "debugcomplete":
-        (debugcomplete,
-         [('o', 'options', None, _('show the command options'))],
-         _('[-o] CMD')),
-    "debugdag":
-        (debugdag,
-         [('t', 'tags', None, _('use tags as labels')),
-          ('b', 'branches', None, _('annotate with branch names')),
-          ('', 'dots', None, _('use dots for runs')),
-          ('s', 'spaces', None, _('separate elements by spaces')),
-         ],
-         _('[OPTION]... [FILE [REV]...]')),
-    "debugdate":
-        (debugdate,
-         [('e', 'extended', None, _('try extended date formats'))],
-         _('[-e] DATE [RANGE]')),
-    "debugdata": (debugdata, [], _('FILE REV')),
-    "debugfsinfo": (debugfsinfo, [], _('[PATH]')),
-    "debugignore": (debugignore, [], ''),
-    "debugindex": (debugindex,
-                   [('f', 'format', 0, _('revlog format'), _('FORMAT'))],
-                   _('FILE')),
-    "debugindexdot": (debugindexdot, [], _('FILE')),
-    "debuginstall": (debuginstall, [], ''),
-    "debugpushkey": (debugpushkey, [], _('REPO NAMESPACE [KEY OLD NEW]')),
-    "debugrebuildstate":
-        (debugrebuildstate,
-         [('r', 'rev', '',
-           _('revision to rebuild to'), _('REV'))],
-         _('[-r REV] [REV]')),
-    "debugrename":
-        (debugrename,
-         [('r', 'rev', '',
-           _('revision to debug'), _('REV'))],
-         _('[-r REV] FILE')),
-    "debugrevspec":
-        (debugrevspec, [], ('REVSPEC')),
-    "debugsetparents":
-        (debugsetparents, [], _('REV1 [REV2]')),
-    "debugstate":
-        (debugstate,
-         [('', 'nodates', None, _('do not display the saved mtime'))],
-         _('[OPTION]...')),
-    "debugsub":
-        (debugsub,
-         [('r', 'rev', '',
-           _('revision to check'), _('REV'))],
-         _('[-r REV] [REV]')),
-    "debugwalk": (debugwalk, walkopts, _('[OPTION]... [FILE]...')),
-    "^diff":
-        (diff,
-         [('r', 'rev', [],
-           _('revision'), _('REV')),
-          ('c', 'change', '',
-           _('change made by revision'), _('REV'))
-         ] + diffopts + diffopts2 + walkopts + subrepoopts,
-         _('[OPTION]... ([-c REV] | [-r REV1 [-r REV2]]) [FILE]...')),
-    "^export":
-        (export,
-         [('o', 'output', '',
-           _('print output to file with formatted name'), _('FORMAT')),
-          ('', 'switch-parent', None, _('diff against the second parent')),
-          ('r', 'rev', [],
-           _('revisions to export'), _('REV')),
-          ] + diffopts,
-         _('[OPTION]... [-o OUTFILESPEC] REV...')),
-    "^forget":
-        (forget,
-         [] + walkopts,
-         _('[OPTION]... FILE...')),
-    "grep":
-        (grep,
-         [('0', 'print0', None, _('end fields with NUL')),
-          ('', 'all', None, _('print all revisions that match')),
-          ('f', 'follow', None,
-           _('follow changeset history,'
-             ' or file history across copies and renames')),
-          ('i', 'ignore-case', None, _('ignore case when matching')),
-          ('l', 'files-with-matches', None,
-           _('print only filenames and revisions that match')),
-          ('n', 'line-number', None, _('print matching line numbers')),
-          ('r', 'rev', [],
-           _('only search files changed within revision range'), _('REV')),
-          ('u', 'user', None, _('list the author (long with -v)')),
-          ('d', 'date', None, _('list the date (short with -q)')),
-         ] + walkopts,
-         _('[OPTION]... PATTERN [FILE]...')),
-    "heads":
-        (heads,
-         [('r', 'rev', '',
-           _('show only heads which are descendants of STARTREV'),
-           _('STARTREV')),
-          ('t', 'topo', False, _('show topological heads only')),
-          ('a', 'active', False,
-           _('show active branchheads only (DEPRECATED)')),
-          ('c', 'closed', False,
-           _('show normal and closed branch heads')),
-         ] + templateopts,
-         _('[-ac] [-r STARTREV] [REV]...')),
-    "help": (help_, [], _('[TOPIC]')),
-    "identify|id":
-        (identify,
-         [('r', 'rev', '',
-           _('identify the specified revision'), _('REV')),
-          ('n', 'num', None, _('show local revision number')),
-          ('i', 'id', None, _('show global revision id')),
-          ('b', 'branch', None, _('show branch')),
-          ('t', 'tags', None, _('show tags')),
-          ('B', 'bookmarks', None, _('show bookmarks'))],
-         _('[-nibtB] [-r REV] [SOURCE]')),
-    "import|patch":
-        (import_,
-         [('p', 'strip', 1,
-           _('directory strip option for patch. This has the same '
-             'meaning as the corresponding patch option'),
-           _('NUM')),
-          ('b', 'base', '',
-           _('base path'), _('PATH')),
-          ('f', 'force', None,
-           _('skip check for outstanding uncommitted changes')),
-          ('', 'no-commit', None,
-           _("don't commit, just update the working directory")),
-          ('', 'exact', None,
-           _('apply patch to the nodes from which it was generated')),
-          ('', 'import-branch', None,
-           _('use any branch information in patch (implied by --exact)'))] +
-         commitopts + commitopts2 + similarityopts,
-         _('[OPTION]... PATCH...')),
-    "incoming|in":
-        (incoming,
-         [('f', 'force', None,
-           _('run even if remote repository is unrelated')),
-          ('n', 'newest-first', None, _('show newest record first')),
-          ('', 'bundle', '',
-           _('file to store the bundles into'), _('FILE')),
-          ('r', 'rev', [],
-           _('a remote changeset intended to be added'), _('REV')),
-          ('B', 'bookmarks', False, _("compare bookmarks")),
-          ('b', 'branch', [],
-           _('a specific branch you would like to pull'), _('BRANCH')),
-         ] + logopts + remoteopts + subrepoopts,
-         _('[-p] [-n] [-M] [-f] [-r REV]...'
-           ' [--bundle FILENAME] [SOURCE]')),
-    "^init":
-        (init,
-         remoteopts,
-         _('[-e CMD] [--remotecmd CMD] [DEST]')),
-    "locate":
-        (locate,
-         [('r', 'rev', '',
-           _('search the repository as it is in REV'), _('REV')),
-          ('0', 'print0', None,
-           _('end filenames with NUL, for use with xargs')),
-          ('f', 'fullpath', None,
-           _('print complete paths from the filesystem root')),
-         ] + walkopts,
-         _('[OPTION]... [PATTERN]...')),
-    "^log|history":
-        (log,
-         [('f', 'follow', None,
-           _('follow changeset history,'
-             ' or file history across copies and renames')),
-          ('', 'follow-first', None,
-           _('only follow the first parent of merge changesets')),
-          ('d', 'date', '',
-           _('show revisions matching date spec'), _('DATE')),
-          ('C', 'copies', None, _('show copied files')),
-          ('k', 'keyword', [],
-           _('do case-insensitive search for a given text'), _('TEXT')),
-          ('r', 'rev', [],
-           _('show the specified revision or range'), _('REV')),
-          ('', 'removed', None, _('include revisions where files were removed')),
-          ('m', 'only-merges', None, _('show only merges')),
-          ('u', 'user', [],
-           _('revisions committed by user'), _('USER')),
-          ('', 'only-branch', [],
-           _('show only changesets within the given named branch (DEPRECATED)'),
-           _('BRANCH')),
-          ('b', 'branch', [],
-           _('show changesets within the given named branch'), _('BRANCH')),
-          ('P', 'prune', [],
-           _('do not display revision or any of its ancestors'), _('REV')),
-         ] + logopts + walkopts,
-         _('[OPTION]... [FILE]')),
-    "manifest":
-        (manifest,
-         [('r', 'rev', '',
-           _('revision to display'), _('REV'))],
-         _('[-r REV]')),
-    "^merge":
-        (merge,
-         [('f', 'force', None, _('force a merge with outstanding changes')),
-          ('t', 'tool', '', _('specify merge tool')),
-          ('r', 'rev', '',
-           _('revision to merge'), _('REV')),
-          ('P', 'preview', None,
-           _('review revisions to merge (no merge is performed)'))],
-         _('[-P] [-f] [[-r] REV]')),
-    "outgoing|out":
-        (outgoing,
-         [('f', 'force', None,
-           _('run even when the destination is unrelated')),
-          ('r', 'rev', [],
-           _('a changeset intended to be included in the destination'),
-           _('REV')),
-          ('n', 'newest-first', None, _('show newest record first')),
-          ('B', 'bookmarks', False, _("compare bookmarks")),
-          ('b', 'branch', [],
-           _('a specific branch you would like to push'), _('BRANCH')),
-         ] + logopts + remoteopts + subrepoopts,
-         _('[-M] [-p] [-n] [-f] [-r REV]... [DEST]')),
-    "parents":
-        (parents,
-         [('r', 'rev', '',
-           _('show parents of the specified revision'), _('REV')),
-         ] + templateopts,
-         _('[-r REV] [FILE]')),
-    "paths": (paths, [], _('[NAME]')),
-    "^pull":
-        (pull,
-         [('u', 'update', None,
-           _('update to new branch head if changesets were pulled')),
-          ('f', 'force', None,
-           _('run even when remote repository is unrelated')),
-          ('r', 'rev', [],
-           _('a remote changeset intended to be added'), _('REV')),
-          ('B', 'bookmark', [], _("bookmark to pull"), _('BOOKMARK')),
-          ('b', 'branch', [],
-           _('a specific branch you would like to pull'), _('BRANCH')),
-         ] + remoteopts,
-         _('[-u] [-f] [-r REV]... [-e CMD] [--remotecmd CMD] [SOURCE]')),
-    "^push":
-        (push,
-         [('f', 'force', None, _('force push')),
-          ('r', 'rev', [],
-           _('a changeset intended to be included in the destination'),
-           _('REV')),
-          ('B', 'bookmark', [], _("bookmark to push"), _('BOOKMARK')),
-          ('b', 'branch', [],
-           _('a specific branch you would like to push'), _('BRANCH')),
-          ('', 'new-branch', False, _('allow pushing a new branch')),
-         ] + remoteopts,
-         _('[-f] [-r REV]... [-e CMD] [--remotecmd CMD] [DEST]')),
-    "recover": (recover, []),
-    "^remove|rm":
-        (remove,
-         [('A', 'after', None, _('record delete for missing files')),
-          ('f', 'force', None,
-           _('remove (and delete) file even if added or modified')),
-         ] + walkopts,
-         _('[OPTION]... FILE...')),
-    "rename|move|mv":
-        (rename,
-         [('A', 'after', None, _('record a rename that has already occurred')),
-          ('f', 'force', None,
-           _('forcibly copy over an existing managed file')),
-         ] + walkopts + dryrunopts,
-         _('[OPTION]... SOURCE... DEST')),
-    "resolve":
-        (resolve,
-         [('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, _('mark files as unresolved')),
-          ('t', 'tool', '', _('specify merge tool')),
-          ('n', 'no-status', None, _('hide status prefix'))]
-          + walkopts,
-          _('[OPTION]... [FILE]...')),
-    "revert":
-        (revert,
-         [('a', 'all', None, _('revert all changes when no arguments given')),
-          ('d', 'date', '',
-           _('tipmost revision matching date'), _('DATE')),
-          ('r', 'rev', '',
-           _('revert to the specified revision'), _('REV')),
-          ('', 'no-backup', None, _('do not save backup copies of files')),
-         ] + walkopts + dryrunopts,
-         _('[OPTION]... [-r REV] [NAME]...')),
-    "rollback": (rollback, dryrunopts),
-    "root": (root, []),
-    "^serve":
-        (serve,
-         [('A', 'accesslog', '',
-           _('name of access log file to write to'), _('FILE')),
-          ('d', 'daemon', None, _('run server in background')),
-          ('', 'daemon-pipefds', '',
-           _('used internally by daemon mode'), _('NUM')),
-          ('E', 'errorlog', '',
-           _('name of error log file to write to'), _('FILE')),
-          # use string type, then we can check if something was passed
-          ('p', 'port', '',
-           _('port to listen on (default: 8000)'), _('PORT')),
-          ('a', 'address', '',
-           _('address to listen on (default: all interfaces)'), _('ADDR')),
-          ('', 'prefix', '',
-           _('prefix path to serve from (default: server root)'), _('PREFIX')),
-          ('n', 'name', '',
-           _('name to show in web pages (default: working directory)'),
-           _('NAME')),
-          ('', 'web-conf', '',
-           _('name of the hgweb config file (see "hg help hgweb")'),
-           _('FILE')),
-          ('', 'webdir-conf', '',
-           _('name of the hgweb config file (DEPRECATED)'), _('FILE')),
-          ('', 'pid-file', '',
-           _('name of file to write process ID to'), _('FILE')),
-          ('', 'stdio', None, _('for remote clients')),
-          ('t', 'templates', '',
-           _('web templates to use'), _('TEMPLATE')),
-          ('', 'style', '',
-           _('template style to use'), _('STYLE')),
-          ('6', 'ipv6', None, _('use IPv6 in addition to IPv4')),
-          ('', 'certificate', '',
-           _('SSL certificate file'), _('FILE'))],
-         _('[OPTION]...')),
-    "showconfig|debugconfig":
-        (showconfig,
-         [('u', 'untrusted', None, _('show untrusted configuration options'))],
-         _('[-u] [NAME]...')),
-    "^summary|sum":
-        (summary,
-         [('', 'remote', None, _('check for push and pull'))], '[--remote]'),
-    "^status|st":
-        (status,
-         [('A', 'all', None, _('show status of all files')),
-          ('m', 'modified', None, _('show only modified files')),
-          ('a', 'added', None, _('show only added files')),
-          ('r', 'removed', None, _('show only removed files')),
-          ('d', 'deleted', None, _('show only deleted (but tracked) files')),
-          ('c', 'clean', None, _('show only files without changes')),
-          ('u', 'unknown', None, _('show only unknown (not tracked) files')),
-          ('i', 'ignored', None, _('show only ignored files')),
-          ('n', 'no-status', None, _('hide status prefix')),
-          ('C', 'copies', None, _('show source of copied files')),
-          ('0', 'print0', None,
-           _('end filenames with NUL, for use with xargs')),
-          ('', 'rev', [],
-           _('show difference from revision'), _('REV')),
-          ('', 'change', '',
-           _('list the changed files of a revision'), _('REV')),
-         ] + walkopts + subrepoopts,
-         _('[OPTION]... [FILE]...')),
-    "tag":
-        (tag,
-         [('f', 'force', None, _('force tag')),
-          ('l', 'local', None, _('make the tag local')),
-          ('r', 'rev', '',
-           _('revision to tag'), _('REV')),
-          ('', 'remove', None, _('remove a tag')),
-          # -l/--local is already there, commitopts cannot be used
-          ('e', 'edit', None, _('edit commit message')),
-          ('m', 'message', '',
-           _('use <text> as commit message'), _('TEXT')),
-         ] + commitopts2,
-         _('[-f] [-l] [-m TEXT] [-d DATE] [-u USER] [-r REV] NAME...')),
-    "tags": (tags, [], ''),
-    "tip":
-        (tip,
-         [('p', 'patch', None, _('show patch')),
-          ('g', 'git', None, _('use git extended diff format')),
-         ] + templateopts,
-         _('[-p] [-g]')),
-    "unbundle":
-        (unbundle,
-         [('u', 'update', None,
-           _('update to new branch head if changesets were unbundled'))],
-         _('[-u] FILE...')),
-    "^update|up|checkout|co":
-        (update,
-         [('C', 'clean', None, _('discard uncommitted changes (no backup)')),
-          ('c', 'check', None,
-           _('update across branches if no uncommitted changes')),
-          ('d', 'date', '',
-           _('tipmost revision matching date'), _('DATE')),
-          ('r', 'rev', '',
-           _('revision'), _('REV'))],
-         _('[-c] [-C] [-d DATE] [[-r] REV]')),
-    "verify": (verify, []),
-    "version": (version_, []),
-}
-
 norepo = ("clone init version help debugcommands debugcomplete"
-          " debugdate debuginstall debugfsinfo debugpushkey")
+          " debugdate debuginstall debugfsinfo debugpushkey debugwireargs"
+          " debugknown debuggetbundle debugbundle")
 optionalrepo = ("identify paths serve showconfig debugancestor debugdag"
-                " debugdata debugindex debugindexdot")
+                " debugdata debugindex debugindexdot debugrevlog")
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mercurial/commandserver.py	Sat Jun 18 17:03:01 2011 -0500
@@ -0,0 +1,213 @@
+# commandserver.py - communicate with Mercurial's API over a pipe
+#
+#  Copyright Matt Mackall <mpm@selenic.com>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2 or any later version.
+
+from i18n import _
+import struct
+import sys
+import dispatch, encoding, util
+
+logfile = None
+
+def log(*args):
+    if not logfile:
+        return
+
+    for a in args:
+        logfile.write(str(a))
+
+    logfile.flush()
+
+class channeledoutput(object):
+    """
+    Write data from in_ to out in the following format:
+
+    data length (unsigned int),
+    data
+    """
+    def __init__(self, in_, out, channel):
+        self.in_ = in_
+        self.out = out
+        self.channel = channel
+
+    def write(self, data):
+        if not data:
+            return
+        self.out.write(struct.pack('>cI', self.channel, len(data)))
+        self.out.write(data)
+        self.out.flush()
+
+    def __getattr__(self, attr):
+        if attr in ('isatty', 'fileno'):
+            raise AttributeError, attr
+        return getattr(self.in_, attr)
+
+class channeledinput(object):
+    """
+    Read data from in_.
+
+    Requests for input are written to out in the following format:
+    channel identifier - 'I' for plain input, 'L' line based (1 byte)
+    how many bytes to send at most (unsigned int),
+
+    The client replies with:
+    data length (unsigned int), 0 meaning EOF
+    data
+    """
+
+    maxchunksize = 4 * 1024
+
+    def __init__(self, in_, out, channel):
+        self.in_ = in_
+        self.out = out
+        self.channel = channel
+
+    def read(self, size=-1):
+        if size < 0:
+            # if we need to consume all the clients input, ask for 4k chunks
+            # so the pipe doesn't fill up risking a deadlock
+            size = self.maxchunksize
+            s = self._read(size, self.channel)
+            buf = s
+            while s:
+                buf += s
+                s = self._read(size, self.channel)
+
+            return buf
+        else:
+            return self._read(size, self.channel)
+
+    def _read(self, size, channel):
+        if not size:
+            return ''
+        assert size > 0
+
+        # tell the client we need at most size bytes
+        self.out.write(struct.pack('>cI', channel, size))
+        self.out.flush()
+
+        length = self.in_.read(4)
+        length = struct.unpack('>I', length)[0]
+        if not length:
+            return ''
+        else:
+            return self.in_.read(length)
+
+    def readline(self, size=-1):
+        if size < 0:
+            size = self.maxchunksize
+            s = self._read(size, 'L')
+            buf = s
+            # keep asking for more until there's either no more or
+            # we got a full line
+            while s and s[-1] != '\n':
+                buf += s
+                s = self._read(size, 'L')
+
+            return buf
+        else:
+            return self._read(size, 'L')
+
+    def __iter__(self):
+        return self
+
+    def next(self):
+        l = self.readline()
+        if not l:
+            raise StopIteration
+        return l
+
+    def __getattr__(self, attr):
+        if attr in ('isatty', 'fileno'):
+            raise AttributeError, attr
+        return getattr(self.in_, attr)
+
+class server(object):
+    """
+    Listens for commands on stdin, runs them and writes the output on a channel
+    based stream to stdout.
+    """
+    def __init__(self, ui, repo, mode):
+        self.ui = ui
+
+        logpath = ui.config("cmdserver", "log", None)
+        if logpath:
+            global logfile
+            if logpath == '-':
+                # write log on a special 'd'ebug channel
+                logfile = channeledoutput(sys.stdout, sys.stdout, 'd')
+            else:
+                logfile = open(logpath, 'a')
+
+        self.repo = repo
+
+        if mode == 'pipe':
+            self.cerr = channeledoutput(sys.stderr, sys.stdout, 'e')
+            self.cout = channeledoutput(sys.stdout, sys.stdout, 'o')
+            self.cin = channeledinput(sys.stdin, sys.stdout, 'I')
+            self.cresult = channeledoutput(sys.stdout, sys.stdout, 'r')
+
+            self.client = sys.stdin
+        else:
+            raise util.Abort(_('unknown mode %s') % mode)
+
+    def _read(self, size):
+        data = self.client.read(size)
+
+        # is the other end closed?
+        if not data:
+            raise EOFError()
+
+        return data
+
+    def runcommand(self):
+        """ reads a list of \0 terminated arguments, executes
+        and writes the return code to the result channel """
+
+        length = struct.unpack('>I', self._read(4))[0]
+        args = self._read(length).split('\0')
+
+        # copy the ui so changes to it don't persist between requests
+        req = dispatch.request(args, self.ui.copy(), self.repo, self.cin,
+                               self.cout, self.cerr)
+
+        ret = dispatch.dispatch(req) or 0 # might return None
+
+        self.cresult.write(struct.pack('>i', int(ret)))
+
+    def getencoding(self):
+        """ writes the current encoding to the result channel """
+        self.cresult.write(encoding.encoding)
+
+    def serveone(self):
+        cmd = self.client.readline()[:-1]
+        if cmd:
+            handler = self.capabilities.get(cmd)
+            if handler:
+                handler(self)
+            else:
+                # clients are expected to check what commands are supported by
+                # looking at the servers capabilities
+                raise util.Abort(_('unknown command %s') % cmd)
+
+        return cmd != ''
+
+    capabilities = {'runcommand'  : runcommand,
+                    'getencoding' : getencoding}
+
+    def serve(self):
+        self.cout.write('capabilities: %s' % ' '.join(self.capabilities.keys()))
+        self.cout.write('encoding: %s' % encoding.encoding)
+
+        try:
+            while self.serveone():
+                pass
+        except EOFError:
+            # we'll get here if the client disconnected while we were reading
+            # its request
+            return 1
+
+        return 0
--- a/mercurial/config.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/config.py	Sat Jun 18 17:03:01 2011 -0500
@@ -7,7 +7,7 @@
 
 from i18n import _
 import error, util
-import re, os
+import re, os, errno
 
 class sortdict(dict):
     'a simple sorted dictionary'
@@ -75,6 +75,7 @@
         itemre = re.compile(r'([^=\s][^=]*?)\s*=\s*(.*\S|)')
         contre = re.compile(r'\s+(\S|\S.*\S)\s*$')
         emptyre = re.compile(r'(;|#|\s*$)')
+        commentre = re.compile(r'(;|#)')
         unsetre = re.compile(r'%unset\s+(\S+)')
         includere = re.compile(r'%include\s+(\S|\S.*\S)\s*$')
         section = ""
@@ -85,6 +86,8 @@
         for l in data.splitlines(True):
             line += 1
             if cont:
+                if commentre.match(l):
+                    continue
                 m = contre.match(l)
                 if m:
                     if sections and section not in sections:
@@ -103,9 +106,10 @@
                     try:
                         include(inc, remap=remap, sections=sections)
                     except IOError, inst:
-                        raise error.ParseError(_("cannot include %s (%s)")
-                                               % (inc, inst.strerror),
-                                               "%s:%s" % (src, line))
+                        if inst.errno != errno.ENOENT:
+                            raise error.ParseError(_("cannot include %s (%s)")
+                                                   % (inc, inst.strerror),
+                                                   "%s:%s" % (src, line))
                 continue
             if emptyre.match(l):
                 continue
@@ -138,5 +142,5 @@
 
     def read(self, path, fp=None, sections=None, remap=None):
         if not fp:
-            fp = open(path)
+            fp = util.posixfile(path)
         self.parse(path, fp.read(), sections, remap, self.read)
--- a/mercurial/context.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/context.py	Sat Jun 18 17:03:01 2011 -0500
@@ -7,7 +7,8 @@
 
 from node import nullid, nullrev, short, hex
 from i18n import _
-import ancestor, bdiff, error, util, subrepo, patch, encoding
+import ancestor, bdiff, error, util, scmutil, subrepo, patch, encoding
+import match as matchmod
 import os, errno, stat
 
 propertycache = util.propertycache
@@ -116,6 +117,8 @@
         return self._repo.nodetags(self._node)
     def bookmarks(self):
         return self._repo.nodebookmarks(self._node)
+    def hidden(self):
+        return self._rev in self._repo.changelog.hiddenrevs
 
     def parents(self):
         """return contexts for each parent changeset"""
@@ -206,6 +209,12 @@
     def sub(self, path):
         return subrepo.subrepo(self, path)
 
+    def match(self, pats=[], include=None, exclude=None, default='glob'):
+        r = self._repo
+        return matchmod.match(r.root, r.getcwd(), pats,
+                              include, exclude, default,
+                              auditor=r.auditor, ctx=self)
+
     def diff(self, ctx2=None, match=None, **opts):
         """Returns a diff generator for the given contexts and matcher"""
         if ctx2 is None:
@@ -402,6 +411,15 @@
         return [filectx(self._repo, p, fileid=n, filelog=l)
                 for p, n, l in pl if n != nullid]
 
+    def p1(self):
+        return self.parents()[0]
+
+    def p2(self):
+        p = self.parents()
+        if len(p) == 2:
+            return p[1]
+        return filectx(self._repo, self._path, fileid=-1, filelog=self._filelog)
+
     def children(self):
         # hard for renames
         c = self._filelog.children(self._filenode)
@@ -652,6 +670,12 @@
 
         return man
 
+    def __iter__(self):
+        d = self._repo.dirstate
+        for f in d:
+            if d[f] != 'r':
+                yield f
+
     @propertycache
     def _status(self):
         return self._repo.status()[:4]
@@ -792,10 +816,11 @@
         try:
             rejected = []
             for f in list:
+                scmutil.checkportable(ui, join(f))
                 p = self._repo.wjoin(f)
                 try:
                     st = os.lstat(p)
-                except:
+                except OSError:
                     ui.warn(_("%s does not exist!\n") % join(f))
                     rejected.append(f)
                     continue
@@ -819,14 +844,16 @@
         finally:
             wlock.release()
 
-    def forget(self, list):
+    def forget(self, files):
         wlock = self._repo.wlock()
         try:
-            for f in list:
+            for f in files:
                 if self._repo.dirstate[f] != 'a':
-                    self._repo.ui.warn(_("%s not added!\n") % f)
+                    self._repo.dirstate.remove(f)
+                elif f not in self._repo.dirstate:
+                    self._repo.ui.warn(_("%s not tracked!\n") % f)
                 else:
-                    self._repo.dirstate.forget(f)
+                    self._repo.dirstate.drop(f)
         finally:
             wlock.release()
 
@@ -835,28 +862,6 @@
             *[p.rev() for p in self._parents]):
             yield changectx(self._repo, a)
 
-    def remove(self, list, unlink=False):
-        if unlink:
-            for f in list:
-                try:
-                    util.unlinkpath(self._repo.wjoin(f))
-                except OSError, inst:
-                    if inst.errno != errno.ENOENT:
-                        raise
-        wlock = self._repo.wlock()
-        try:
-            for f in list:
-                if unlink and os.path.lexists(self._repo.wjoin(f)):
-                    self._repo.ui.warn(_("%s still exists!\n") % f)
-                elif self._repo.dirstate[f] == 'a':
-                    self._repo.dirstate.forget(f)
-                elif f not in self._repo.dirstate:
-                    self._repo.ui.warn(_("%s not tracked!\n") % f)
-                else:
-                    self._repo.dirstate.remove(f)
-        finally:
-            wlock.release()
-
     def undelete(self, list):
         pctxs = self.parents()
         wlock = self._repo.wlock()
@@ -1012,9 +1017,7 @@
         self._filectxfn = filectxfn
 
         self._extra = extra and extra.copy() or {}
-        if 'branch' not in self._extra:
-            self._extra['branch'] = 'default'
-        elif self._extra.get('branch') == '':
+        if self._extra.get('branch', '') == '':
             self._extra['branch'] = 'default'
 
     def __str__(self):
--- a/mercurial/copies.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/copies.py	Sat Jun 18 17:03:01 2011 -0500
@@ -93,7 +93,7 @@
         return {}, {}
 
     # avoid silly behavior for parent -> working dir
-    if c2.node() is None and c1.node() == repo.dirstate.parents()[0]:
+    if c2.node() is None and c1.node() == repo.dirstate.p1():
         return repo.dirstate.copies(), {}
 
     limit = _findlimit(repo, c1.rev(), c2.rev())
@@ -134,7 +134,7 @@
             if f2r is None:
                 f2 = g2.next()
 
-            while 1:
+            while True:
                 f1r, f2r = f1.rev(), f2.rev()
                 if f1r > f2r:
                     f1 = g1.next()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mercurial/dagutil.py	Sat Jun 18 17:03:01 2011 -0500
@@ -0,0 +1,277 @@
+# dagutil.py - dag utilities for mercurial
+#
+# Copyright 2010 Benoit Boissinot <bboissin@gmail.com>
+# and Peter Arrenbrecht <peter@arrenbrecht.ch>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2 or any later version.
+
+from node import nullrev
+from i18n import _
+
+
+class basedag(object):
+    '''generic interface for DAGs
+
+    terms:
+    "ix" (short for index) identifies a nodes internally,
+    "id" identifies one externally.
+
+    All params are ixs unless explicitly suffixed otherwise.
+    Pluralized params are lists or sets.
+    '''
+
+    def __init__(self):
+        self._inverse = None
+
+    def nodeset(self):
+        '''set of all node idxs'''
+        raise NotImplementedError()
+
+    def heads(self):
+        '''list of head ixs'''
+        raise NotImplementedError()
+
+    def parents(self, ix):
+        '''list of parents ixs of ix'''
+        raise NotImplementedError()
+
+    def inverse(self):
+        '''inverse DAG, where parents becomes children, etc.'''
+        raise NotImplementedError()
+
+    def ancestorset(self, starts, stops=None):
+        '''
+        set of all ancestors of starts (incl), but stop walk at stops (excl)
+        '''
+        raise NotImplementedError()
+
+    def descendantset(self, starts, stops=None):
+        '''
+        set of all descendants of starts (incl), but stop walk at stops (excl)
+        '''
+        return self.inverse().ancestorset(starts, stops)
+
+    def headsetofconnecteds(self, ixs):
+        '''
+        subset of connected list of ixs so that no node has a descendant in it
+
+        By "connected list" we mean that if an ancestor and a descendant are in
+        the list, then so is at least one path connecting them.
+        '''
+        raise NotImplementedError()
+
+    def externalize(self, ix):
+        '''return a list of (or set if given a set) of node ids'''
+        return self._externalize(ix)
+
+    def externalizeall(self, ixs):
+        '''return a list of (or set if given a set) of node ids'''
+        ids = self._externalizeall(ixs)
+        if isinstance(ixs, set):
+            return set(ids)
+        return list(ids)
+
+    def internalize(self, id):
+        '''return a list of (or set if given a set) of node ixs'''
+        return self._internalize(id)
+
+    def internalizeall(self, ids, filterunknown=False):
+        '''return a list of (or set if given a set) of node ids'''
+        ixs = self._internalizeall(ids, filterunknown)
+        if isinstance(ids, set):
+            return set(ixs)
+        return list(ixs)
+
+
+class genericdag(basedag):
+    '''generic implementations for DAGs'''
+
+    def ancestorset(self, starts, stops=None):
+        stops = stops and set(stops) or set()
+        seen = set()
+        pending = list(starts)
+        while pending:
+            n = pending.pop()
+            if n not in seen and n not in stops:
+                seen.add(n)
+                pending.extend(self.parents(n))
+        return seen
+
+    def headsetofconnecteds(self, ixs):
+        hds = set(ixs)
+        if not hds:
+            return hds
+        for n in ixs:
+            for p in self.parents(n):
+                hds.discard(p)
+        assert hds
+        return hds
+
+
+class revlogbaseddag(basedag):
+    '''generic dag interface to a revlog'''
+
+    def __init__(self, revlog, nodeset):
+        basedag.__init__(self)
+        self._revlog = revlog
+        self._heads = None
+        self._nodeset = nodeset
+
+    def nodeset(self):
+        return self._nodeset
+
+    def heads(self):
+        if self._heads is None:
+            self._heads = self._getheads()
+        return self._heads
+
+    def _externalize(self, ix):
+        return self._revlog.index[ix][7]
+    def _externalizeall(self, ixs):
+        idx = self._revlog.index
+        return [idx[i][7] for i in ixs]
+
+    def _internalize(self, id):
+        ix = self._revlog.rev(id)
+        if ix == nullrev:
+            raise LookupError(id, self._revlog.indexfile, _('nullid'))
+        return ix
+    def _internalizeall(self, ids, filterunknown):
+        rl = self._revlog
+        if filterunknown:
+            return [r for r in map(rl.nodemap.get, ids)
+                    if r is not None and r != nullrev]
+        return map(self._internalize, ids)
+
+
+class revlogdag(revlogbaseddag):
+    '''dag interface to a revlog'''
+
+    def __init__(self, revlog):
+        revlogbaseddag.__init__(self, revlog, set(xrange(len(revlog))))
+
+    def _getheads(self):
+        return [r for r in self._revlog.headrevs() if r != nullrev]
+
+    def parents(self, ix):
+        rlog = self._revlog
+        idx = rlog.index
+        revdata = idx[ix]
+        prev = revdata[5]
+        if prev != nullrev:
+            prev2 = revdata[6]
+            if prev2 == nullrev:
+                return [prev]
+            return [prev, prev2]
+        prev2 = revdata[6]
+        if prev2 != nullrev:
+            return [prev2]
+        return []
+
+    def inverse(self):
+        if self._inverse is None:
+            self._inverse = inverserevlogdag(self)
+        return self._inverse
+
+    def ancestorset(self, starts, stops=None):
+        rlog = self._revlog
+        idx = rlog.index
+        stops = stops and set(stops) or set()
+        seen = set()
+        pending = list(starts)
+        while pending:
+            rev = pending.pop()
+            if rev not in seen and rev not in stops:
+                seen.add(rev)
+                revdata = idx[rev]
+                for i in [5, 6]:
+                    prev = revdata[i]
+                    if prev != nullrev:
+                        pending.append(prev)
+        return seen
+
+    def headsetofconnecteds(self, ixs):
+        if not ixs:
+            return set()
+        rlog = self._revlog
+        idx = rlog.index
+        headrevs = set(ixs)
+        for rev in ixs:
+            revdata = idx[rev]
+            for i in [5, 6]:
+                prev = revdata[i]
+                if prev != nullrev:
+                    headrevs.discard(prev)
+        assert headrevs
+        return headrevs
+
+    def linearize(self, ixs):
+        '''linearize and topologically sort a list of revisions
+
+        The linearization process tries to create long runs of revs where
+        a child rev comes immediately after its first parent. This is done by
+        visiting the heads of the given revs in inverse topological order,
+        and for each visited rev, visiting its second parent, then its first
+        parent, then adding the rev itself to the output list.
+        '''
+        sorted = []
+        visit = list(self.headsetofconnecteds(ixs))
+        visit.sort(reverse=True)
+        finished = set()
+
+        while visit:
+            cur = visit.pop()
+            if cur < 0:
+                cur = -cur - 1
+                if cur not in finished:
+                    sorted.append(cur)
+                    finished.add(cur)
+            else:
+                visit.append(-cur - 1)
+                visit += [p for p in self.parents(cur)
+                          if p in ixs and p not in finished]
+        assert len(sorted) == len(ixs)
+        return sorted
+
+
+class inverserevlogdag(revlogbaseddag, genericdag):
+    '''inverse of an existing revlog dag; see revlogdag.inverse()'''
+
+    def __init__(self, orig):
+        revlogbaseddag.__init__(self, orig._revlog, orig._nodeset)
+        self._orig = orig
+        self._children = {}
+        self._roots = []
+        self._walkfrom = len(self._revlog) - 1
+
+    def _walkto(self, walkto):
+        rev = self._walkfrom
+        cs = self._children
+        roots = self._roots
+        idx = self._revlog.index
+        while rev >= walkto:
+            data = idx[rev]
+            isroot = True
+            for prev in [data[5], data[6]]: # parent revs
+                if prev != nullrev:
+                    cs.setdefault(prev, []).append(rev)
+                    isroot = False
+            if isroot:
+                roots.append(rev)
+            rev -= 1
+        self._walkfrom = rev - 1
+
+    def _getheads(self):
+        self._walkto(nullrev)
+        return self._roots
+
+    def parents(self, ix):
+        if ix is None:
+            return []
+        if ix <= self._walkfrom:
+            self._walkto(ix)
+        return self._children.get(ix, [])
+
+    def inverse(self):
+        return self._orig
--- a/mercurial/dirstate.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/dirstate.py	Sat Jun 18 17:03:01 2011 -0500
@@ -7,7 +7,7 @@
 
 from node import nullid
 from i18n import _
-import util, ignore, osutil, parsers, encoding
+import scmutil, util, ignore, osutil, parsers, encoding
 import struct, os, stat, errno
 import cStringIO
 
@@ -49,6 +49,7 @@
         self._rootdir = os.path.join(root, '')
         self._dirty = False
         self._dirtypl = False
+        self._lastnormaltime = None
         self._ui = ui
 
     @propertycache
@@ -73,7 +74,7 @@
     @propertycache
     def _branch(self):
         try:
-            return self._opener("branch").read().strip() or "default"
+            return self._opener.read("branch").strip() or "default"
         except IOError:
             return "default"
 
@@ -137,7 +138,7 @@
                     p = self._join(x)
                     if os.path.islink(p):
                         return 'l'
-                    if util.is_exec(p):
+                    if util.isexec(p):
                         return 'x'
                     return ''
                 return f
@@ -152,7 +153,7 @@
             def f(x):
                 if 'l' in fallback(x):
                     return 'l'
-                if util.is_exec(self._join(x)):
+                if util.isexec(self._join(x)):
                     return 'x'
                 return ''
             return f
@@ -202,6 +203,12 @@
     def parents(self):
         return [self._validate(p) for p in self._pl]
 
+    def p1(self):
+        return self._validate(self._pl[0])
+
+    def p2(self):
+        return self._validate(self._pl[1])
+
     def branch(self):
         return encoding.tolocal(self._branch)
 
@@ -213,13 +220,13 @@
         if branch in ['tip', '.', 'null']:
             raise util.Abort(_('the name \'%s\' is reserved') % branch)
         self._branch = encoding.fromlocal(branch)
-        self._opener("branch", "w").write(self._branch + '\n')
+        self._opener.write("branch", self._branch + '\n')
 
     def _read(self):
         self._map = {}
         self._copymap = {}
         try:
-            st = self._opener("dirstate").read()
+            st = self._opener.read("dirstate")
         except IOError, err:
             if err.errno != errno.ENOENT:
                 raise
@@ -236,6 +243,7 @@
                 "_ignore"):
             if a in self.__dict__:
                 delattr(self, a)
+        self._lastnormaltime = None
         self._dirty = False
 
     def copy(self, source, dest):
@@ -261,9 +269,7 @@
     def _addpath(self, f, check=False):
         oldstate = self[f]
         if check or oldstate == "r":
-            if '\r' in f or '\n' in f:
-                raise util.Abort(
-                    _("'\\n' and '\\r' disallowed in filenames: %r") % f)
+            scmutil.checkfilename(f)
             if f in self._dirs:
                 raise util.Abort(_('directory %r already in dirstate') % f)
             # shadows
@@ -281,9 +287,15 @@
         self._dirty = True
         self._addpath(f)
         s = os.lstat(self._join(f))
-        self._map[f] = ('n', s.st_mode, s.st_size, int(s.st_mtime))
+        mtime = int(s.st_mtime)
+        self._map[f] = ('n', s.st_mode, s.st_size, mtime)
         if f in self._copymap:
             del self._copymap[f]
+        if mtime > self._lastnormaltime:
+            # Remember the most recent modification timeslot for status(),
+            # to make sure we won't miss future size-preserving file content
+            # modifications that happen within the same timeslot.
+            self._lastnormaltime = mtime
 
     def normallookup(self, f):
         '''Mark a file normal, but possibly dirty.'''
@@ -353,14 +365,11 @@
         if f in self._copymap:
             del self._copymap[f]
 
-    def forget(self, f):
-        '''Forget a file.'''
+    def drop(self, f):
+        '''Drop a file from the dirstate'''
         self._dirty = True
-        try:
-            self._droppath(f)
-            del self._map[f]
-        except KeyError:
-            self._ui.warn(_("not in dirstate: %s\n") % f)
+        self._droppath(f)
+        del self._map[f]
 
     def _normalize(self, path, isknown):
         normed = os.path.normcase(path)
@@ -397,6 +406,7 @@
             delattr(self, "_dirs")
         self._copymap = {}
         self._pl = [nullid, nullid]
+        self._lastnormaltime = None
         self._dirty = True
 
     def rebuild(self, parent, files):
@@ -444,6 +454,7 @@
             write(f)
         st.write(cs.getvalue())
         st.rename()
+        self._lastnormaltime = None
         self._dirty = self._dirtypl = False
 
     def _dirignore(self, f):
@@ -680,6 +691,7 @@
                 # lines are an expansion of "islink => checklink"
                 # where islink means "is this a link?" and checklink
                 # means "can we check links?".
+                mtime = int(st.st_mtime)
                 if (size >= 0 and
                     (size != st.st_size
                      or ((mode ^ st.st_mode) & 0100 and self._checkexec))
@@ -687,9 +699,15 @@
                     or size == -2 # other parent
                     or fn in self._copymap):
                     madd(fn)
-                elif (time != int(st.st_mtime)
+                elif (mtime != time
                       and (mode & lnkkind != lnkkind or self._checklink)):
                     ladd(fn)
+                elif mtime == self._lastnormaltime:
+                    # fn may have been changed in the same timeslot without
+                    # changing its size. This can happen if we quickly do
+                    # multiple commits in a single transaction.
+                    # Force lookup, so we don't miss such a racy file change.
+                    ladd(fn)
                 elif listclean:
                     cadd(fn)
             elif state == 'm':
--- a/mercurial/discovery.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/discovery.py	Sat Jun 18 17:03:01 2011 -0500
@@ -7,184 +7,59 @@
 
 from node import nullid, short
 from i18n import _
-import util, error
+import util, setdiscovery, treediscovery
 
 def findcommonincoming(repo, remote, heads=None, force=False):
-    """Return a tuple (common, missing roots, heads) used to identify
-    missing nodes from remote.
-
-    If a list of heads is specified, return only nodes which are heads
-    or ancestors of these heads.
-    """
-    m = repo.changelog.nodemap
-    search = []
-    fetch = set()
-    seen = set()
-    seenbranch = set()
-    base = set()
-
-    if not heads:
-        heads = remote.heads()
-
-    if repo.changelog.tip() == nullid:
-        base.add(nullid)
-        if heads != [nullid]:
-            return [nullid], [nullid], list(heads)
-        return [nullid], [], []
-
-    # assume we're closer to the tip than the root
-    # and start by examining the heads
-    repo.ui.status(_("searching for changes\n"))
-
-    unknown = []
-    for h in heads:
-        if h not in m:
-            unknown.append(h)
-        else:
-            base.add(h)
-
-    heads = unknown
-    if not unknown:
-        return list(base), [], []
-
-    req = set(unknown)
-    reqcnt = 0
+    """Return a tuple (common, anyincoming, heads) used to identify the common
+    subset of nodes between repo and remote.
 
-    # search through remote branches
-    # a 'branch' here is a linear segment of history, with four parts:
-    # head, root, first parent, second parent
-    # (a branch always has two parents (or none) by definition)
-    unknown = remote.branches(unknown)
-    while unknown:
-        r = []
-        while unknown:
-            n = unknown.pop(0)
-            if n[0] in seen:
-                continue
+    "common" is a list of (at least) the heads of the common subset.
+    "anyincoming" is testable as a boolean indicating if any nodes are missing
+      locally. If remote does not support getbundle, this actually is a list of
+      roots of the nodes that would be incoming, to be supplied to
+      changegroupsubset. No code except for pull should be relying on this fact
+      any longer.
+    "heads" is either the supplied heads, or else the remote's heads.
 
-            repo.ui.debug("examining %s:%s\n"
-                          % (short(n[0]), short(n[1])))
-            if n[0] == nullid: # found the end of the branch
-                pass
-            elif n in seenbranch:
-                repo.ui.debug("branch already found\n")
-                continue
-            elif n[1] and n[1] in m: # do we know the base?
-                repo.ui.debug("found incomplete branch %s:%s\n"
-                              % (short(n[0]), short(n[1])))
-                search.append(n[0:2]) # schedule branch range for scanning
-                seenbranch.add(n)
-            else:
-                if n[1] not in seen and n[1] not in fetch:
-                    if n[2] in m and n[3] in m:
-                        repo.ui.debug("found new changeset %s\n" %
-                                      short(n[1]))
-                        fetch.add(n[1]) # earliest unknown
-                    for p in n[2:4]:
-                        if p in m:
-                            base.add(p) # latest known
+    If you pass heads and they are all known locally, the reponse lists justs
+    these heads in "common" and in "heads".
 
-                for p in n[2:4]:
-                    if p not in req and p not in m:
-                        r.append(p)
-                        req.add(p)
-            seen.add(n[0])
+    Please use findcommonoutgoing to compute the set of outgoing nodes to give
+    extensions a good hook into outgoing.
+    """
+
+    if not remote.capable('getbundle'):
+        return treediscovery.findcommonincoming(repo, remote, heads, force)
 
-        if r:
-            reqcnt += 1
-            repo.ui.progress(_('searching'), reqcnt, unit=_('queries'))
-            repo.ui.debug("request %d: %s\n" %
-                        (reqcnt, " ".join(map(short, r))))
-            for p in xrange(0, len(r), 10):
-                for b in remote.branches(r[p:p + 10]):
-                    repo.ui.debug("received %s:%s\n" %
-                                  (short(b[0]), short(b[1])))
-                    unknown.append(b)
+    if heads:
+        allknown = True
+        nm = repo.changelog.nodemap
+        for h in heads:
+            if nm.get(h) is None:
+                allknown = False
+                break
+        if allknown:
+            return (heads, False, heads)
 
-    # do binary search on the branches we found
-    while search:
-        newsearch = []
-        reqcnt += 1
-        repo.ui.progress(_('searching'), reqcnt, unit=_('queries'))
-        for n, l in zip(search, remote.between(search)):
-            l.append(n[1])
-            p = n[0]
-            f = 1
-            for i in l:
-                repo.ui.debug("narrowing %d:%d %s\n" % (f, len(l), short(i)))
-                if i in m:
-                    if f <= 2:
-                        repo.ui.debug("found new branch changeset %s\n" %
-                                          short(p))
-                        fetch.add(p)
-                        base.add(i)
-                    else:
-                        repo.ui.debug("narrowed branch search to %s:%s\n"
-                                      % (short(p), short(i)))
-                        newsearch.append((p, i))
-                    break
-                p, f = i, f * 2
-            search = newsearch
-
-    # sanity check our fetch list
-    for f in fetch:
-        if f in m:
-            raise error.RepoError(_("already have changeset ")
-                                  + short(f[:4]))
+    res = setdiscovery.findcommonheads(repo.ui, repo, remote,
+                                       abortwhenunrelated=not force)
+    common, anyinc, srvheads = res
+    return (list(common), anyinc, heads or list(srvheads))
 
-    base = list(base)
-    if base == [nullid]:
-        if force:
-            repo.ui.warn(_("warning: repository is unrelated\n"))
-        else:
-            raise util.Abort(_("repository is unrelated"))
-
-    repo.ui.debug("found new changesets starting at " +
-                 " ".join([short(f) for f in fetch]) + "\n")
-
-    repo.ui.progress(_('searching'), None)
-    repo.ui.debug("%d total queries\n" % reqcnt)
-
-    return base, list(fetch), heads
-
-def findoutgoing(repo, remote, base=None, remoteheads=None, force=False):
-    """Return list of nodes that are roots of subsets not in remote
+def findcommonoutgoing(repo, other, onlyheads=None, force=False, commoninc=None):
+    '''Return a tuple (common, anyoutgoing, heads) used to identify the set
+    of nodes present in repo but not in other.
 
-    If base dict is specified, assume that these nodes and their parents
-    exist on the remote side.
-    If remotehead is specified, assume it is the list of the heads from
-    the remote repository.
-    """
-    if base is None:
-        base = findcommonincoming(repo, remote, heads=remoteheads,
-                                  force=force)[0]
-    else:
-        base = list(base)
-
-    repo.ui.debug("common changesets up to "
-                  + " ".join(map(short, base)) + "\n")
-
-    remain = set(repo.changelog.nodemap)
+    If onlyheads is given, only nodes ancestral to nodes in onlyheads (inclusive)
+    are included. If you already know the local repo's heads, passing them in
+    onlyheads is faster than letting them be recomputed here.
 
-    # prune everything remote has from the tree
-    remain.remove(nullid)
-    remove = base
-    while remove:
-        n = remove.pop(0)
-        if n in remain:
-            remain.remove(n)
-            for p in repo.changelog.parents(n):
-                remove.append(p)
+    If commoninc is given, it must the the result of a prior call to
+    findcommonincoming(repo, other, force) to avoid recomputing it here.
 
-    # find every node whose parents have been pruned
-    subset = []
-    # find every remote head that will get new children
-    for n in remain:
-        p1, p2 = repo.changelog.parents(n)
-        if p1 not in remain and p2 not in remain:
-            subset.append(n)
-
-    return subset
+    The returned tuple is meant to be passed to changelog.findmissing.'''
+    common, _any, _hds = commoninc or findcommonincoming(repo, other, force=force)
+    return (common, onlyheads or repo.heads())
 
 def prepush(repo, remote, force, revs, newbranch):
     '''Analyze the local and remote repositories and determine which
@@ -200,15 +75,15 @@
     changegroup is a readable file-like object whose read() returns
     successive changegroup chunks ready to be sent over the wire and
     remoteheads is the list of remote heads.'''
-    remoteheads = remote.heads()
-    common, inc, rheads = findcommonincoming(repo, remote, heads=remoteheads,
-                                             force=force)
+    commoninc = findcommonincoming(repo, remote, force=force)
+    common, revs = findcommonoutgoing(repo, remote, onlyheads=revs,
+                                      commoninc=commoninc, force=force)
+    _common, inc, remoteheads = commoninc
 
     cl = repo.changelog
-    update = findoutgoing(repo, remote, common, remoteheads)
-    outg, bases, heads = cl.nodesbetween(update, revs)
+    outg = cl.findmissing(common, revs)
 
-    if not bases:
+    if not outg:
         repo.ui.status(_("no changes found\n"))
         return None, 1
 
@@ -284,22 +159,23 @@
             newhs = set(newmap[branch])
             oldhs = set(oldmap[branch])
             if len(newhs) > len(oldhs):
+                dhs = list(newhs - oldhs)
                 if error is None:
-                    if branch:
-                        error = _("push creates new remote heads "
-                                  "on branch '%s'!") % branch
+                    if branch != 'default':
+                        error = _("push creates new remote head %s "
+                                  "on branch '%s'!") % (short(dhs[0]), branch)
                     else:
-                        error = _("push creates new remote heads!")
+                        error = _("push creates new remote head %s!"
+                                  ) % short(dhs[0])
                     if branch in unsynced:
                         hint = _("you should pull and merge or "
                                  "use push -f to force")
                     else:
                         hint = _("did you forget to merge? "
                                  "use push -f to force")
-                if branch:
-                    repo.ui.debug("new remote heads on branch '%s'\n" % branch)
-                for h in (newhs - oldhs):
-                    repo.ui.debug("new remote head %s\n" % short(h))
+                repo.ui.note("new remote heads on branch '%s'\n" % branch)
+                for h in dhs:
+                    repo.ui.note("new remote head %s\n" % short(h))
         if error:
             raise util.Abort(error, hint=hint)
 
@@ -309,8 +185,7 @@
 
     if revs is None:
         # use the fast path, no race possible on push
-        nodes = repo.changelog.findmissing(common)
-        cg = repo._changegroup(nodes, 'push')
+        cg = repo._changegroup(outg, 'push')
     else:
-        cg = repo.changegroupsubset(update, revs, 'push')
+        cg = repo.getbundle('push', heads=revs, common=common)
     return cg, remoteheads
--- a/mercurial/dispatch.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/dispatch.py	Sat Jun 18 17:03:01 2011 -0500
@@ -11,34 +11,63 @@
 import cmdutil, encoding
 import ui as uimod
 
+class request(object):
+    def __init__(self, args, ui=None, repo=None, fin=None, fout=None, ferr=None):
+        self.args = args
+        self.ui = ui
+        self.repo = repo
+
+        # input/output/error streams
+        self.fin = fin
+        self.fout = fout
+        self.ferr = ferr
+
 def run():
     "run the command in sys.argv"
-    sys.exit(dispatch(sys.argv[1:]))
+    sys.exit(dispatch(request(sys.argv[1:])))
 
-def dispatch(args):
-    "run the command specified in args"
+def dispatch(req):
+    "run the command specified in req.args"
+    if req.ferr:
+        ferr = req.ferr
+    elif req.ui:
+        ferr = req.ui.ferr
+    else:
+        ferr = sys.stderr
+
     try:
-        u = uimod.ui()
-        if '--traceback' in args:
-            u.setconfig('ui', 'traceback', 'on')
+        if not req.ui:
+            req.ui = uimod.ui()
+        if '--traceback' in req.args:
+            req.ui.setconfig('ui', 'traceback', 'on')
+
+        # set ui streams from the request
+        if req.fin:
+            req.ui.fin = req.fin
+        if req.fout:
+            req.ui.fout = req.fout
+        if req.ferr:
+            req.ui.ferr = req.ferr
     except util.Abort, inst:
-        sys.stderr.write(_("abort: %s\n") % inst)
+        ferr.write(_("abort: %s\n") % inst)
         if inst.hint:
-            sys.stderr.write(_("(%s)\n") % inst.hint)
+            ferr.write(_("(%s)\n") % inst.hint)
         return -1
     except error.ParseError, inst:
         if len(inst.args) > 1:
-            sys.stderr.write(_("hg: parse error at %s: %s\n") %
+            ferr.write(_("hg: parse error at %s: %s\n") %
                              (inst.args[1], inst.args[0]))
         else:
-            sys.stderr.write(_("hg: parse error: %s\n") % inst.args[0])
+            ferr.write(_("hg: parse error: %s\n") % inst.args[0])
         return -1
-    return _runcatch(u, args)
 
-def _runcatch(ui, args):
+    return _runcatch(req)
+
+def _runcatch(req):
     def catchterm(*args):
         raise error.SignalInterrupt
 
+    ui = req.ui
     try:
         for name in 'SIGBREAK', 'SIGHUP', 'SIGTERM':
             num = getattr(signal, name, None)
@@ -50,17 +79,17 @@
     try:
         try:
             # enter the debugger before command execution
-            if '--debugger' in args:
+            if '--debugger' in req.args:
                 ui.warn(_("entering debugger - "
                         "type c to continue starting hg or h for help\n"))
                 pdb.set_trace()
             try:
-                return _dispatch(ui, args)
+                return _dispatch(req)
             finally:
                 ui.flush()
         except:
             # enter the debugger when we hit an exception
-            if '--debugger' in args:
+            if '--debugger' in req.args:
                 traceback.print_exc()
                 pdb.post_mortem(sys.exc_info()[2])
             ui.traceback()
@@ -90,7 +119,7 @@
     except error.CommandError, inst:
         if inst.args[0]:
             ui.warn(_("hg %s: %s\n") % (inst.args[0], inst.args[1]))
-            commands.help_(ui, inst.args[0])
+            commands.help_(ui, inst.args[0], full=False, command=True)
         else:
             ui.warn(_("hg: %s\n") % inst.args[1])
             commands.help_(ui, 'shortlist')
@@ -133,7 +162,8 @@
         elif hasattr(inst, "reason"):
             try: # usually it is in the form (errno, strerror)
                 reason = inst.reason.args[1]
-            except: # it might be anything, for example a string
+            except (AttributeError, IndexError):
+                 # it might be anything, for example a string
                 reason = inst.reason
             ui.warn(_("abort: error: %s\n") % reason)
         elif hasattr(inst, "args") and inst.args[0] == errno.EPIPE:
@@ -181,10 +211,21 @@
 
     return -1
 
-def aliasargs(fn):
-    if hasattr(fn, 'args'):
-        return fn.args
-    return []
+def aliasargs(fn, givenargs):
+    args = getattr(fn, 'args', [])
+    if args and givenargs:
+        cmd = ' '.join(map(util.shellquote, args))
+
+        nums = []
+        def replacer(m):
+            num = int(m.group(1)) - 1
+            nums.append(num)
+            return givenargs[num]
+        cmd = re.sub(r'\$(\d+|\$)', replacer, cmd)
+        givenargs = [x for i, x in enumerate(givenargs)
+                     if i not in nums]
+        args = shlex.split(cmd)
+    return args + givenargs
 
 class cmdalias(object):
     def __init__(self, name, definition, cmdtable):
@@ -235,7 +276,7 @@
                 replace['0'] = self.name
                 replace['@'] = ' '.join(args)
                 cmd = util.interpolate(r'\$', replace, cmd, escape_prefix=True)
-                return util.system(cmd, environ=env)
+                return util.system(cmd, environ=env, out=ui.fout)
             self.fn = fn
             return
 
@@ -262,7 +303,7 @@
             else:
                 self.fn, self.opts = tableentry
 
-            self.args = aliasargs(self.fn) + args
+            self.args = aliasargs(self.fn, args)
             if cmd not in commands.norepo.split(' '):
                 self.norepo = False
             if self.help.startswith("hg " + cmd):
@@ -329,7 +370,7 @@
         aliases, entry = cmdutil.findcmd(cmd, commands.table,
                                      ui.config("ui", "strict"))
         cmd = aliases[0]
-        args = aliasargs(entry[0]) + args
+        args = aliasargs(entry[0], args)
         defaults = ui.config("defaults", cmd)
         if defaults:
             args = map(util.expandpath, shlex.split(defaults)) + args
@@ -474,7 +515,10 @@
     os.chdir(cwd)
 
 _loaded = set()
-def _dispatch(ui, args):
+def _dispatch(req):
+    args = req.args
+    ui = req.ui
+
     shellaliasfn = _checkshellalias(ui, args)
     if shellaliasfn:
         return shellaliasfn()
@@ -549,16 +593,20 @@
         atexit.register(print_time)
 
     if options['verbose'] or options['debug'] or options['quiet']:
-        ui.setconfig('ui', 'verbose', str(bool(options['verbose'])))
-        ui.setconfig('ui', 'debug', str(bool(options['debug'])))
-        ui.setconfig('ui', 'quiet', str(bool(options['quiet'])))
+        for ui_ in (ui, lui):
+            ui_.setconfig('ui', 'verbose', str(bool(options['verbose'])))
+            ui_.setconfig('ui', 'debug', str(bool(options['debug'])))
+            ui_.setconfig('ui', 'quiet', str(bool(options['quiet'])))
     if options['traceback']:
-        ui.setconfig('ui', 'traceback', 'on')
+        for ui_ in (ui, lui):
+            ui_.setconfig('ui', 'traceback', 'on')
     if options['noninteractive']:
-        ui.setconfig('ui', 'interactive', 'off')
+        for ui_ in (ui, lui):
+            ui_.setconfig('ui', 'interactive', 'off')
 
     if cmdoptions.get('insecure', False):
-        ui.setconfig('web', 'cacerts', '')
+        for ui_ in (ui, lui):
+            ui_.setconfig('web', 'cacerts', '')
 
     if options['help']:
         return commands.help_(ui, cmd, options['version'])
@@ -570,25 +618,31 @@
     repo = None
     cmdpats = args[:]
     if cmd not in commands.norepo.split():
-        try:
-            repo = hg.repository(ui, path=path)
-            ui = repo.ui
-            if not repo.local():
-                raise util.Abort(_("repository '%s' is not local") % path)
-            ui.setconfig("bundle", "mainreporoot", repo.root)
-        except error.RequirementError:
-            raise
-        except error.RepoError:
-            if cmd not in commands.optionalrepo.split():
-                if args and not path: # try to infer -R from command args
-                    repos = map(cmdutil.findrepo, args)
-                    guess = repos[0]
-                    if guess and repos.count(guess) == len(repos):
-                        return _dispatch(ui, ['--repository', guess] + fullargs)
-                if not path:
-                    raise error.RepoError(_("There is no Mercurial repository"
-                                      " here (.hg not found)"))
+        # use the repo from the request only if we don't have -R
+        if not rpath:
+            repo = req.repo
+
+        if not repo:
+            try:
+                repo = hg.repository(ui, path=path)
+                ui = repo.ui
+                if not repo.local():
+                    raise util.Abort(_("repository '%s' is not local") % path)
+                ui.setconfig("bundle", "mainreporoot", repo.root)
+            except error.RequirementError:
                 raise
+            except error.RepoError:
+                if cmd not in commands.optionalrepo.split():
+                    if args and not path: # try to infer -R from command args
+                        repos = map(cmdutil.findrepo, args)
+                        guess = repos[0]
+                        if guess and repos.count(guess) == len(repos):
+                            req.args = ['--repository', guess] + fullargs
+                            return _dispatch(req)
+                    if not path:
+                        raise error.RepoError(_("no repository found in %r"
+                                                " (.hg not found)") % os.getcwd())
+                    raise
         args.insert(0, repo)
     elif rpath:
         ui.warn(_("warning: --repository ignored\n"))
--- a/mercurial/encoding.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/encoding.py	Sat Jun 18 17:03:01 2011 -0500
@@ -148,3 +148,17 @@
         return sum([w(c) in wide and 2 or 1 for c in d])
     return len(d)
 
+def lower(s):
+    "best-effort encoding-aware case-folding of local string s"
+    try:
+        if isinstance(s, localstr):
+            u = s._utf8.decode("utf-8")
+        else:
+            u = s.decode(encoding, encodingmode)
+
+        lu = u.lower()
+        if u == lu:
+            return s # preserve localstring
+        return lu.encode(encoding)
+    except UnicodeError:
+        return s.lower() # we don't know how to fold this except in ASCII
--- a/mercurial/extensions.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/extensions.py	Sat Jun 18 17:03:01 2011 -0500
@@ -6,12 +6,12 @@
 # GNU General Public License version 2 or any later version.
 
 import imp, os
-import util, cmdutil, help, error
+import util, cmdutil, error
 from i18n import _, gettext
 
 _extensions = {}
 _order = []
-_ignore = ['hbisect', 'bookmarks']
+_ignore = ['hbisect', 'bookmarks', 'parentrevspec']
 
 def extensions():
     for name in _order:
@@ -21,13 +21,17 @@
 
 def find(name):
     '''return module with given extension name'''
+    mod = None
     try:
-        return _extensions[name]
+        mod =  _extensions[name]
     except KeyError:
         for k, v in _extensions.iteritems():
             if k.endswith('.' + name) or k.endswith('/' + name):
-                return v
+                mod = v
+                break
+    if not mod:
         raise KeyError(name)
+    return mod
 
 def loadpath(path, module_name):
     module_name = module_name.replace('.', '_')
@@ -209,6 +213,38 @@
         exts[name] = path
     return exts
 
+def _moduledoc(file):
+    '''return the top-level python documentation for the given file
+
+    Loosely inspired by pydoc.source_synopsis(), but rewritten to
+    handle triple quotes and to return the whole text instead of just
+    the synopsis'''
+    result = []
+
+    line = file.readline()
+    while line[:1] == '#' or not line.strip():
+        line = file.readline()
+        if not line:
+            break
+
+    start = line[:3]
+    if start == '"""' or start == "'''":
+        line = line[3:]
+        while line:
+            if line.rstrip().endswith(start):
+                line = line.split(start)[0]
+                if line:
+                    result.append(line)
+                break
+            elif not line:
+                return None # unmatched delimiter
+            result.append(line)
+            line = file.readline()
+    else:
+        return None
+
+    return ''.join(result)
+
 def _disabledhelp(path):
     '''retrieve help synopsis of a disabled extension (without importing)'''
     try:
@@ -216,7 +252,7 @@
     except IOError:
         return
     else:
-        doc = help.moduledoc(file)
+        doc = _moduledoc(file)
         file.close()
 
     if doc: # extracting localized synopsis
@@ -225,28 +261,38 @@
         return _('(no help text available)')
 
 def disabled():
-    '''find disabled extensions from hgext
-    returns a dict of {name: desc}, and the max name length'''
+    '''find disabled extensions from hgext. returns a dict of {name: desc}'''
+    try:
+        from hgext import __index__
+        return dict((name, gettext(desc))
+                    for name, desc in __index__.docs.iteritems()
+                    if name not in _order)
+    except ImportError:
+        pass
 
     paths = _disabledpaths()
     if not paths:
-        return None, 0
+        return None
 
     exts = {}
-    maxlength = 0
     for name, path in paths.iteritems():
         doc = _disabledhelp(path)
-        if not doc:
-            continue
+        if doc:
+            exts[name] = doc
 
-        exts[name] = doc
-        if len(name) > maxlength:
-            maxlength = len(name)
-
-    return exts, maxlength
+    return exts
 
 def disabledext(name):
     '''find a specific disabled extension from hgext. returns desc'''
+    try:
+        from hgext import __index__
+        if name in _order:  # enabled
+            return
+        else:
+            return gettext(__index__.docs.get(name))
+    except ImportError:
+        pass
+
     paths = _disabledpaths()
     if name in paths:
         return _disabledhelp(paths[name])
@@ -297,13 +343,11 @@
     raise error.UnknownCommand(cmd)
 
 def enabled():
-    '''return a dict of {name: desc} of extensions, and the max name length'''
+    '''return a dict of {name: desc} of extensions'''
     exts = {}
-    maxlength = 0
     for ename, ext in extensions():
         doc = (gettext(ext.__doc__) or _('(no help text available)'))
         ename = ename.split('.')[-1]
-        maxlength = max(len(ename), maxlength)
         exts[ename] = doc.splitlines()[0].strip()
 
-    return exts, maxlength
+    return exts
--- a/mercurial/filelog.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/filelog.py	Sat Jun 18 17:03:01 2011 -0500
@@ -6,17 +6,28 @@
 # GNU General Public License version 2 or any later version.
 
 import revlog
+import re
 
+_mdre = re.compile('\1\n')
 def _parsemeta(text):
-    if not text.startswith('\1\n'):
-        return {}
-    s = text.index('\1\n', 2)
-    mt = text[2:s]
-    m = {}
-    for l in mt.splitlines():
+    """return (metadatadict, keylist, metadatasize)"""
+    # text can be buffer, so we can't use .startswith or .index
+    if text[:2] != '\1\n':
+        return None, None, None
+    s = _mdre.search(text, 2).start()
+    mtext = text[2:s]
+    meta = {}
+    keys = []
+    for l in mtext.splitlines():
         k, v = l.split(": ", 1)
-        m[k] = v
-    return m
+        meta[k] = v
+        keys.append(k)
+    return meta, keys, (s + 2)
+
+def _packmeta(meta, keys=None):
+    if not keys:
+        keys = sorted(meta.iterkeys())
+    return "".join("%s: %s\n" % (k, meta[k]) for k in keys)
 
 class filelog(revlog.revlog):
     def __init__(self, opener, path):
@@ -32,15 +43,14 @@
 
     def add(self, text, meta, transaction, link, p1=None, p2=None):
         if meta or text.startswith('\1\n'):
-            mt = ["%s: %s\n" % (k, v) for k, v in sorted(meta.iteritems())]
-            text = "\1\n%s\1\n%s" % ("".join(mt), text)
+            text = "\1\n%s\1\n%s" % (_packmeta(meta), text)
         return self.addrevision(text, transaction, link, p1, p2)
 
     def renamed(self, node):
         if self.parents(node)[0] != revlog.nullid:
             return False
         t = self.revision(node)
-        m = _parsemeta(t)
+        m = _parsemeta(t)[0]
         if m and "copy" in m:
             return (m["copy"], revlog.bin(m["copyrev"]))
         return False
@@ -77,3 +87,6 @@
             return t2 != text
 
         return True
+
+    def _file(self, f):
+        return filelog(self.opener, f)
--- a/mercurial/filemerge.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/filemerge.py	Sat Jun 18 17:03:01 2011 -0500
@@ -29,12 +29,12 @@
         k = _toolstr(ui, tool, kn)
         if not k:
             continue
-        p = util.lookup_reg(k, _toolstr(ui, tool, "regname"))
+        p = util.lookupreg(k, _toolstr(ui, tool, "regname"))
         if p:
-            p = util.find_exe(p + _toolstr(ui, tool, "regappend"))
+            p = util.findexe(p + _toolstr(ui, tool, "regappend"))
             if p:
                 return p
-    return util.find_exe(_toolstr(ui, tool, "executable", tool))
+    return util.findexe(_toolstr(ui, tool, "executable", tool))
 
 def _picktool(repo, ui, path, binary, symlink):
     def check(tool, pat, symlink, binary):
@@ -113,14 +113,14 @@
 
 def _matcheol(file, origfile):
     "Convert EOL markers in a file to match origfile"
-    tostyle = _eoltype(open(origfile, "rb").read())
+    tostyle = _eoltype(util.readfile(origfile))
     if tostyle:
-        data = open(file, "rb").read()
+        data = util.readfile(file)
         style = _eoltype(data)
         if style:
             newdata = data.replace(style, tostyle)
             if newdata != data:
-                open(file, "wb").write(newdata)
+                util.writefile(file, newdata)
 
 def filemerge(repo, mynode, orig, fcd, fco, fca):
     """perform a 3-way merge in the working directory
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mercurial/fileset.py	Sat Jun 18 17:03:01 2011 -0500
@@ -0,0 +1,428 @@
+# fileset.py - file set queries for mercurial
+#
+# Copyright 2010 Matt Mackall <mpm@selenic.com>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2 or any later version.
+
+import parser, error, util, merge, re
+from i18n import _
+
+elements = {
+    "(": (20, ("group", 1, ")"), ("func", 1, ")")),
+    "-": (5, ("negate", 19), ("minus", 5)),
+    "not": (10, ("not", 10)),
+    "!": (10, ("not", 10)),
+    "and": (5, None, ("and", 5)),
+    "&": (5, None, ("and", 5)),
+    "or": (4, None, ("or", 4)),
+    "|": (4, None, ("or", 4)),
+    "+": (4, None, ("or", 4)),
+    ",": (2, None, ("list", 2)),
+    ")": (0, None, None),
+    "symbol": (0, ("symbol",), None),
+    "string": (0, ("string",), None),
+    "end": (0, None, None),
+}
+
+keywords = set(['and', 'or', 'not'])
+
+globchars = ".*{}[]?/\\"
+
+def tokenize(program):
+    pos, l = 0, len(program)
+    while pos < l:
+        c = program[pos]
+        if c.isspace(): # skip inter-token whitespace
+            pass
+        elif c in "(),-|&+!": # handle simple operators
+            yield (c, None, pos)
+        elif (c in '"\'' or c == 'r' and
+              program[pos:pos + 2] in ("r'", 'r"')): # handle quoted strings
+            if c == 'r':
+                pos += 1
+                c = program[pos]
+                decode = lambda x: x
+            else:
+                decode = lambda x: x.decode('string-escape')
+            pos += 1
+            s = pos
+            while pos < l: # find closing quote
+                d = program[pos]
+                if d == '\\': # skip over escaped characters
+                    pos += 2
+                    continue
+                if d == c:
+                    yield ('string', decode(program[s:pos]), s)
+                    break
+                pos += 1
+            else:
+                raise error.ParseError(_("unterminated string"), s)
+        elif c.isalnum() or c in globchars or ord(c) > 127:
+            # gather up a symbol/keyword
+            s = pos
+            pos += 1
+            while pos < l: # find end of symbol
+                d = program[pos]
+                if not (d.isalnum() or d in globchars or ord(d) > 127):
+                    break
+                pos += 1
+            sym = program[s:pos]
+            if sym in keywords: # operator keywords
+                yield (sym, None, s)
+            else:
+                yield ('symbol', sym, s)
+            pos -= 1
+        else:
+            raise error.ParseError(_("syntax error"), pos)
+        pos += 1
+    yield ('end', None, pos)
+
+parse = parser.parser(tokenize, elements).parse
+
+def getstring(x, err):
+    if x and (x[0] == 'string' or x[0] == 'symbol'):
+        return x[1]
+    raise error.ParseError(err)
+
+def getset(mctx, x):
+    if not x:
+        raise error.ParseError(_("missing argument"))
+    return methods[x[0]](mctx, *x[1:])
+
+def stringset(mctx, x):
+    m = mctx.matcher([x])
+    return [f for f in mctx.subset if m(f)]
+
+def andset(mctx, x, y):
+    return getset(mctx.narrow(getset(mctx, x)), y)
+
+def orset(mctx, x, y):
+    # needs optimizing
+    xl = getset(mctx, x)
+    yl = getset(mctx, y)
+    return xl + [f for f in yl if f not in xl]
+
+def notset(mctx, x):
+    s = set(getset(mctx, x))
+    return [r for r in mctx.subset if r not in s]
+
+def listset(mctx, a, b):
+    raise error.ParseError(_("can't use a list in this context"))
+
+def modified(mctx, x):
+    """``modified()``
+    File that is modified according to status.
+    """
+    getargs(x, 0, 0, _("modified takes no arguments"))
+    s = mctx.status()[0]
+    return [f for f in mctx.subset if f in s]
+
+def added(mctx, x):
+    """``added()``
+    File that is added according to status.
+    """
+    getargs(x, 0, 0, _("added takes no arguments"))
+    s = mctx.status()[1]
+    return [f for f in mctx.subset if f in s]
+
+def removed(mctx, x):
+    """``removed()``
+    File that is removed according to status.
+    """
+    getargs(x, 0, 0, _("removed takes no arguments"))
+    s = mctx.status()[2]
+    return [f for f in mctx.subset if f in s]
+
+def deleted(mctx, x):
+    """``deleted()``
+    File that is deleted according to status.
+    """
+    getargs(x, 0, 0, _("deleted takes no arguments"))
+    s = mctx.status()[3]
+    return [f for f in mctx.subset if f in s]
+
+def unknown(mctx, x):
+    """``unknown()``
+    File that is unknown according to status. These files will only be
+    considered if this predicate is used.
+    """
+    getargs(x, 0, 0, _("unknown takes no arguments"))
+    s = mctx.status()[4]
+    return [f for f in mctx.subset if f in s]
+
+def ignored(mctx, x):
+    """``ignored()``
+    File that is ignored according to status. These files will only be
+    considered if this predicate is used.
+    """
+    getargs(x, 0, 0, _("ignored takes no arguments"))
+    s = mctx.status()[5]
+    return [f for f in mctx.subset if f in s]
+
+def clean(mctx, x):
+    """``clean()``
+    File that is clean according to status.
+    """
+    getargs(x, 0, 0, _("clean takes no arguments"))
+    s = mctx.status()[6]
+    return [f for f in mctx.subset if f in s]
+
+def func(mctx, a, b):
+    if a[0] == 'symbol' and a[1] in symbols:
+        return symbols[a[1]](mctx, b)
+    raise error.ParseError(_("not a function: %s") % a[1])
+
+def getlist(x):
+    if not x:
+        return []
+    if x[0] == 'list':
+        return getlist(x[1]) + [x[2]]
+    return [x]
+
+def getargs(x, min, max, err):
+    l = getlist(x)
+    if len(l) < min or len(l) > max:
+        raise error.ParseError(err)
+    return l
+
+def binary(mctx, x):
+    """``binary()``
+    File that appears to be binary (contails NUL bytes).
+    """
+    getargs(x, 0, 0, _("binary takes no arguments"))
+    return [f for f in mctx.subset if util.binary(mctx.ctx[f].data())]
+
+def exec_(mctx, x):
+    """``exec()``
+    File that is marked as executable.
+    """
+    getargs(x, 0, 0, _("exec takes no arguments"))
+    return [f for f in mctx.subset if mctx.ctx.flags(f) == 'x']
+
+def symlink(mctx, x):
+    """``symlink()``
+    File that is marked as a symlink.
+    """
+    getargs(x, 0, 0, _("symlink takes no arguments"))
+    return [f for f in mctx.subset if mctx.ctx.flags(f) == 'l']
+
+def resolved(mctx, x):
+    """``resolved()``
+    File that is marked resolved according to the resolve state.
+    """
+    getargs(x, 0, 0, _("resolved takes no arguments"))
+    if mctx.ctx.rev() is not None:
+        return []
+    ms = merge.mergestate(mctx.ctx._repo)
+    return [f for f in mctx.subset if f in ms and ms[f] == 'r']
+
+def unresolved(mctx, x):
+    """``unresolved()``
+    File that is marked unresolved according to the resolve state.
+    """
+    getargs(x, 0, 0, _("unresolved takes no arguments"))
+    if mctx.ctx.rev() is not None:
+        return []
+    ms = merge.mergestate(mctx.ctx._repo)
+    return [f for f in mctx.subset if f in ms and ms[f] == 'u']
+
+def hgignore(mctx, x):
+    """``resolved()``
+    File that matches the active .hgignore pattern.
+    """
+    getargs(x, 0, 0, _("hgignore takes no arguments"))
+    ignore = mctx.ctx._repo.dirstate._ignore
+    return [f for f in mctx.subset if ignore(f)]
+
+def grep(mctx, x):
+    """``grep(regex)``
+    File contains the given regular expression.
+    """
+    pat = getstring(x, _("grep requires a pattern"))
+    r = re.compile(pat)
+    return [f for f in mctx.subset if r.search(mctx.ctx[f].data())]
+
+_units = dict(k=2**10, K=2**10, kB=2**10, KB=2**10,
+              M=2**20, MB=2**20, G=2**30, GB=2**30,
+              kiB=10**3, MiB=10**6, GiB=10**9)
+
+def _sizetoint(s):
+    try:
+        s = s.strip()
+        for k, v in _units.items():
+            if s.endswith(k):
+                return int(float(s[:-len(k)]) * v)
+        return int(s)
+    except ValueError:
+        raise
+        raise error.ParseError(_("couldn't parse size"), s)
+
+def _sizetomax(s):
+    try:
+        s = s.strip()
+        for k, v in _units.items():
+            if s.endswith(k):
+                # max(4k) = 5k - 1, max(4.5k) = 4.6k - 1
+                n = s[:-len(k)]
+                inc = 1.0
+                if "." in n:
+                    inc /= 10 ** len(n.split(".")[1])
+                return int((float(n) + inc) * v) - 1
+        # no extension, this is a precise value
+        return int(s)
+    except ValueError:
+        raise
+        raise error.ParseError(_("couldn't parse size"), s)
+
+def size(mctx, x):
+    """``size(expression)``
+    File size matches the given expression. Examples:
+
+    - 1k (files from 1024 to 2047 bytes)
+    - 1.0kiB (files from 1000 to 1100 bytes)
+    - < 20k (files less than 20480 bytes)
+    - >= .5MiB (files at least 500000 bytes)
+    - 4k - 1MB (files from 4096 bytes to 1048576 bytes)
+    """
+
+    expr = getstring(x, _("grep requires a pattern")).strip()
+    if '-' in expr: # do we have a range?
+        a, b = expr.split('-', 1)
+        a = _sizetoint(a)
+        b = _sizetoint(b)
+        m = lambda x: x >= a and x <= b
+    elif expr.startswith("<="):
+        a = _sizetoint(expr[2:])
+        m = lambda x: x <= a
+    elif expr.startswith("<"):
+        a = _sizetoint(expr[1:])
+        m = lambda x: x < a
+    elif expr.startswith(">="):
+        a = _sizetoint(expr[2:])
+        m = lambda x: x >= a
+    elif expr.startswith(">"):
+        a = _sizetoint(expr[1:])
+        m = lambda x: x > a
+    elif expr[0].isdigit or expr[0] == '.':
+        a = _sizetoint(expr)
+        b = _sizetomax(expr)
+        m = lambda x: x >=a and x <= b
+    else:
+        raise error.ParseError(_("couldn't parse size"), expr)
+
+    return [f for f in mctx.subset if m(mctx.ctx[f].size())]
+
+def encoding(mctx, x):
+    """``encoding(name)``
+    File can be successfully decoded with the given character
+    encoding. May not be useful for encodings other than ASCII and
+    UTF-8.
+    """
+
+    enc = getstring(x, _("encoding requires an encoding name"))
+
+    s = []
+    for f in mctx.subset:
+        d = mctx.ctx[f].data()
+        try:
+            d.decode(enc)
+        except LookupError:
+            raise util.Abort(_("unknown encoding '%s'") % enc)
+        except UnicodeDecodeError:
+            continue
+        s.append(f)
+
+    return s
+
+def copied(mctx, x):
+    """``copied()``
+    File that is recorded as being copied.
+    """
+    s = []
+    for f in mctx.subset:
+        p = mctx.ctx[f].parents()
+        if p and p[0].path() != f:
+            s.append(f)
+    return s
+
+symbols = {
+    'added': added,
+    'binary': binary,
+    'clean': clean,
+    'copied': copied,
+    'deleted': deleted,
+    'encoding': encoding,
+    'exec': exec_,
+    'grep': grep,
+    'ignored': ignored,
+    'hgignore': hgignore,
+    'modified': modified,
+    'removed': removed,
+    'resolved': resolved,
+    'size': size,
+    'symlink': symlink,
+    'unknown': unknown,
+    'unresolved': unresolved,
+}
+
+methods = {
+    'string': stringset,
+    'symbol': stringset,
+    'and': andset,
+    'or': orset,
+    'list': listset,
+    'group': getset,
+    'not': notset,
+    'func': func,
+}
+
+class matchctx(object):
+    def __init__(self, ctx, subset=None, status=None):
+        self.ctx = ctx
+        self.subset = subset
+        self._status = status
+    def status(self):
+        return self._status
+    def matcher(self, patterns):
+        return self.ctx.match(patterns)
+    def filter(self, files):
+        return [f for f in files if f in self.subset]
+    def narrow(self, files):
+        return matchctx(self.ctx, self.filter(files), self._status)
+
+def _intree(funcs, tree):
+    if isinstance(tree, tuple):
+        if tree[0] == 'func' and tree[1][0] == 'symbol':
+            if tree[1][1] in funcs:
+                return True
+        for s in tree[1:]:
+            if _intree(funcs, s):
+                return True
+    return False
+
+def getfileset(ctx, expr):
+    tree, pos = parse(expr)
+    if (pos != len(expr)):
+        raise error.ParseError("invalid token", pos)
+
+    # do we need status info?
+    if _intree(['modified', 'added', 'removed', 'deleted',
+                'unknown', 'ignored', 'clean'], tree):
+        unknown = _intree(['unknown'], tree)
+        ignored = _intree(['ignored'], tree)
+
+        r = ctx._repo
+        status = r.status(ctx.p1(), ctx,
+                          unknown=unknown, ignored=ignored, clean=True)
+        subset = []
+        for c in status:
+            subset.extend(c)
+    else:
+        status = None
+        subset = ctx.walk(ctx.match([]))
+
+    return getset(matchctx(ctx, subset, status), tree)
+
+# tell hggettext to extract docstrings from these functions:
+i18nfunctions = symbols.values()
--- a/mercurial/graphmod.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/graphmod.py	Sat Jun 18 17:03:01 2011 -0500
@@ -21,40 +21,39 @@
 
 CHANGESET = 'C'
 
-def revisions(repo, start, stop):
+def dagwalker(repo, revs):
     """cset DAG generator yielding (id, CHANGESET, ctx, [parentids]) tuples
 
-    This generator function walks through the revision history from revision
-    start to revision stop (which must be less than or equal to start). It
-    returns a tuple for each node. The node and parent ids are arbitrary
-    integers which identify a node in the context of the graph returned.
+    This generator function walks through revisions (which should be ordered
+    from bigger to lower). It returns a tuple for each node. The node and parent
+    ids are arbitrary integers which identify a node in the context of the graph
+    returned.
     """
-    cur = start
-    while cur >= stop:
-        ctx = repo[cur]
-        parents = set([p.rev() for p in ctx.parents() if p.rev() != nullrev])
-        yield (cur, CHANGESET, ctx, sorted(parents))
-        cur -= 1
+    if not revs:
+        return
 
-def filerevs(repo, path, start, stop, limit=None):
-    """file cset DAG generator yielding (id, CHANGESET, ctx, [parentids]) tuples
+    cl = repo.changelog
+    lowestrev = min(revs)
+    gpcache = {}
 
-    This generator function walks through the revision history of a single
-    file from revision start down to revision stop.
-    """
-    filerev = len(repo.file(path)) - 1
-    rev = stop + 1
-    count = 0
-    while filerev >= 0 and rev > stop:
-        fctx = repo.filectx(path, fileid=filerev)
-        parents = set([f.linkrev() for f in fctx.parents() if f.path() == path])
-        rev = fctx.rev()
-        if rev <= start:
-            yield (rev, CHANGESET, fctx.changectx(), sorted(parents))
-            count += 1
-            if count == limit:
-                break
-        filerev -= 1
+    knownrevs = set(revs)
+    for rev in revs:
+        ctx = repo[rev]
+        parents = sorted(set([p.rev() for p in ctx.parents()
+                              if p.rev() in knownrevs]))
+        mpars = [p.rev() for p in ctx.parents() if
+                 p.rev() != nullrev and p.rev() not in parents]
+
+        for mpar in mpars:
+            gp = gpcache.get(mpar)
+            if gp is None:
+                gp = gpcache[mpar] = grandparent(cl, lowestrev, revs, mpar)
+            if not gp:
+                parents.append(mpar)
+            else:
+                parents.extend(g for g in gp if g not in parents)
+
+        yield (ctx.rev(), CHANGESET, ctx, parents)
 
 def nodes(repo, nodes):
     """cset DAG generator yielding (id, CHANGESET, ctx, [parentids]) tuples
@@ -120,3 +119,21 @@
         # Yield and move on
         yield (cur, type, data, (col, color), edges)
         seen = next
+
+def grandparent(cl, lowestrev, roots, head):
+    """Return all ancestors of head in roots which revision is
+    greater or equal to lowestrev.
+    """
+    pending = set([head])
+    seen = set()
+    kept = set()
+    llowestrev = max(nullrev, lowestrev)
+    while pending:
+        r = pending.pop()
+        if r >= llowestrev and r not in seen:
+            if r in roots:
+                kept.add(r)
+            else:
+                pending.update([p for p in cl.parentrevs(r)])
+            seen.add(r)
+    return sorted(kept)
--- a/mercurial/hbisect.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/hbisect.py	Sat Jun 18 17:03:01 2011 -0500
@@ -54,10 +54,10 @@
             return badrev, None
         return badrev, ancestors
 
-    good = 0
+    good = False
     badrev, ancestors = buildancestors(state['bad'], state['good'])
     if not ancestors: # looking for bad to good transition?
-        good = 1
+        good = True
         badrev, ancestors = buildancestors(state['good'], state['bad'])
     bad = changelog.node(badrev)
     if not ancestors: # now we're confused
--- a/mercurial/help.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/help.py	Sat Jun 18 17:03:01 2011 -0500
@@ -7,45 +7,14 @@
 
 from i18n import gettext, _
 import sys, os
-import extensions
-
-
-def moduledoc(file):
-    '''return the top-level python documentation for the given file
-
-    Loosely inspired by pydoc.source_synopsis(), but rewritten to
-    handle triple quotes and to return the whole text instead of just
-    the synopsis'''
-    result = []
-
-    line = file.readline()
-    while line[:1] == '#' or not line.strip():
-        line = file.readline()
-        if not line:
-            break
+import extensions, revset, fileset, templatekw, templatefilters
+import util
 
-    start = line[:3]
-    if start == '"""' or start == "'''":
-        line = line[3:]
-        while line:
-            if line.rstrip().endswith(start):
-                line = line.split(start)[0]
-                if line:
-                    result.append(line)
-                break
-            elif not line:
-                return None # unmatched delimiter
-            result.append(line)
-            line = file.readline()
-    else:
-        return None
-
-    return ''.join(result)
-
-def listexts(header, exts, maxlength, indent=1):
+def listexts(header, exts, indent=1):
     '''return a text listing of the given extensions'''
     if not exts:
         return ''
+    maxlength = max(len(e) for e in exts)
     result = '\n%s\n\n' % header
     for name, desc in sorted(exts.iteritems()):
         result += '%s%-*s %s\n' % (' ' * indent, maxlength + 2,
@@ -54,13 +23,8 @@
 
 def extshelp():
     doc = loaddoc('extensions')()
-
-    exts, maxlength = extensions.enabled()
-    doc += listexts(_('enabled extensions:'), exts, maxlength)
-
-    exts, maxlength = extensions.disabled()
-    doc += listexts(_('disabled extensions:'), exts, maxlength)
-
+    doc += listexts(_('enabled extensions:'), extensions.enabled())
+    doc += listexts(_('disabled extensions:'), extensions.disabled())
     return doc
 
 def loaddoc(topic):
@@ -79,14 +43,14 @@
                 break
 
         path = os.path.join(docdir, topic + ".txt")
-        doc = gettext(open(path).read())
+        doc = gettext(util.readfile(path))
         for rewriter in helphooks.get(topic, []):
             doc = rewriter(topic, doc)
         return doc
 
     return loader
 
-helptable = [
+helptable = sorted([
     (["config", "hgrc"], _("Configuration Files"), loaddoc('config')),
     (["dates"], _("Date Formats"), loaddoc('dates')),
     (["patterns"], _("File Name Patterns"), loaddoc('patterns')),
@@ -97,21 +61,49 @@
     (['mrevs', 'multirevs'], _('Specifying Multiple Revisions'),
      loaddoc('multirevs')),
     (['revset', 'revsets'], _("Specifying Revision Sets"), loaddoc('revsets')),
+    (['fileset', 'filesets'], _("Specifying File Sets"), loaddoc('filesets')),
     (['diffs'], _('Diff Formats'), loaddoc('diffs')),
     (['merge-tools'], _('Merge Tools'), loaddoc('merge-tools')),
     (['templating', 'templates'], _('Template Usage'),
      loaddoc('templates')),
     (['urls'], _('URL Paths'), loaddoc('urls')),
     (["extensions"], _("Using additional features"), extshelp),
-    (["subrepo", "subrepos"], _("Subrepositories"), loaddoc('subrepos')),
-    (["hgweb"], _("Configuring hgweb"), loaddoc('hgweb')),
-    (["glossary"], _("Glossary"), loaddoc('glossary')),
-]
+   (["subrepo", "subrepos"], _("Subrepositories"), loaddoc('subrepos')),
+   (["hgweb"], _("Configuring hgweb"), loaddoc('hgweb')),
+   (["glossary"], _("Glossary"), loaddoc('glossary')),
+   (["hgignore", "ignore"], _("syntax for Mercurial ignore files"),
+    loaddoc('hgignore')),
+])
 
 # Map topics to lists of callable taking the current topic help and
 # returning the updated version
-helphooks = {
-}
+helphooks = {}
 
 def addtopichook(topic, rewriter):
     helphooks.setdefault(topic, []).append(rewriter)
+
+def makeitemsdoc(topic, doc, marker, items):
+    """Extract docstring from the items key to function mapping, build a
+    .single documentation block and use it to overwrite the marker in doc
+    """
+    entries = []
+    for name in sorted(items):
+        text = (items[name].__doc__ or '').rstrip()
+        if not text:
+            continue
+        text = gettext(text)
+        lines = text.splitlines()
+        lines[1:] = [('  ' + l.strip()) for l in lines[1:]]
+        entries.append('\n'.join(lines))
+    entries = '\n\n'.join(entries)
+    return doc.replace(marker, entries)
+
+def addtopicsymbols(topic, marker, symbols):
+    def add(topic, doc):
+        return makeitemsdoc(topic, doc, marker, symbols)
+    addtopichook(topic, add)
+
+addtopicsymbols('filesets', '.. predicatesmarker', fileset.symbols)
+addtopicsymbols('revsets', '.. predicatesmarker', revset.symbols)
+addtopicsymbols('templates', '.. keywordsmarker', templatekw.keywords)
+addtopicsymbols('templates', '.. filtersmarker', templatefilters.filters)
--- a/mercurial/help/config.txt	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/help/config.txt	Sat Jun 18 17:03:01 2011 -0500
@@ -1,57 +1,1288 @@
-Mercurial reads configuration data from several files, if they exist.
-Below we list the most specific file first.
+The Mercurial system uses a set of configuration files to control
+aspects of its behavior.
 
-On Windows, these configuration files are read:
+The configuration files use a simple ini-file format. A configuration
+file consists of sections, led by a ``[section]`` header and followed
+by ``name = value`` entries::
 
-- ``<repo>\.hg\hgrc``
-- ``%USERPROFILE%\.hgrc``
-- ``%USERPROFILE%\mercurial.ini``
-- ``%HOME%\.hgrc``
-- ``%HOME%\mercurial.ini``
-- ``C:\mercurial\mercurial.ini`` (unless regkey or hgrc.d\ or mercurial.ini found)
-- ``HKEY_LOCAL_MACHINE\SOFTWARE\Mercurial`` (unless hgrc.d\ or mercurial.ini found)
-- ``<hg.exe-dir>\hgrc.d\*.rc`` (unless mercurial.ini found)
-- ``<hg.exe-dir>\mercurial.ini``
+  [ui]
+  username = Firstname Lastname <firstname.lastname@example.net>
+  verbose = True
 
-On Unix, these files are read:
+The above entries will be referred to as ``ui.username`` and
+``ui.verbose``, respectively. See the Syntax section below.
 
-- ``<repo>/.hg/hgrc``
-- ``$HOME/.hgrc``
-- ``/etc/mercurial/hgrc``
-- ``/etc/mercurial/hgrc.d/*.rc``
-- ``<install-root>/etc/mercurial/hgrc``
-- ``<install-root>/etc/mercurial/hgrc.d/*.rc``
+Files
+-----
 
+Mercurial reads configuration data from several files, if they exist.
 These files do not exist by default and you will have to create the
 appropriate configuration files yourself: global configuration like
 the username setting is typically put into
 ``%USERPROFILE%\mercurial.ini`` or ``$HOME/.hgrc`` and local
 configuration is put into the per-repository ``<repo>/.hg/hgrc`` file.
 
-If there is a per-repository configuration file which is not owned by
-the active user, Mercurial will warn you that the file is skipped::
+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 earlier paths override later
+ones.
+
+| (Unix, Windows) ``<repo>/.hg/hgrc``
+
+    Per-repository configuration options that only apply in a
+    particular repository. This file is not version-controlled, and
+    will not get transferred during a "clone" operation. Options in
+    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.
+
+| (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) ``<install-dir>\Mercurial.ini`` **or**
+| (Windows) ``<install-dir>\hgrc.d\*.rc`` **or**
+| (Windows) ``HKEY_LOCAL_MACHINE\SOFTWARE\Mercurial``
+
+    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.  Mercurial checks each of these locations in the specified
+    order until one or more configuration files are detected.  If the
+    pywin32 extensions are not installed, Mercurial will only look for
+    site-wide configuration in ``C:\Mercurial\Mercurial.ini``.
+
+Syntax
+------
+
+A configuration file consists of sections, led by a ``[section]`` header
+and followed by ``name = value`` entries (sometimes called
+``configuration keys``)::
+
+    [spam]
+    eggs=ham
+    green=
+       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.
+
+Configuration keys can be set multiple times, in which case Mercurial
+will use the value that was configured last. As an example::
+
+    [spam]
+    eggs=large
+    ham=serrano
+    eggs=small
+
+This would set the configuration key named ``eggs`` to ``small``.
+
+It is also possible to define a section multiple times. A section can
+be redefined on the same and/or on different configuration files. For
+example::
+
+    [foo]
+    eggs=large
+    ham=serrano
+    eggs=small
+
+    [bar]
+    eggs=ham
+    green=
+       eggs
+
+    [foo]
+    ham=prosciutto
+    eggs=medium
+    bread=toasted
+
+This would set the ``eggs``, ``ham``, and ``bread`` configuration keys
+of the ``foo`` section to ``medium``, ``prosciutto``, and ``toasted``,
+respectively. As you can see there only thing that matters is the last
+value that was set for each of the configuration keys.
+
+If a configuration key is set multiple times in different
+configuration files the final value will depend on the order in which
+the different configuration files are read, with settings from earlier
+paths overriding later ones as described on the ``Files`` section
+above.
+
+A line of the form ``%include file`` will include ``file`` into the
+current configuration file. The inclusion is recursive, which means
+that included files can include other files. Filenames are relative to
+the configuration file in which the ``%include`` directive is found.
+Environment variables and ``~user`` constructs are expanded in
+``file``. This lets you do something like::
+
+  %include ~/.hgrc.d/$HOST.rc
+
+to include a different configuration file on each computer you use.
+
+A line with ``%unset name`` will remove ``name`` from the current
+section, if it has been set previously.
+
+The values are either free-form text strings, lists of text strings,
+or Boolean values. Boolean values can be set to true using any of "1",
+"yes", "true", or "on" and to false using "0", "no", "false", or "off"
+(all case insensitive).
+
+List values are separated by whitespace or comma, except when values are
+placed in double quotation marks::
+
+  allow_read = "John Doe, PhD", brian, betty
+
+Quotation marks can be escaped by prefixing them with a backslash. Only
+quotation marks at the beginning of a word is counted as a quotation
+(e.g., ``foo"bar baz`` is the list of ``foo"bar`` and ``baz``).
+
+Sections
+--------
+
+This section describes the different sections that may appear in a
+Mercurial configuration file, the purpose of each section, its possible
+keys, and their possible values.
+
+``alias``
+"""""""""
 
-  not trusting file <repo>/.hg/hgrc from untrusted user USER, group GROUP
+Defines command aliases.
+Aliases allow you to define your own commands in terms of other
+commands (or aliases), optionally including arguments. Positional
+arguments in the form of ``$1``, ``$2``, etc in the alias definition
+are expanded by Mercurial before execution. Positional arguments not
+already used by ``$N`` in the definition are put at the end of the
+command to be executed.
+
+Alias definitions consist of lines of the form::
+
+    <alias> = <command> [<argument>]...
+
+For example, this definition::
+
+    latest = log --limit 5
+
+creates a new command ``latest`` that shows only the five most recent
+changesets. You can define subsequent aliases using earlier ones::
+
+    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!
+
+An alias can start with an exclamation point (``!``) to make it a
+shell alias. A shell alias is executed with the shell and will let you
+run arbitrary commands. As an example, ::
+
+   echo = !echo
+
+will let you do ``hg echo foo`` to have ``foo`` printed in your
+terminal. A better example might be::
+
+   purge = !$HG status --no-status --unknown -0 | xargs -0 rm
+
+which will make ``hg purge`` delete all unknown files in the
+repository in the same manner as the purge extension.
+
+Shell aliases are executed in an environment where ``$HG`` expand to
+the path of the Mercurial that was used to execute the alias. This is
+useful when you want to call further Mercurial commands in a shell
+alias, as was done above for the purge alias. In addition,
+``$HG_ARGS`` expand to the arguments given to Mercurial. In the ``hg
+echo foo`` call above, ``$HG_ARGS`` would expand to ``echo foo``.
+
+``auth``
+""""""""
+
+Authentication credentials for HTTP authentication. This section
+allows you to store usernames and passwords for use when logging
+*into* HTTP servers. See the ``[web]`` configuration section if
+you want to configure *who* can login to your HTTP server.
+
+Each line has the following format::
+
+    <name>.<argument> = <value>
+
+where ``<name>`` is used to group arguments into authentication
+entries. Example::
+
+    foo.prefix = hg.intevation.org/mercurial
+    foo.username = foo
+    foo.password = bar
+    foo.schemes = http https
+
+    bar.prefix = secure.example.org
+    bar.key = path/to/file.key
+    bar.cert = path/to/file.cert
+    bar.schemes = https
+
+Supported arguments:
+
+``prefix``
+    Either ``*`` or a URI prefix with or without the scheme part.
+    The authentication entry with the longest matching prefix is used
+    (where ``*`` matches everything and counts as a match of length
+    1). If the prefix doesn't include a scheme, the match is performed
+    against the URI with its scheme stripped as well, and the schemes
+    argument, q.v., is then subsequently consulted.
+
+``username``
+    Optional. Username to authenticate with. If not given, and the
+    remote site requires basic or digest authentication, the user will
+    be prompted for it. Environment variables are expanded in the
+    username letting you do ``foo.username = $USER``.
+
+``password``
+    Optional. Password to authenticate with. If not given, and the
+    remote site requires basic or digest authentication, the user
+    will be prompted for it.
+
+``key``
+    Optional. PEM encoded client certificate key file. Environment
+    variables are expanded in the filename.
+
+``cert``
+    Optional. PEM encoded client certificate chain file. Environment
+    variables are expanded in the filename.
+
+``schemes``
+    Optional. Space separated list of URI schemes to use this
+    authentication entry with. Only used if the prefix doesn't include
+    a scheme. Supported schemes are http and https. They will match
+    static-http and static-https respectively, as well.
+    Default: https.
+
+If no suitable authentication entry is found, the user is prompted
+for credentials as usual if required by the remote.
+
+
+``decode/encode``
+"""""""""""""""""
+
+Filters for transforming files on checkout/checkin. This would
+typically be used for newline processing or other
+localization/canonicalization of files.
+
+Filters consist of a filter pattern followed by a filter command.
+Filter patterns are globs by default, rooted at the repository root.
+For example, to match any file ending in ``.txt`` in the root
+directory only, use the pattern ``*.txt``. To match any file ending
+in ``.c`` anywhere in the repository, use the pattern ``**.c``.
+For each file only the first matching filter applies.
+
+The filter command can start with a specifier, either ``pipe:`` or
+``tempfile:``. If no specifier is given, ``pipe:`` is used by default.
+
+A ``pipe:`` command must accept data on stdin and return the transformed
+data on stdout.
+
+Pipe example::
+
+  [encode]
+  # uncompress gzip files on checkin to improve delta compression
+  # note: not necessarily a good idea, just an example
+  *.gz = pipe: gunzip
+
+  [decode]
+  # recompress gzip files when writing them to the working dir (we
+  # can safely omit "pipe:", because it's the default)
+  *.gz = gzip
+
+A ``tempfile:`` command is a template. The string ``INFILE`` is replaced
+with the name of a temporary file that contains the data to be
+filtered by the command. The string ``OUTFILE`` is replaced with the name
+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.
+
+This filter mechanism is used internally by the ``eol`` extension to
+translate line ending characters between Windows (CRLF) and Unix (LF)
+format. We suggest you use the ``eol`` extension for convenience.
+
 
-If this bothers you, the warning can be silenced (the file would still
-be ignored) or trust can be established. Use one of the following
-settings, the syntax is explained below:
+``defaults``
+""""""""""""
+
+(defaults are deprecated. Don't use them. Use aliases instead)
+
+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::
+
+  [defaults]
+  log = -v
+  status = -m
+
+The actual commands, instead of their aliases, must be used when
+defining command defaults. The command defaults will also be applied
+to the aliases of the commands defined.
+
+
+``diff``
+""""""""
+
+Settings used when displaying diffs. Everything except for ``unified`` is a
+Boolean and defaults to False.
+
+``git``
+    Use git extended diff format.
+
+``nodates``
+    Don't include dates in diff headers.
+
+``showfunc``
+    Show which function each change is in.
+
+``ignorews``
+    Ignore white space when comparing lines.
+
+``ignorewsamount``
+    Ignore changes in the amount of white space.
+
+``ignoreblanklines``
+    Ignore changes whose lines are all blank.
+
+``unified``
+    Number of lines of context to show.
+
+``email``
+"""""""""
+
+Settings for extensions that send email messages.
+
+``from``
+    Optional. Email address to use in "From" header and SMTP envelope
+    of outgoing messages.
+
+``to``
+    Optional. Comma-separated list of recipients' email addresses.
+
+``cc``
+    Optional. Comma-separated list of carbon copy recipients'
+    email addresses.
+
+``bcc``
+    Optional. Comma-separated list of blind carbon copy recipients'
+    email addresses.
+
+``method``
+    Optional. Method to use to send email messages. If value is ``smtp``
+    (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
+    ``/usr/sbin/sendmail`` is enough to use sendmail to send messages.
+
+``charsets``
+    Optional. Comma-separated list of character sets considered
+    convenient for recipients. Addresses, headers, and parts not
+    containing patches of outgoing messages will be encoded in the
+    first character set to which conversion from local encoding
+    (``$HGENCODING``, ``ui.fallbackencoding``) succeeds. If correct
+    conversion fails, the text in question is sent as is. Defaults to
+    empty (explicit) list.
+
+    Order of outgoing email character sets:
+
+    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::
+
+  [email]
+  from = Joseph User <joe.user@example.com>
+  method = /usr/sbin/sendmail
+  # charsets for western Europeans
+  # us-ascii, utf-8 omitted, as they are tried first and last
+  charsets = iso-8859-1, iso-8859-15, windows-1252
+
+
+``extensions``
+""""""""""""""
+
+Mercurial has an extension mechanism for adding new features. To
+enable an extension, create an entry for it in this section.
+
+If you know that the extension is already in Python's search path,
+you can give the name of the module, followed by ``=``, with nothing
+after the ``=``.
+
+Otherwise, give a name that you choose, followed by ``=``, followed by
+the path to the ``.py`` file (including the file name extension) that
+defines the extension.
+
+To explicitly disable an extension that is enabled in an hgrc of
+broader scope, prepend its path with ``!``, as in ``foo = !/ext/path``
+or ``foo = !`` when path is not supplied.
+
+Example for ``~/.hgrc``::
+
+  [extensions]
+  # (the mq extension will get loaded from Mercurial's path)
+  mq =
+  # (this extension will get loaded from the file specified)
+  myfeature = ~/.hgext/myfeature.py
+
+
+``hostfingerprints``
+""""""""""""""""""""
+
+Fingerprints of the certificates of known HTTPS servers.
+A HTTPS connection to a server with a fingerprint configured here will
+only succeed if the servers certificate matches the fingerprint.
+This is very similar to how ssh known hosts works.
+The fingerprint is the SHA-1 hash value of the DER encoded certificate.
+The CA chain and web.cacerts is not used for servers with a fingerprint.
+
+For example::
+
+    [hostfingerprints]
+    hg.intevation.org = 38:76:52:7c:87:26:9a:8f:4a:f8:d3:de:08:45:3b:ea:d6:4b:ee:cc
+
+This feature is only supported when using Python 2.6 or later.
+
+
+``format``
+""""""""""
+
+``usestore``
+    Enable or disable the "store" repository format which improves
+    compatibility with systems that fold case or otherwise mangle
+    filenames. Enabled by default. Disabling this option will allow
+    you to store longer filenames in some situations at the expense of
+    compatibility and ensures that the on-disk format of newly created
+    repositories will be compatible with Mercurial before version 0.9.4.
 
-- ``ui.report_untrusted = False``
-- ``trusted.users = USER``
-- ``trusted.groups = GROUP``
+``usefncache``
+    Enable or disable the "fncache" repository format which enhances
+    the "store" repository format (which has to be enabled to use
+    fncache) to allow longer filenames and avoids using Windows
+    reserved names, e.g. "nul". Enabled by default. Disabling this
+    option ensures that the on-disk format of newly created
+    repositories will be compatible with Mercurial before version 1.1.
+
+``dotencode``
+    Enable or disable the "dotencode" repository format which enhances
+    the "fncache" repository format (which has to be enabled to use
+    dotencode) to avoid issues with filenames starting with ._ on
+    Mac OS X and spaces on Windows. Enabled by default. Disabling this
+    option ensures that the on-disk format of newly created
+    repositories will be compatible with Mercurial before version 1.7.
+
+``merge-patterns``
+""""""""""""""""""
+
+This section specifies merge tools to associate with particular file
+patterns. Tools matched here will take precedence over the default
+merge tool. Patterns are globs by default, rooted at the repository
+root.
+
+Example::
+
+  [merge-patterns]
+  **.c = kdiff3
+  **.jpg = myimgmerge
+
+``merge-tools``
+"""""""""""""""
+
+This section configures external merge tools to use for file-level
+merges.
+
+Example ``~/.hgrc``::
+
+  [merge-tools]
+  # Override stock tool location
+  kdiff3.executable = ~/bin/kdiff3
+  # Specify command line
+  kdiff3.args = $base $local $other -o $output
+  # Give higher priority
+  kdiff3.priority = 1
+
+  # Define new tool
+  myHtmlTool.args = -m $local $other $base $output
+  myHtmlTool.regkey = Software\FooSoftware\HtmlMerge
+  myHtmlTool.priority = 1
+
+Supported arguments:
+
+``priority``
+  The priority in which to evaluate this tool.
+  Default: 0.
+
+``executable``
+  Either just the name of the executable or its pathname.  On Windows,
+  the path can use environment variables with ${ProgramFiles} syntax.
+  Default: the tool name.
+
+``args``
+  The arguments to pass to the tool executable. You can refer to the
+  files being merged as well as the output file through these
+  variables: ``$base``, ``$local``, ``$other``, ``$output``.
+  Default: ``$local $base $other``
+
+``premerge``
+  Attempt to run internal non-interactive 3-way merge tool before
+  launching external tool.  Options are ``true``, ``false``, or ``keep``
+  to leave markers in the file if the premerge fails.
+  Default: True
+
+``binary``
+  This tool can merge binary files. Defaults to False, unless tool
+  was selected by file pattern match.
+
+``symlink``
+  This tool can merge symlinks. Defaults to False, even if tool was
+  selected by file pattern match.
+
+``check``
+  A list of merge success-checking options:
+
+  ``changed``
+    Ask whether merge was successful when the merged file shows no changes.
+  ``conflicts``
+    Check whether there are conflicts even though the tool reported success.
+  ``prompt``
+    Always prompt for merge success, regardless of success reported by tool.
+
+``checkchanged``
+  True is equivalent to ``check = changed``.
+  Default: False
+
+``checkconflicts``
+  True is equivalent to ``check = conflicts``.
+  Default: False
+
+``fixeol``
+  Attempt to fix up EOL changes caused by the merge tool.
+  Default: False
+
+``gui``
+  This tool requires a graphical interface to run. Default: False
+
+``regkey``
+  Windows registry key which describes install location of this
+  tool. Mercurial will search for this key first under
+  ``HKEY_CURRENT_USER`` and then under ``HKEY_LOCAL_MACHINE``.
+  Default: None
+
+``regkeyalt``
+  An alternate Windows registry key to try if the first key is not
+  found.  The alternate key uses the same ``regname`` and ``regappend``
+  semantics of the primary key.  The most common use for this key
+  is to search for 32bit applications on 64bit operating systems.
+  Default: None
+
+``regname``
+  Name of value to read from specified registry key. Defaults to the
+  unnamed (default) value.
+
+``regappend``
+  String to append to the value read from the registry, typically
+  the executable name of the tool.
+  Default: None
+
+
+``hooks``
+"""""""""
+
+Commands or Python functions that get automatically executed by
+various actions such as starting or finishing a commit. Multiple
+hooks can be run for the same action by appending a suffix to the
+action. Overriding a site-wide hook can be done by changing its
+value or setting it to an empty string.
+
+Example ``.hg/hgrc``::
+
+  [hooks]
+  # update working directory after adding changesets
+  changegroup.update = hg update
+  # do not use the site-wide hook
+  incoming =
+  incoming.email = /my/email/hook
+  incoming.autobuild = /my/build/hook
+
+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``.
+
+``changegroup``
+  Run after a changegroup has been added via push, pull or unbundle.
+  ID of the first new changeset is in ``$HG_NODE``. URL from which
+  changes came is in ``$HG_URL``.
 
-The configuration files for Mercurial use a simple ini-file format. A
-configuration file consists of sections, led by a ``[section]`` header
-and followed by ``name = value`` entries::
+``commit``
+  Run after a changeset has been created in the local repository. ID
+  of the newly created changeset is in ``$HG_NODE``. Parent changeset
+  IDs are in ``$HG_PARENT1`` and ``$HG_PARENT2``.
+
+``incoming``
+  Run after a changeset has been pulled, pushed, or unbundled into
+  the local repository. The ID of the newly arrived changeset is in
+  ``$HG_NODE``. URL that was source of changes came is in ``$HG_URL``.
+
+``outgoing``
+  Run after sending changes from local repository to another. ID of
+  first changeset sent is in ``$HG_NODE``. Source of operation is in
+  ``$HG_SOURCE``; see "preoutgoing" hook for description.
+
+``post-<command>``
+  Run after successful invocations of the associated command. The
+  contents of the command line are passed as ``$HG_ARGS`` and the result
+  code in ``$HG_RESULT``. Parsed command line arguments are passed as 
+  ``$HG_PATS`` and ``$HG_OPTS``. These contain string representations of
+  the python data internally passed to <command>. ``$HG_OPTS`` is a 
+  dictionary of options (with unspecified options set to their defaults).
+  ``$HG_PATS`` is a list of arguments. Hook failure is ignored.
+
+``pre-<command>``
+  Run before executing the associated command. The contents of the
+  command line are passed as ``$HG_ARGS``. Parsed command line arguments
+  are passed as ``$HG_PATS`` and ``$HG_OPTS``. These contain string
+  representations of the data internally passed to <command>. ``$HG_OPTS``
+  is a  dictionary of options (with unspecified options set to their
+  defaults). ``$HG_PATS`` is a list of arguments. If the hook returns 
+  failure, the command doesn't execute and Mercurial returns the failure
+  code.
+
+``prechangegroup``
+  Run before a changegroup is added via push, pull or unbundle. Exit
+  status 0 allows the changegroup to proceed. Non-zero status will
+  cause the push, pull or unbundle to fail. URL from which changes
+  will come is in ``$HG_URL``.
+
+``precommit``
+  Run before starting a local commit. Exit status 0 allows the
+  commit to proceed. Non-zero status will cause the commit to fail.
+  Parent changeset IDs are in ``$HG_PARENT1`` and ``$HG_PARENT2``.
+
+``prelistkeys``
+  Run before listing pushkeys (like bookmarks) in the
+  repository. Non-zero status will cause failure. The key namespace is
+  in ``$HG_NAMESPACE``.
+
+``preoutgoing``
+  Run before collecting changes to send from the local repository to
+  another. Non-zero status will cause failure. This lets you prevent
+  pull over HTTP or SSH. Also prevents against local pull, push
+  (outbound) or bundle commands, but not effective, since you can
+  just copy files instead then. Source of operation is in
+  ``$HG_SOURCE``. If "serve", operation is happening on behalf of remote
+  SSH or HTTP repository. If "push", "pull" or "bundle", operation
+  is happening on behalf of repository on same system.
+
+``prepushkey``
+  Run before a pushkey (like a bookmark) is added to the
+  repository. Non-zero status will cause the key to be rejected. The
+  key namespace is in ``$HG_NAMESPACE``, the key is in ``$HG_KEY``,
+  the old value (if any) is in ``$HG_OLD``, and the new value is in
+  ``$HG_NEW``.
+
+``pretag``
+  Run before creating a tag. Exit status 0 allows the tag to be
+  created. Non-zero status will cause the tag to fail. ID of
+  changeset to tag is in ``$HG_NODE``. Name of tag is in ``$HG_TAG``. Tag is
+  local if ``$HG_LOCAL=1``, in repository if ``$HG_LOCAL=0``.
+
+``pretxnchangegroup``
+  Run after a changegroup has been added via push, pull or unbundle,
+  but before the transaction has been committed. Changegroup is
+  visible to hook program. This lets you validate incoming changes
+  before accepting them. Passed the ID of the first new changeset in
+  ``$HG_NODE``. Exit status 0 allows the transaction to commit. Non-zero
+  status will cause the transaction to be rolled back and the push,
+  pull or unbundle will fail. URL that was source of changes is in
+  ``$HG_URL``.
+
+``pretxncommit``
+  Run after a changeset has been created but the transaction not yet
+  committed. Changeset is visible to hook program. This lets you
+  validate commit message and changes. Exit status 0 allows the
+  commit to proceed. Non-zero status will cause the transaction to
+  be rolled back. ID of changeset is in ``$HG_NODE``. Parent changeset
+  IDs are in ``$HG_PARENT1`` and ``$HG_PARENT2``.
+
+``preupdate``
+  Run before updating the working directory. Exit status 0 allows
+  the update to proceed. Non-zero status will prevent the update.
+  Changeset ID of first new parent is in ``$HG_PARENT1``. If merge, ID
+  of second new parent is in ``$HG_PARENT2``.
+
+``listkeys``
+  Run after listing pushkeys (like bookmarks) in the repository. The
+  key namespace is in ``$HG_NAMESPACE``. ``$HG_VALUES`` is a
+  dictionary containing the keys and values.
+
+``pushkey``
+  Run after a pushkey (like a bookmark) is added to the
+  repository. The key namespace is in ``$HG_NAMESPACE``, the key is in
+  ``$HG_KEY``, the old value (if any) is in ``$HG_OLD``, and the new
+  value is in ``$HG_NEW``.
+
+``tag``
+  Run after a tag is created. ID of tagged changeset is in ``$HG_NODE``.
+  Name of tag is in ``$HG_TAG``. Tag is local if ``$HG_LOCAL=1``, in
+  repository if ``$HG_LOCAL=0``.
+
+``update``
+  Run after updating the working directory. Changeset ID of first
+  new parent is in ``$HG_PARENT1``. If merge, ID of second new parent is
+  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:: 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::
+
+  hookname = python:modulename.submodule.callable
+  hookname = python:/path/to/python/module.py:callable
+
+Python hooks are run within the Mercurial process. Each hook is
+called with at least three keyword arguments: a ui object (keyword
+``ui``), a repository object (keyword ``repo``), and a ``hooktype``
+keyword that tells what kind of hook is used. Arguments listed as
+environment variables above are passed as keyword arguments, with no
+``HG_`` prefix, and names in lower case.
+
+If a Python hook returns a "true" value or raises an exception, this
+is treated as a failure.
+
+
+``http_proxy``
+""""""""""""""
+
+Used to access web-based Mercurial repositories through a HTTP
+proxy.
+
+``host``
+    Host name and (optional) port of the proxy server, for example
+    "myproxy:8000".
+
+``no``
+    Optional. Comma-separated list of host names that should bypass
+    the proxy.
+
+``passwd``
+    Optional. Password to authenticate with at the proxy server.
+
+``user``
+    Optional. User name to authenticate with at the proxy server.
+
+``always``
+    Optional. Always use the proxy, even for localhost and any entries
+    in ``http_proxy.no``. True or False. Default: False.
+
+``smtp``
+""""""""
+
+Configuration for extensions that need to send email messages.
+
+``host``
+    Host name of mail server, e.g. "mail.example.com".
+
+``port``
+    Optional. Port to connect to on mail server. Default: 25.
+
+``tls``
+    Optional. Method to enable TLS when connecting to mail server: starttls,
+    smtps or none. Default: none.
+
+``username``
+    Optional. User name for authenticating with the SMTP server.
+    Default: none.
+
+``password``
+    Optional. Password for authenticating with the SMTP server. If not
+    specified, interactive sessions will prompt the user for a
+    password; non-interactive sessions will fail. Default: none.
+
+``local_hostname``
+    Optional. It's the hostname that the sender can use to identify
+    itself to the MTA.
+
+
+``patch``
+"""""""""
+
+Settings used when applying patches, for instance through the 'import'
+command or with Mercurial Queues extension.
+
+``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 ignored when patching and the result line endings are
+    normalized to either LF (Unix) or CRLF (Windows). When set to
+    ``auto``, end of lines are again ignored while patching but line
+    endings in patched files are normalized to their original setting
+    on a per-file basis. If target file does not exist or has no end
+    of line, patch line endings are preserved.
+    Default: strict.
+
+
+``paths``
+"""""""""
+
+Assigns symbolic names to repositories. The left side is the
+symbolic name, and the right gives the directory or URL that is the
+location of the repository. Default paths can be declared by setting
+the following entries.
+
+``default``
+    Directory or URL to use when pulling if no source is specified.
+    Default is set to repository from which the current repository was
+    cloned.
+
+``default-push``
+    Optional. Directory or URL to use when pushing if no destination
+    is specified.
+
+
+``profiling``
+"""""""""""""
+
+Specifies profiling format and file output. In this section
+description, 'profiling data' stands for the raw data collected
+during profiling, while 'profiling report' stands for a statistical
+text report generated from the profiling data. The profiling is done
+using lsprof.
+
+``format``
+    Profiling format.
+    Default: text.
+
+    ``text``
+      Generate a profiling report. When saving to a file, it should be
+      noted that only the report is saved, and the profiling data is
+      not kept.
+    ``kcachegrind``
+      Format profiling data for kcachegrind use: when saving to a
+      file, the generated file can directly be loaded into
+      kcachegrind.
+
+``output``
+    File path where profiling data or report should be saved. If the
+    file exists, it is replaced. Default: None, data is printed on
+    stderr
+
+``server``
+""""""""""
+
+Controls generic server settings.
+
+``uncompressed``
+    Whether to allow clients to clone a repository using the
+    uncompressed streaming protocol. This transfers about 40% more
+    data than a regular clone, but uses less memory and CPU on both
+    server and client. Over a LAN (100 Mbps or better) or a very fast
+    WAN, an uncompressed streaming clone is a lot faster (~10x) than a
+    regular clone. Over most WAN connections (anything slower than
+    about 6 Mbps), uncompressed streaming is slower, because of the
+    extra data transfer overhead. This mode will also temporarily hold
+    the write lock while determining what data to transfer.
+    Default is True.
+
+``validate``
+    Whether to validate the completeness of pushed changesets by
+    checking that all new file revisions specified in manifests are
+    present. Default is False.
+
+``subpaths``
+""""""""""""
+
+Defines subrepositories source locations rewriting rules of the form::
+
+    <pattern> = <replacement>
+
+Where ``pattern`` is a regular expression matching the source and
+``replacement`` is the replacement string used to rewrite it. Groups
+can be matched in ``pattern`` and referenced in ``replacements``. For
+instance::
+
+    http://server/(.*)-hg/ = http://hg.server/\1/
+
+rewrites ``http://server/foo-hg/`` into ``http://hg.server/foo/``.
+
+All patterns are applied in definition order.
+
+``trusted``
+"""""""""""
+
+Mercurial will not use the settings in the
+``.hg/hgrc`` file from a repository if it doesn't belong to a trusted
+user or to a trusted group, as various hgrc features allow arbitrary
+commands to be run. This issue is often encountered when configuring
+hooks or extensions for shared repositories or servers. However,
+the web interface will use some safe settings from the ``[web]``
+section.
 
-  [ui]
-  username = Firstname Lastname <firstname.lastname@example.net>
-  verbose = True
+This section specifies what users and groups are trusted. The
+current user is always trusted. To trust everybody, list a user or a
+group with name ``*``. These settings must be placed in an
+*already-trusted file* to take effect, such as ``$HOME/.hgrc`` of the
+user or service running Mercurial.
+
+``users``
+  Comma-separated list of trusted users.
+
+``groups``
+  Comma-separated list of trusted groups.
+
+
+``ui``
+""""""
+
+User interface controls.
+
+``archivemeta``
+    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.
+
+``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 is False.
+
+``commitsubrepos``
+    Whether to commit modified subrepositories when committing the
+    parent repository. If False and one subrepository has uncommitted
+    changes, abort the commit.
+    Default is True.
+
+``debug``
+    Print debugging information. True or False. Default is False.
+
+``editor``
+    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.
+
+``ignore``
+    A file to read per-user ignore patterns from. This file should be
+    in the same format as a repository-wide .hgignore file. This
+    option supports hook syntax, so if you want to specify multiple
+    ignore files, you can do so by setting something like
+    ``ignore.other = ~/.hgignore2``. For details of the ignore file
+    format, see the ``hgignore(5)`` man page.
+
+``interactive``
+    Allow to prompt the user. True or False. Default is True.
+
+``logtemplate``
+    Template string for commands that print changesets.
+
+``merge``
+    The conflict resolution program to use during a manual merge.
+    For more information on merge tools see :hg:`help merge-tools`.
+    For configuring merge tools see the ``[merge-tools]`` section.
+
+``portablefilenames``
+    Check for portable filenames. Can be ``warn``, ``ignore`` or ``abort``.
+    Default is ``warn``.
+    If set to ``warn`` (or ``true``), a warning message is printed on POSIX
+    platforms, if a file with a non-portable filename is added (e.g. a file
+    with a name that can't be created on Windows because it contains reserved
+    parts like ``AUX``, reserved characters like ``:``, or would cause a case
+    collision with an existing file).
+    If set to ``ignore`` (or ``false``), no warning is printed.
+    If set to ``abort``, the command is aborted.
+    On Windows, this configuration option is ignored and the command aborted.
+
+``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``.
+
+``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.
+
+``slash``
+    Display paths using a slash (``/``) as the path separator. This
+    only makes a difference on systems where the default path
+    separator is not the slash character (e.g. Windows uses the
+    backslash character (``\``)).
+    Default is False.
+
+``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.
+
+``style``
+    Name of style to use for command output.
+
+``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
+    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). Environment variables in the
+    username are expanded.
+
+``verbose``
+    Increase the amount of output printed. True or False. Default is False.
+
+
+``web``
+"""""""
+
+Web interface configuration. The settings in this section apply to
+both the builtin webserver (started by :hg:`serve`) and the script you
+run through a webserver (``hgweb.cgi`` and the derivatives for FastCGI
+and WSGI).
+
+The Mercurial webserver does no authentication (it does not prompt for
+usernames and passwords to validate *who* users are), but it does do
+authorization (it grants or denies access for *authenticated users*
+based on settings in this section). You must either configure your
+webserver to do authentication for you, or disable the authorization
+checks.
+
+For a quick setup in a trusted environment, e.g., a private LAN, where
+you want it to accept pushes from anybody, you can use the following
+command line::
+
+    $ hg --config web.allow_push=* --config web.push_ssl=False serve
+
+Note that this will allow anybody to push anything to the server and
+that this should not be used for public servers.
+
+The full set of options is:
+
+``accesslog``
+    Where to output the access log. Default is stdout.
+
+``address``
+    Interface address to bind to. Default is all.
 
-The above entries will be referred to as ``ui.username`` and
-``ui.verbose``, respectively. Please see the hgrc man page for a full
-description of the possible configuration values:
+``allow_archive``
+    List of archive format (bz2, gz, zip) allowed for downloading.
+    Default is empty.
+
+``allowbz2``
+    (DEPRECATED) Whether to allow .tar.bz2 downloading of repository
+    revisions.
+    Default is False.
+
+``allowgz``
+    (DEPRECATED) Whether to allow .tar.gz downloading of repository
+    revisions.
+    Default is False.
+
+``allowpull``
+    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. The contents of the allow_push list are
+    examined after the deny_push list.
+
+``allow_read``
+    If the user has not already been denied repository access due to
+    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, 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 contents of the allow_read list are
+    examined after the deny_read list.
+
+``allowzip``
+    (DEPRECATED) Whether to allow .zip downloading of repository
+    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/``.
+
+``cacerts``
+    Path to file containing a list of PEM encoded certificate
+    authority certificates. Environment variables and ``~user``
+    constructs are expanded in the filename. If specified on the
+    client, then it will verify the identity of remote HTTPS servers
+    with these certificates. The form must be as follows::
+
+        -----BEGIN CERTIFICATE-----
+        ... (certificate in base64 PEM encoding) ...
+        -----END CERTIFICATE-----
+        -----BEGIN CERTIFICATE-----
+        ... (certificate in base64 PEM encoding) ...
+        -----END CERTIFICATE-----
+
+    This feature is only supported when using Python 2.6 or later. If you wish
+    to use it with earlier versions of Python, install the backported
+    version of the ssl library that is available from
+    ``http://pypi.python.org``.
+
+    You can use OpenSSL's CA certificate file if your platform has one.
+    On most Linux systems this will be ``/etc/ssl/certs/ca-certificates.crt``.
+    Otherwise you will have to generate this file manually.
+
+    To disable SSL verification temporarily, specify ``--insecure`` from
+    command line.
+
+``cache``
+    Whether to support caching in hgweb. Defaults to True.
+
+``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.
 
-- on Unix-like systems: ``man hgrc``
-- online: http://www.selenic.com/mercurial/hgrc.5.html
+``deny_push``
+    Whether to deny pushing to the repository. If empty or not set,
+    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 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 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
+    content of the allow_read list (see description). If both
+    deny_read and allow_read are empty or not set, then access is
+    permitted to all users by default. If the repository is being
+    served via hgwebdir, denied users will not be able to see it in
+    the list of repositories. The contents of the deny_read list have
+    priority over (are examined before) the contents of the allow_read
+    list.
+
+``descend``
+    hgwebdir indexes will not descend into subdirectories. Only repositories
+    directly in the current path will be shown (other repositories are still
+    available from the index corresponding to their containing path).
+
+``description``
+    Textual description of the repository's purpose or contents.
+    Default is "unknown".
+
+``encoding``
+    Character encoding name. Default is the current locale charset.
+    Example: "UTF-8"
+
+``errorlog``
+    Where to output the error log. Default is stderr.
+
+``hidden``
+    Whether to hide the repository in the hgwebdir index.
+    Default is False.
+
+``ipv6``
+    Whether to use IPv6. Default is False.
+
+``logourl``
+    Base URL to use for logos. If unset, ``http://mercurial.selenic.com/``
+    will be used.
+
+``name``
+    Repository name to use in the web interface. Default is current
+    working directory.
+
+``maxchanges``
+    Maximum number of changes to list on the changelog. Default is 10.
+
+``maxfiles``
+    Maximum number of files to list per changeset. Default is 10.
+
+``port``
+    Port to listen on. Default is 8000.
+
+``prefix``
+    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.
+
+``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/``.
+
+``stripes``
+    How many lines a "zebra stripe" should span in multiline output.
+    Default is 1; set to 0 to disable.
+
+``style``
+    Which template map style to use.
+
+``templates``
+    Where to find the HTML templates. Default is install path.
--- a/mercurial/help/dates.txt	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/help/dates.txt	Sat Jun 18 17:03:01 2011 -0500
@@ -30,7 +30,7 @@
 
 The log command also accepts date ranges:
 
-- ``<{datetime}`` - at or before a given date/time
-- ``>{datetime}`` - on or after a given date/time
-- ``{datetime} to {datetime}`` - a date range, inclusive
-- ``-{days}`` - within a given number of days of today
+- ``<DATE`` - at or before a given date/time
+- ``>DATE`` - on or after a given date/time
+- ``DATE to DATE`` - a date range, inclusive
+- ``-DAYS`` - within a given number of days of today
--- a/mercurial/help/environment.txt	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/help/environment.txt	Sat Jun 18 17:03:01 2011 -0500
@@ -59,6 +59,14 @@
     Equivalent options set via command line flags or environment
     variables are not overridden.
 
+HGPLAINEXCEPT
+    This is a comma-separated list of features to preserve when
+    HGPLAIN is enabled. Currently the only value supported is "i18n",
+    which preserves internationalization in plain mode.
+
+    Setting HGPLAINEXCEPT to anything (even an empty string) will
+    enable plain mode.
+
 HGUSER
     This is the string used as the author of a commit. If not set,
     available values will be considered in this order:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mercurial/help/filesets.txt	Sat Jun 18 17:03:01 2011 -0500
@@ -0,0 +1,65 @@
+Mercurial supports a functional language for selecting a set of
+files. 
+
+Like other file patterns, this pattern type is indicated by a prefix,
+'set:'. The language supports a number of predicates which are joined
+by infix operators. Parenthesis can be used for grouping.
+
+Identifiers such as filenames or patterns must be quoted with single
+or double quotes if they contain characters outside of
+``[.*{}[]?/\_a-zA-Z0-9\x80-\xff]`` or if they match one of the
+predefined predicates. This generally applies to file patterns other
+than globs and arguments for predicates.
+
+Special characters can be used in quoted identifiers by escaping them,
+e.g., ``\n`` is interpreted as a newline. To prevent them from being
+interpreted, strings can be prefixed with ``r``, e.g. ``r'...'``.
+
+There is a single prefix operator:
+
+``not x``
+  Files not in x. Short form is ``! x``.
+
+These are the supported infix operators:
+
+``x and y``
+  The intersection of files in x and y. Short form is ``x & y``.
+
+``x or y``
+  The union of files in x and y. There are two alternative short
+  forms: ``x | y`` and ``x + y``.
+
+``x - y``
+  Files in x but not in y.
+
+The following predicates are supported:
+
+.. predicatesmarker
+
+Some sample queries:
+
+- Show status of files that appear to be binary in the working directory::
+
+    hg status -A "set:binary()"
+
+- Forget files that are in .hgignore but are already tracked::
+
+    hg forget "set:hgignore() and not ignored()"
+
+- Find text files that contain a string::
+
+    hg locate "set:grep(magic) and not binary()"
+
+- Find C files in a non-standard encoding::
+
+    hg locate "set:**.c and not encoding(ascii)"
+
+- Revert copies of large binary files::
+
+    hg revert "set:copied() and binary() and size('>1M')"
+
+- Remove files listed in files.lst that contain the letter a or b::
+
+    hg remove "set: 'listfile:foo.lst' and (**a* or **b*)"
+
+See also :hg:`help patterns`.
--- a/mercurial/help/glossary.txt	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/help/glossary.txt	Sat Jun 18 17:03:01 2011 -0500
@@ -5,6 +5,18 @@
     changeset is an ancestor, and a parent of an ancestor is an
     ancestor. See also: 'Descendant'.
 
+Bookmark
+    Bookmarks are pointers to certain commits that move when
+    committing. They are similar to tags in that it is possible to use
+    bookmark names in all places where Mercurial expects a changeset
+    ID, e.g., with :hg:`update`. Unlike tags, bookmarks move along
+    when you make a commit.
+
+    Bookmarks can be renamed, copied and deleted. Bookmarks are local,
+    unless they are explicitly pushed or pulled between repositories.
+    Pushing and pulling bookmarks allow you to collaborate with others
+    on a branch without creating a named branch.
+
 Branch
     (Noun) A child changeset that has been created from a parent that
     is not a head. These are known as topological branches, see
@@ -339,6 +351,12 @@
     A changeset that has only the null changeset as its parent. Most
     repositories have only a single root changeset.
 
+Tag
+    An alternative name given to a changeset. Tags can be used in all
+    places where Mercurial expects a changeset ID, e.g., with
+    :hg:`update`. The creation of a tag is stored in the history and
+    will thus automatically be shared with other using push and pull.
+
 Tip
     The changeset with the highest revision number. It is the changeset
     most recently added in a repository.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mercurial/help/hgignore.txt	Sat Jun 18 17:03:01 2011 -0500
@@ -0,0 +1,80 @@
+Synopsis
+--------
+
+The Mercurial system uses a file called ``.hgignore`` in the root
+directory of a repository to control its behavior when it searches
+for files that it is not currently tracking.
+
+Description
+-----------
+
+The working directory of a Mercurial repository will often contain
+files that should not be tracked by Mercurial. These include backup
+files created by editors and build products created by compilers.
+These files can be ignored by listing them in a ``.hgignore`` file in
+the root of the working directory. The ``.hgignore`` file must be
+created manually. It is typically put under version control, so that
+the settings will propagate to other repositories with push and pull.
+
+An untracked file is ignored if its path relative to the repository
+root directory, or any prefix path of that path, is matched against
+any pattern in ``.hgignore``.
+
+For example, say we have an untracked file, ``file.c``, at
+``a/b/file.c`` inside our repository. Mercurial will ignore ``file.c``
+if any pattern in ``.hgignore`` matches ``a/b/file.c``, ``a/b`` or ``a``.
+
+In addition, a Mercurial configuration file can reference a set of
+per-user or global ignore files. See the ``ignore`` configuration
+key on the ``[ui]`` section of :hg:`help config` for details of how to
+configure these files.
+
+To control Mercurial's handling of files that it manages, many
+commands support the ``-I`` and ``-X`` options; see
+:hg:`help <command>` and :hg:`help patterns` for details.
+
+Syntax
+------
+
+An ignore file is a plain text file consisting of a list of patterns,
+with one pattern per line. Empty lines are skipped. The ``#``
+character is treated as a comment character, and the ``\`` character
+is treated as an escape character.
+
+Mercurial supports several pattern syntaxes. The default syntax used
+is Python/Perl-style regular expressions.
+
+To change the syntax used, use a line of the following form::
+
+  syntax: NAME
+
+where ``NAME`` is one of the following:
+
+``regexp``
+  Regular expression, Python/Perl syntax.
+``glob``
+  Shell-style glob.
+
+The chosen syntax stays in effect when parsing all patterns that
+follow, until another syntax is selected.
+
+Neither glob nor regexp patterns are rooted. A glob-syntax pattern of
+the form ``*.c`` will match a file ending in ``.c`` in any directory,
+and a regexp pattern of the form ``\.c$`` will do the same. To root a
+regexp pattern, start it with ``^``.
+
+Example
+-------
+
+Here is an example ignore file. ::
+
+  # use glob syntax.
+  syntax: glob
+
+  *.elc
+  *.pyc
+  *~
+
+  # switch to regexp syntax.
+  syntax: regexp
+  ^\.pc/
--- a/mercurial/help/patterns.txt	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/help/patterns.txt	Sat Jun 18 17:03:01 2011 -0500
@@ -49,3 +49,5 @@
 
   listfile:list.txt  read list from list.txt with one file pattern per line
   listfile0:list.txt read list from list.txt with null byte delimiters
+
+See also :hg:`help filesets`.
--- a/mercurial/help/revsets.txt	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/help/revsets.txt	Sat Jun 18 17:03:01 2011 -0500
@@ -42,11 +42,45 @@
 
 ``x - y``
   Changesets in x but not in y.
+  
+``x^n``
+  The nth parent of x, n == 0, 1, or 2.
+  For n == 0, x; for n == 1, the first parent of each changeset in x;
+  for n == 2, the second parent of changeset in x.
+
+``x~n``
+  The nth first ancestor of x; ``x~0`` is x; ``x~3`` is ``x^^^``.
+
+There is a single postfix operator:
+
+``x^``
+  Equivalent to ``x^1``, the first parent of each changeset in x.
+
 
 The following predicates are supported:
 
 .. predicatesmarker
 
+New predicates (known as "aliases") can be defined, using any combination of
+existing predicates or other aliases. An alias definition looks like::
+
+  <alias> = <definition>
+
+in the ``revsetalias`` section of ``.hgrc``. Arguments of the form `$1`, `$2`,
+etc. are substituted from the alias into the definition.
+
+For example,
+
+::
+
+  [revsetalias]
+  h = heads()
+  d($1) = sort($1, date)
+  rs($1, $2) = reverse(sort($1, $2))
+
+defines three aliases, ``h``, ``d``, and ``rs``. ``rs(0:tip, author)`` is
+exactly equivalent to ``reverse(sort(0:tip, author))``.
+
 Command line equivalents for :hg:`log`::
 
   -f    ->  ::.
--- a/mercurial/help/templates.txt	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/help/templates.txt	Sat Jun 18 17:03:01 2011 -0500
@@ -23,52 +23,7 @@
 keywords depends on the exact context of the templater. These
 keywords are usually available for templating a log-like command:
 
-:author: String. The unmodified author of the changeset.
-
-:branch: String. The name of the branch on which the changeset was
-    committed.
-
-:branches: List of strings. The name of the branch on which the
-    changeset was committed. Will be empty if the branch name was
-    default.
-
-:children: List of strings. The children of the changeset.
-
-:date: Date information. The date when the changeset was committed.
-
-:desc: String. The text of the changeset description.
-
-:diffstat: String. Statistics of changes with the following format:
-    "modified files: +added/-removed lines"
-
-:files: List of strings. All files modified, added, or removed by this
-    changeset.
-
-:file_adds: List of strings. Files added by this changeset.
-
-:file_copies: List of strings. Files copied in this changeset with
-    their sources.
-
-:file_copies_switch: List of strings. Like "file_copies" but displayed
-    only if the --copied switch is set.
-
-:file_mods: List of strings. Files modified by this changeset.
-
-:file_dels: List of strings. Files removed by this changeset.
-
-:node: String. The changeset identification hash, as a 40 hexadecimal
-    digit string.
-
-:parents: List of strings. The parents of the changeset.
-
-:rev: Integer. The repository-local changeset revision number.
-
-:tags: List of strings. Any tags associated with the changeset.
-
-:latesttag: String. Most recent global tag in the ancestors of this
-    changeset.
-
-:latesttagdistance: Integer. Longest path to the latest tag.
+.. keywordsmarker
 
 The "date" keyword does not produce human-readable output. If you
 want to use a date in your output, you can use a filter to process
@@ -82,82 +37,4 @@
 
 List of filters:
 
-:addbreaks: Any text. Add an XHTML "<br />" tag before the end of
-    every line except the last.
-
-:age: Date. Returns a human-readable date/time difference between the
-    given date/time and the current date/time.
-
-:basename: Any text. Treats the text as a path, and returns the last
-    component of the path after splitting by the path separator
-    (ignoring trailing separators). For example, "foo/bar/baz" becomes
-    "baz" and "foo/bar//" becomes "bar".
-
-:stripdir: Treat the text as path and strip a directory level, if
-    possible. For example, "foo" and "foo/bar" becomes "foo".
-
-:date: Date. Returns a date in a Unix date format, including 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``.
-
-:email: Any text. Extracts the first string that looks like 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.
-
-:hex: Any text. Convert a binary Mercurial node identifier into
-    its long hexadecimal representation.
-
-:fill68: Any text. Wraps the text to fit in 68 columns.
-
-:fill76: Any text. Wraps the text to fit in 76 columns.
-
-:firstline: Any text. Returns the first line of text.
-
-:nonempty: Any text. Returns '(none)' if the string is empty.
-
-:hgdate: Date. Returns the date as a pair of numbers: "1157407993
-    25200" (Unix timestamp, timezone offset).
-
-:isodate: Date. Returns the date in ISO 8601 format: "2009-08-18 13:00
-    +0200".
-
-:isodatesec: Date. Returns the date in ISO 8601 format, including
-    seconds: "2009-08-18 13:00:13 +0200". See also the rfc3339date
-    filter.
-
-:localdate: Date. Converts a date to local date.
-
-:obfuscate: Any text. Returns the input text rendered as a sequence of
-    XML entities.
-
-:person: Any text. Returns the text before an email address.
-
-:rfc822date: Date. Returns a date using the same format used in email
-    headers: "Tue, 18 Aug 2009 13:00:13 +0200".
-
-:rfc3339date: Date. Returns a date using the Internet date format
-    specified in RFC 3339: "2009-08-18T13:00:13+02:00".
-
-:short: Changeset hash. Returns the short form of a changeset hash,
-    i.e. a 12 hexadecimal digit string.
-
-:shortdate: Date. Returns a date like "2006-09-18".
-
-:stringify: Any type. Turns the value into text by converting values into
-    text and concatenating them.
-
-:strip: Any text. Strips all leading and trailing whitespace.
-
-:tabindent: Any text. Returns the text, with every line except the
-     first starting with a tab character.
-
-:urlescape: Any text. Escapes all "special" characters. For example,
-    "foo bar" becomes "foo%20bar".
-
-:user: Any text. Returns the user portion of an email address.
+.. filtersmarker
--- a/mercurial/hg.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/hg.py	Sat Jun 18 17:03:01 2011 -0500
@@ -8,16 +8,16 @@
 
 from i18n import _
 from lock import release
-from node import hex, nullid, nullrev, short
-import localrepo, bundlerepo, httprepo, sshrepo, statichttprepo
-import lock, util, extensions, error, encoding, node
-import cmdutil, discovery, url
+from node import hex, nullid
+import localrepo, bundlerepo, httprepo, sshrepo, statichttprepo, bookmarks
+import lock, util, extensions, error, node
+import cmdutil, discovery
 import merge as mergemod
 import verify as verifymod
 import errno, os, shutil
 
 def _local(path):
-    path = util.expandpath(util.drop_scheme('file', path))
+    path = util.expandpath(util.localpath(path))
     return (os.path.isfile(path) and bundlerepo or localrepo)
 
 def addbranchrevs(lrepo, repo, branches, revs):
@@ -51,13 +51,15 @@
             revs.append(hashbranch)
     return revs, revs[0]
 
-def parseurl(url, branches=None):
+def parseurl(path, branches=None):
     '''parse url#branch, returning (url, (branch, branches))'''
 
-    if '#' not in url:
-        return url, (None, branches or [])
-    url, branch = url.split('#', 1)
-    return url, (branch, branches or [])
+    u = util.url(path)
+    branch = None
+    if u.fragment:
+        branch = u.fragment
+        u.fragment = None
+    return str(u), (branch, branches or [])
 
 schemes = {
     'bundle': bundlerepo,
@@ -68,12 +70,9 @@
     'static-http': statichttprepo,
 }
 
-def _lookup(path):
-    scheme = 'file'
-    if path:
-        c = path.find(':')
-        if c > 0:
-            scheme = path[:c]
+def _peerlookup(path):
+    u = util.url(path)
+    scheme = u.scheme or 'file'
     thing = schemes.get(scheme) or schemes['file']
     try:
         return thing(path)
@@ -84,14 +83,14 @@
     '''return true if repo or path is local'''
     if isinstance(repo, str):
         try:
-            return _lookup(repo).islocal(repo)
+            return _peerlookup(repo).islocal(repo)
         except AttributeError:
             return False
     return repo.local()
 
 def repository(ui, path='', create=False):
     """return a repository object for the specified path"""
-    repo = _lookup(path).instance(ui, path, create)
+    repo = _peerlookup(path).instance(ui, path, create)
     ui = getattr(repo, "ui", ui)
     for name, module in extensions.extensions():
         hook = getattr(module, 'reposetup', None)
@@ -99,19 +98,15 @@
             hook(ui, repo)
     return repo
 
+def peer(ui, opts, path, create=False):
+    '''return a repository peer for the specified path'''
+    rui = remoteui(ui, opts)
+    return _peerlookup(path).instance(rui, path, create)
+
 def defaultdest(source):
     '''return default destination of clone if none is given'''
     return os.path.basename(os.path.normpath(source))
 
-def localpath(path):
-    if path.startswith('file://localhost/'):
-        return path[16:]
-    if path.startswith('file://'):
-        return path[7:]
-    if path.startswith('file:'):
-        return path[5:]
-    return path
-
 def share(ui, source, dest=None, update=True):
     '''create a shared repository'''
 
@@ -143,26 +138,27 @@
 
     if not os.path.isdir(root):
         os.mkdir(root)
-    os.mkdir(roothg)
+    util.makedir(roothg, notindexed=True)
 
     requirements = ''
     try:
-        requirements = srcrepo.opener('requires').read()
+        requirements = srcrepo.opener.read('requires')
     except IOError, inst:
         if inst.errno != errno.ENOENT:
             raise
 
     requirements += 'shared\n'
-    file(os.path.join(roothg, 'requires'), 'w').write(requirements)
-    file(os.path.join(roothg, 'sharedpath'), 'w').write(sharedpath)
+    util.writefile(os.path.join(roothg, 'requires'), requirements)
+    util.writefile(os.path.join(roothg, 'sharedpath'), sharedpath)
+
+    r = repository(ui, root)
 
     default = srcrepo.ui.config('paths', 'default')
     if default:
-        f = file(os.path.join(roothg, 'hgrc'), 'w')
-        f.write('[paths]\ndefault = %s\n' % default)
-        f.close()
-
-    r = repository(ui, root)
+        fp = r.opener("hgrc", "w", text=True)
+        fp.write("[paths]\n")
+        fp.write("default = %s\n" % default)
+        fp.close()
 
     if update:
         r.ui.status(_("updating working directory\n"))
@@ -178,8 +174,8 @@
                 continue
         _update(r, uprev)
 
-def clone(ui, source, dest=None, pull=False, rev=None, update=True,
-          stream=False, branch=None):
+def clone(ui, peeropts, source, dest=None, pull=False, rev=None,
+          update=True, stream=False, branch=None):
     """Make a copy of an existing repository.
 
     Create a copy of an existing repository in a new directory.  The
@@ -218,12 +214,12 @@
     if isinstance(source, str):
         origsource = ui.expandpath(source)
         source, branch = parseurl(origsource, branch)
-        src_repo = repository(ui, source)
+        srcrepo = repository(remoteui(ui, peeropts), source)
     else:
-        src_repo = source
+        srcrepo = source
         branch = (None, branch or [])
-        origsource = source = src_repo.url()
-    rev, checkout = addbranchrevs(src_repo, src_repo, branch, rev)
+        origsource = source = srcrepo.url()
+    rev, checkout = addbranchrevs(srcrepo, srcrepo, branch, rev)
 
     if dest is None:
         dest = defaultdest(source)
@@ -231,8 +227,8 @@
     else:
         dest = ui.expandpath(dest)
 
-    dest = localpath(dest)
-    source = localpath(source)
+    dest = util.localpath(dest)
+    source = util.localpath(source)
 
     if os.path.exists(dest):
         if not os.path.isdir(dest):
@@ -250,15 +246,17 @@
             if self.dir_:
                 self.rmtree(self.dir_, True)
 
-    src_lock = dest_lock = dir_cleanup = None
+    srclock = destlock = dircleanup = None
     try:
-        if islocal(dest):
-            dir_cleanup = DirCleanup(dest)
+        abspath = origsource
+        if islocal(origsource):
+            abspath = os.path.abspath(util.localpath(origsource))
 
-        abspath = origsource
+        if islocal(dest):
+            dircleanup = DirCleanup(dest)
+
         copy = False
-        if src_repo.cancopy() and islocal(dest):
-            abspath = os.path.abspath(util.drop_scheme('file', origsource))
+        if srcrepo.cancopy() and islocal(dest):
             copy = not pull and not rev
 
         if copy:
@@ -267,40 +265,40 @@
                 # can end up with extra data in the cloned revlogs that's
                 # not pointed to by changesets, thus causing verify to
                 # fail
-                src_lock = src_repo.lock(wait=False)
+                srclock = srcrepo.lock(wait=False)
             except error.LockError:
                 copy = False
 
         if copy:
-            src_repo.hook('preoutgoing', throw=True, source='clone')
+            srcrepo.hook('preoutgoing', throw=True, source='clone')
             hgdir = os.path.realpath(os.path.join(dest, ".hg"))
             if not os.path.exists(dest):
                 os.mkdir(dest)
             else:
                 # only clean up directories we create ourselves
-                dir_cleanup.dir_ = hgdir
+                dircleanup.dir_ = hgdir
             try:
-                dest_path = hgdir
-                os.mkdir(dest_path)
+                destpath = hgdir
+                util.makedir(destpath, notindexed=True)
             except OSError, inst:
                 if inst.errno == errno.EEXIST:
-                    dir_cleanup.close()
+                    dircleanup.close()
                     raise util.Abort(_("destination '%s' already exists")
                                      % dest)
                 raise
 
             hardlink = None
             num = 0
-            for f in src_repo.store.copylist():
-                src = os.path.join(src_repo.sharedpath, f)
-                dst = os.path.join(dest_path, f)
+            for f in srcrepo.store.copylist():
+                src = os.path.join(srcrepo.sharedpath, f)
+                dst = os.path.join(destpath, f)
                 dstbase = os.path.dirname(dst)
                 if dstbase and not os.path.exists(dstbase):
                     os.mkdir(dstbase)
                 if os.path.exists(src):
                     if dst.endswith('data'):
                         # lock to avoid premature writing to the target
-                        dest_lock = lock.lock(os.path.join(dstbase, "lock"))
+                        destlock = lock.lock(os.path.join(dstbase, "lock"))
                     hardlink, n = util.copyfiles(src, dst, hardlink)
                     num += n
             if hardlink:
@@ -310,67 +308,83 @@
 
             # we need to re-init the repo after manually copying the data
             # into it
-            dest_repo = repository(ui, dest)
-            src_repo.hook('outgoing', source='clone',
+            destrepo = repository(remoteui(ui, peeropts), dest)
+            srcrepo.hook('outgoing', source='clone',
                           node=node.hex(node.nullid))
         else:
             try:
-                dest_repo = repository(ui, dest, create=True)
+                destrepo = repository(remoteui(ui, peeropts), dest,
+                                      create=True)
             except OSError, inst:
                 if inst.errno == errno.EEXIST:
-                    dir_cleanup.close()
+                    dircleanup.close()
                     raise util.Abort(_("destination '%s' already exists")
                                      % dest)
                 raise
 
             revs = None
             if rev:
-                if 'lookup' not in src_repo.capabilities:
+                if not srcrepo.capable('lookup'):
                     raise util.Abort(_("src repository does not support "
                                        "revision lookup and so doesn't "
                                        "support clone by revision"))
-                revs = [src_repo.lookup(r) for r in rev]
+                revs = [srcrepo.lookup(r) for r in rev]
                 checkout = revs[0]
-            if dest_repo.local():
-                dest_repo.clone(src_repo, heads=revs, stream=stream)
-            elif src_repo.local():
-                src_repo.push(dest_repo, revs=revs)
+            if destrepo.local():
+                destrepo.clone(srcrepo, heads=revs, stream=stream)
+            elif srcrepo.local():
+                srcrepo.push(destrepo, revs=revs)
             else:
                 raise util.Abort(_("clone from remote to remote not supported"))
 
-        if dir_cleanup:
-            dir_cleanup.close()
+        if dircleanup:
+            dircleanup.close()
 
-        if dest_repo.local():
-            fp = dest_repo.opener("hgrc", "w", text=True)
+        if destrepo.local():
+            fp = destrepo.opener("hgrc", "w", text=True)
             fp.write("[paths]\n")
             fp.write("default = %s\n" % abspath)
             fp.close()
 
-            dest_repo.ui.setconfig('paths', 'default', abspath)
+            destrepo.ui.setconfig('paths', 'default', abspath)
 
             if update:
                 if update is not True:
                     checkout = update
-                    if src_repo.local():
-                        checkout = src_repo.lookup(update)
+                    if srcrepo.local():
+                        checkout = srcrepo.lookup(update)
                 for test in (checkout, 'default', 'tip'):
                     if test is None:
                         continue
                     try:
-                        uprev = dest_repo.lookup(test)
+                        uprev = destrepo.lookup(test)
                         break
                     except error.RepoLookupError:
                         continue
-                bn = dest_repo[uprev].branch()
-                dest_repo.ui.status(_("updating to branch %s\n") % bn)
-                _update(dest_repo, uprev)
+                bn = destrepo[uprev].branch()
+                destrepo.ui.status(_("updating to branch %s\n") % bn)
+                _update(destrepo, uprev)
 
-        return src_repo, dest_repo
+        # clone all bookmarks
+        if destrepo.local() and srcrepo.capable("pushkey"):
+            rb = srcrepo.listkeys('bookmarks')
+            for k, n in rb.iteritems():
+                try:
+                    m = destrepo.lookup(n)
+                    destrepo._bookmarks[k] = m
+                except error.RepoLookupError:
+                    pass
+            if rb:
+                bookmarks.write(destrepo)
+        elif srcrepo.local() and destrepo.capable("pushkey"):
+            for k, n in srcrepo._bookmarks.iteritems():
+                destrepo.pushkey('bookmarks', k, '', hex(n))
+
+        return srcrepo, destrepo
     finally:
-        release(src_lock, dest_lock)
-        if dir_cleanup is not None:
-            dir_cleanup.cleanup()
+        release(srclock, destlock)
+        if dircleanup is not None:
+            dircleanup.cleanup()
 
 def _showstats(repo, stats):
     repo.ui.status(_("%d files updated, %d files merged, "
@@ -415,20 +429,19 @@
     and is supposed to contain only code that can't be unified.
     """
     source, branches = parseurl(ui.expandpath(source), opts.get('branch'))
-    other = repository(remoteui(repo, opts), source)
-    ui.status(_('comparing with %s\n') % url.hidepassword(source))
+    other = peer(repo, opts, source)
+    ui.status(_('comparing with %s\n') % util.hidepassword(source))
     revs, checkout = addbranchrevs(repo, other, branches, opts.get('rev'))
 
     if revs:
         revs = [other.lookup(rev) for rev in revs]
-    other, incoming, bundle = bundlerepo.getremotechanges(ui, repo, other, revs,
-                                opts["bundle"], opts["force"])
-    if incoming is None:
-        ui.status(_("no changes found\n"))
-        return subreporecurse()
+    other, chlist, cleanupfn = bundlerepo.getremotechanges(ui, repo, other,
+                                revs, opts["bundle"], opts["force"])
+    try:
+        if not chlist:
+            ui.status(_("no changes found\n"))
+            return subreporecurse()
 
-    try:
-        chlist = other.changelog.nodesbetween(incoming, revs)[0]
         displayer = cmdutil.show_changeset(ui, other, opts, buffered)
 
         # XXX once graphlog extension makes it into core,
@@ -437,10 +450,7 @@
 
         displayer.close()
     finally:
-        if hasattr(other, 'close'):
-            other.close()
-        if bundle:
-            os.unlink(bundle)
+        cleanupfn()
     subreporecurse()
     return 0 # exit code is zero since we found incoming changes
 
@@ -472,18 +482,19 @@
 def _outgoing(ui, repo, dest, opts):
     dest = ui.expandpath(dest or 'default-push', dest or 'default')
     dest, branches = parseurl(dest, opts.get('branch'))
-    ui.status(_('comparing with %s\n') % url.hidepassword(dest))
+    ui.status(_('comparing with %s\n') % util.hidepassword(dest))
     revs, checkout = addbranchrevs(repo, repo, branches, opts.get('rev'))
     if revs:
         revs = [repo.lookup(rev) for rev in revs]
 
-    other = repository(remoteui(repo, opts), dest)
-    o = discovery.findoutgoing(repo, other, force=opts.get('force'))
+    other = peer(repo, opts, dest)
+    common, outheads = discovery.findcommonoutgoing(repo, other, revs,
+                                                    force=opts.get('force'))
+    o = repo.changelog.findmissing(common, outheads)
     if not o:
         ui.status(_("no changes found\n"))
         return None
-
-    return repo.changelog.nodesbetween(o, revs)[0]
+    return o
 
 def outgoing(ui, repo, dest, opts):
     def recurse():
--- a/mercurial/hgweb/common.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/hgweb/common.py	Sat Jun 18 17:03:01 2011 -0500
@@ -17,12 +17,6 @@
 HTTP_METHOD_NOT_ALLOWED = 405
 HTTP_SERVER_ERROR = 500
 
-# Hooks for hgweb permission checks; extensions can add hooks here. Each hook
-# is invoked like this: hook(hgweb, request, operation), where operation is
-# either read, pull or push. Hooks should either raise an ErrorResponse
-# exception, or just return.
-# It is possible to do both authentication and authorization through this.
-permhooks = []
 
 def checkauthz(hgweb, req, op):
     '''Check permission for operation based on request data (including
@@ -65,18 +59,43 @@
     if not result:
         raise ErrorResponse(HTTP_UNAUTHORIZED, 'push not authorized')
 
-# Add the default permhook, which provides simple authorization.
-permhooks.append(checkauthz)
+# Hooks for hgweb permission checks; extensions can add hooks here.
+# Each hook is invoked like this: hook(hgweb, request, operation),
+# where operation is either read, pull or push. Hooks should either
+# raise an ErrorResponse exception, or just return.
+#
+# It is possible to do both authentication and authorization through
+# this.
+permhooks = [checkauthz]
 
 
 class ErrorResponse(Exception):
     def __init__(self, code, message=None, headers=[]):
         if message is None:
             message = _statusmessage(code)
-        Exception.__init__(self, code, message)
+        Exception.__init__(self)
         self.code = code
         self.message = message
         self.headers = headers
+    def __str__(self):
+        return self.message
+
+class continuereader(object):
+    def __init__(self, f, write):
+        self.f = f
+        self._write = write
+        self.continued = False
+
+    def read(self, amt=-1):
+        if not self.continued:
+            self.continued = True
+            self._write('HTTP/1.1 100 Continue\r\n\r\n')
+        return self.f.read(amt)
+
+    def __getattr__(self, attr):
+        if attr in ('close', 'readline', 'readlines', '__iter__'):
+            return getattr(self.f, attr)
+        raise AttributeError()
 
 def _statusmessage(code):
     from BaseHTTPServer import BaseHTTPRequestHandler
--- a/mercurial/hgweb/hgweb_mod.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/hgweb/hgweb_mod.py	Sat Jun 18 17:03:01 2011 -0500
@@ -17,6 +17,7 @@
 perms = {
     'changegroup': 'pull',
     'changegroupsubset': 'pull',
+    'getbundle': 'pull',
     'stream_out': 'pull',
     'listkeys': 'pull',
     'unbundle': 'push',
@@ -125,7 +126,11 @@
                     self.check_perm(req, perms[cmd])
                 return protocol.call(self.repo, req, cmd)
             except ErrorResponse, inst:
-                if cmd == 'unbundle':
+                # A client that sends unbundle without 100-continue will
+                # break if we respond early.
+                if (cmd == 'unbundle' and
+                    req.env.get('HTTP_EXPECT',
+                                '').lower() != '100-continue'):
                     req.drain()
                 req.respond(inst, protocol.HGTYPE)
                 return '0\n%s\n' % inst.message
@@ -183,7 +188,8 @@
                 req.form['cmd'] = [tmpl.cache['default']]
                 cmd = req.form['cmd'][0]
 
-            caching(self, req) # sets ETag header or raises NOT_MODIFIED
+            if self.configbool('web', 'cache', True):
+                caching(self, req) # sets ETag header or raises NOT_MODIFIED
             if cmd not in webcommands.__all__:
                 msg = 'no such method: %s' % cmd
                 raise ErrorResponse(HTTP_BAD_REQUEST, msg)
@@ -228,6 +234,7 @@
         port = req.env["SERVER_PORT"]
         port = port != default_port and (":" + port) or ""
         urlbase = '%s://%s%s' % (proto, req.env['SERVER_NAME'], port)
+        logourl = self.config("web", "logourl", "http://mercurial.selenic.com/")
         staticurl = self.config("web", "staticurl") or req.url + 'static/'
         if not staticurl.endswith('/'):
             staticurl += '/'
@@ -267,6 +274,7 @@
 
         tmpl = templater.templater(mapfile,
                                    defaults={"url": req.url,
+                                             "logourl": logourl,
                                              "staticurl": staticurl,
                                              "urlbase": urlbase,
                                              "repo": self.reponame,
--- a/mercurial/hgweb/hgwebdir_mod.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/hgweb/hgwebdir_mod.py	Sat Jun 18 17:03:01 2011 -0500
@@ -6,9 +6,9 @@
 # This software may be used and distributed according to the terms of the
 # GNU General Public License version 2 or any later version.
 
-import os, re, time, urlparse
+import os, re, time
 from mercurial.i18n import _
-from mercurial import ui, hg, util, templater
+from mercurial import ui, hg, scmutil, util, templater
 from mercurial import error, encoding
 from common import ErrorResponse, get_mtime, staticfile, paritygen, \
                    get_contact, HTTP_OK, HTTP_NOT_FOUND, HTTP_SERVER_ERROR
@@ -33,16 +33,17 @@
             repos.append((prefix, root))
             continue
         roothead = os.path.normpath(os.path.abspath(roothead))
-        paths = util.walkrepos(roothead, followsym=True, recurse=recurse)
+        paths = scmutil.walkrepos(roothead, followsym=True, recurse=recurse)
         repos.extend(urlrepos(prefix, roothead, paths))
     return repos
 
 def urlrepos(prefix, roothead, paths):
     """yield url paths and filesystem paths from a list of repo paths
 
-    >>> list(urlrepos('hg', '/opt', ['/opt/r', '/opt/r/r', '/opt']))
+    >>> conv = lambda seq: [(v, util.pconvert(p)) for v,p in seq]
+    >>> conv(urlrepos('hg', '/opt', ['/opt/r', '/opt/r/r', '/opt']))
     [('hg/r', '/opt/r'), ('hg/r/r', '/opt/r/r'), ('hg', '/opt')]
-    >>> list(urlrepos('', '/opt', ['/opt/r', '/opt/r/r', '/opt']))
+    >>> conv(urlrepos('', '/opt', ['/opt/r', '/opt/r/r', '/opt']))
     [('r', '/opt/r'), ('r/r', '/opt/r/r'), ('', '/opt')]
     """
     for path in paths:
@@ -76,7 +77,10 @@
             if not os.path.exists(self.conf):
                 raise util.Abort(_('config file %s not found!') % self.conf)
             u.readconfig(self.conf, remap=map, trust=True)
-            paths = u.configitems('hgweb-paths')
+            paths = []
+            for name, ignored in u.configitems('hgweb-paths'):
+                for path in u.configlist('hgweb-paths', name):
+                    paths.append((name, path))
         elif isinstance(self.conf, (list, tuple)):
             paths = self.conf
         elif isinstance(self.conf, dict):
@@ -85,7 +89,7 @@
         repos = findrepos(paths)
         for prefix, root in u.configitems('collections'):
             prefix = util.pconvert(prefix)
-            for path in util.walkrepos(root, followsym=True):
+            for path in scmutil.walkrepos(root, followsym=True):
                 repo = os.path.normpath(path)
                 name = util.pconvert(repo)
                 if name.startswith(prefix):
@@ -247,6 +251,9 @@
                 # update time with local timezone
                 try:
                     r = hg.repository(self.ui, path)
+                except IOError:
+                    u.warn(_('error accessing repository at %s\n') % path)
+                    continue
                 except error.RepoError:
                     u.warn(_('error accessing repository at %s\n') % path)
                     continue
@@ -340,6 +347,7 @@
 
         start = url[-1] == '?' and '&' or '?'
         sessionvars = webutil.sessionvars(vars, start)
+        logourl = config('web', 'logourl', 'http://mercurial.selenic.com/')
         staticurl = config('web', 'staticurl') or url + 'static/'
         if not staticurl.endswith('/'):
             staticurl += '/'
@@ -349,22 +357,15 @@
                                              "footer": footer,
                                              "motd": motd,
                                              "url": url,
+                                             "logourl": logourl,
                                              "staticurl": staticurl,
                                              "sessionvars": sessionvars})
         return tmpl
 
     def updatereqenv(self, env):
-        def splitnetloc(netloc):
-            if ':' in netloc:
-                return netloc.split(':', 1)
-            else:
-                return (netloc, None)
-
         if self._baseurl is not None:
-            urlcomp = urlparse.urlparse(self._baseurl)
-            host, port = splitnetloc(urlcomp[1])
-            path = urlcomp[2]
-            env['SERVER_NAME'] = host
-            if port:
-                env['SERVER_PORT'] = port
-            env['SCRIPT_NAME'] = path
+            u = util.url(self._baseurl)
+            env['SERVER_NAME'] = u.host
+            if u.port:
+                env['SERVER_PORT'] = u.port
+            env['SCRIPT_NAME'] = '/' + u.path
--- a/mercurial/hgweb/protocol.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/hgweb/protocol.py	Sat Jun 18 17:03:01 2011 -0500
@@ -5,39 +5,57 @@
 # This software may be used and distributed according to the terms of the
 # GNU General Public License version 2 or any later version.
 
-import cStringIO, zlib, sys, urllib
+import cgi, cStringIO, zlib, urllib
 from mercurial import util, wireproto
 from common import HTTP_OK
 
 HGTYPE = 'application/mercurial-0.1'
 
 class webproto(object):
-    def __init__(self, req):
+    def __init__(self, req, ui):
         self.req = req
         self.response = ''
+        self.ui = ui
     def getargs(self, args):
+        knownargs = self._args()
         data = {}
         keys = args.split()
         for k in keys:
             if k == '*':
                 star = {}
-                for key in self.req.form.keys():
-                    if key not in keys:
-                        star[key] = self.req.form[key][0]
+                for key in knownargs.keys():
+                    if key != 'cmd' and key not in keys:
+                        star[key] = knownargs[key][0]
                 data['*'] = star
             else:
-                data[k] = self.req.form[k][0]
+                data[k] = knownargs[k][0]
         return [data[k] for k in keys]
+    def _args(self):
+        args = self.req.form.copy()
+        chunks = []
+        i = 1
+        while True:
+            h = self.req.env.get('HTTP_X_HGARG_' + str(i))
+            if h is None:
+                break
+            chunks += [h]
+            i += 1
+        args.update(cgi.parse_qs(''.join(chunks), keep_blank_values=True))
+        return args
     def getfile(self, fp):
         length = int(self.req.env['CONTENT_LENGTH'])
         for s in util.filechunkiter(self.req, limit=length):
             fp.write(s)
     def redirect(self):
-        self.oldio = sys.stdout, sys.stderr
-        sys.stderr = sys.stdout = cStringIO.StringIO()
+        self.oldio = self.ui.fout, self.ui.ferr
+        self.ui.ferr = self.ui.fout = cStringIO.StringIO()
+    def restore(self):
+        val = self.ui.fout.getvalue()
+        self.ui.ferr, self.ui.fout = self.oldio
+        return val
     def groupchunks(self, cg):
         z = zlib.compressobj()
-        while 1:
+        while True:
             chunk = cg.read(4096)
             if not chunk:
                 break
@@ -53,7 +71,7 @@
     return cmd in wireproto.commands
 
 def call(repo, req, cmd):
-    p = webproto(req)
+    p = webproto(req, repo.ui)
     rsp = wireproto.dispatch(repo, p, cmd)
     if isinstance(rsp, str):
         req.respond(HTTP_OK, HGTYPE, length=len(rsp))
@@ -62,14 +80,13 @@
         req.respond(HTTP_OK, HGTYPE)
         return rsp.gen
     elif isinstance(rsp, wireproto.pushres):
-        val = sys.stdout.getvalue()
-        sys.stdout, sys.stderr = p.oldio
+        val = p.restore()
         req.respond(HTTP_OK, HGTYPE)
         return ['%d\n%s' % (rsp.res, val)]
     elif isinstance(rsp, wireproto.pusherr):
         # drain the incoming bundle
         req.drain()
-        sys.stdout, sys.stderr = p.oldio
+        p.restore()
         rsp = '0\n%s\n' % rsp.res
         req.respond(HTTP_OK, HGTYPE, length=len(rsp))
         return [rsp]
--- a/mercurial/hgweb/server.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/hgweb/server.py	Sat Jun 18 17:03:01 2011 -0500
@@ -8,6 +8,7 @@
 
 import os, sys, errno, urllib, BaseHTTPServer, socket, SocketServer, traceback
 from mercurial import util, error
+from mercurial.hgweb import common
 from mercurial.i18n import _
 
 def _splitURI(uri):
@@ -58,6 +59,12 @@
     def log_message(self, format, *args):
         self._log_any(self.server.accesslog, format, *args)
 
+    def log_request(self, code='-', size='-'):
+        xheaders = [h for h in self.headers.items() if h[0].startswith('x-')]
+        self.log_message('"%s" %s %s%s',
+                         self.requestline, str(code), str(size),
+                         ''.join([' %s:%s' % h for h in sorted(xheaders)]))
+
     def do_write(self):
         try:
             self.do_hgweb()
@@ -111,6 +118,9 @@
         env['SERVER_PROTOCOL'] = self.request_version
         env['wsgi.version'] = (1, 0)
         env['wsgi.url_scheme'] = self.url_scheme
+        if env.get('HTTP_EXPECT', '').lower() == '100-continue':
+            self.rfile = common.continuereader(self.rfile, self.wfile.write)
+
         env['wsgi.input'] = self.rfile
         env['wsgi.errors'] = _error_logger(self)
         env['wsgi.multithread'] = isinstance(self.server,
--- a/mercurial/hgweb/webcommands.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/hgweb/webcommands.py	Sat Jun 18 17:03:01 2011 -0500
@@ -80,7 +80,7 @@
                 path=webutil.up(f),
                 text=lines(),
                 rev=fctx.rev(),
-                node=hex(fctx.node()),
+                node=fctx.hex(),
                 author=fctx.user(),
                 date=fctx.date(),
                 desc=fctx.description(),
@@ -108,10 +108,11 @@
     revcount = web.maxchanges
     if 'revcount' in req.form:
         revcount = int(req.form.get('revcount', [revcount])[0])
+        revcount = max(revcount, 1)
         tmpl.defaults['sessionvars']['revcount'] = revcount
 
     lessvars = copy.copy(tmpl.defaults['sessionvars'])
-    lessvars['revcount'] = revcount / 2
+    lessvars['revcount'] = max(revcount / 2, 1)
     lessvars['rev'] = query
     morevars = copy.copy(tmpl.defaults['sessionvars'])
     morevars['revcount'] = revcount * 2
@@ -220,10 +221,11 @@
     revcount = shortlog and web.maxshortchanges or web.maxchanges
     if 'revcount' in req.form:
         revcount = int(req.form.get('revcount', [revcount])[0])
+        revcount = max(revcount, 1)
         tmpl.defaults['sessionvars']['revcount'] = revcount
 
     lessvars = copy.copy(tmpl.defaults['sessionvars'])
-    lessvars['revcount'] = revcount / 2
+    lessvars['revcount'] = max(revcount / 2, 1)
     morevars = copy.copy(tmpl.defaults['sessionvars'])
     morevars['revcount'] = revcount * 2
 
@@ -237,7 +239,7 @@
     changenav = webutil.revnavgen(pos, revcount, count, web.repo.changectx)
 
     return tmpl(shortlog and 'shortlog' or 'changelog', changenav=changenav,
-                node=hex(ctx.node()), rev=pos, changesets=count,
+                node=ctx.hex(), rev=pos, changesets=count,
                 entries=lambda **x: changelist(limit=0,**x),
                 latestentry=lambda **x: changelist(limit=1,**x),
                 archives=web.archivelist("tip"), revcount=revcount,
@@ -261,12 +263,17 @@
                           node=ctx.hex(), file=f,
                           parity=parity.next()))
 
-    parity = paritygen(web.stripecount)
     style = web.config('web', 'style', 'paper')
     if 'style' in req.form:
         style = req.form['style'][0]
 
+    parity = paritygen(web.stripecount)
     diffs = webutil.diffs(web.repo, tmpl, ctx, None, parity, style)
+
+    parity = paritygen(web.stripecount)
+    diffstatgen = webutil.diffstatgen(ctx)
+    diffstat = webutil.diffstat(tmpl, ctx, diffstatgen, parity)
+
     return tmpl('changeset',
                 diff=diffs,
                 rev=ctx.rev(),
@@ -280,6 +287,8 @@
                 desc=ctx.description(),
                 date=ctx.date(),
                 files=files,
+                diffsummary=lambda **x: webutil.diffsummary(diffstatgen),
+                diffstat=diffstat,
                 archives=web.archivelist(ctx.hex()),
                 tags=webutil.nodetagsdict(web.repo, ctx.node()),
                 bookmarks=webutil.nodebookmarksdict(web.repo, ctx.node()),
@@ -393,14 +402,11 @@
 
 def bookmarks(web, req, tmpl):
     i = web.repo._bookmarks.items()
-    i.reverse()
     parity = paritygen(web.stripecount)
 
-    def entries(notip=False, limit=0, **map):
+    def entries(limit=0, **map):
         count = 0
-        for k, n in i:
-            if notip and k == "tip":
-                continue
+        for k, n in sorted(i):
             if limit > 0 and count >= limit:
                 continue
             count = count + 1
@@ -411,9 +417,8 @@
 
     return tmpl("bookmarks",
                 node=hex(web.repo.changelog.tip()),
-                entries=lambda **x: entries(False, 0, **x),
-                entriesnotip=lambda **x: entries(True, 0, **x),
-                latestentry=lambda **x: entries(True, 1, **x))
+                entries=lambda **x: entries(0, **x),
+                latestentry=lambda **x: entries(1, **x))
 
 def branches(web, req, tmpl):
     tips = (web.repo[n] for t, n in web.repo.branchtags().iteritems())
@@ -464,6 +469,15 @@
                        node=hex(n),
                        date=web.repo[n].date())
 
+    def bookmarks(**map):
+        parity = paritygen(web.stripecount)
+        b = web.repo._bookmarks.items()
+        for k, n in sorted(b)[:10]:  # limit to 10 bookmarks
+            yield {'parity': parity.next(),
+                   'bookmark': k,
+                   'date': web.repo[n].date(),
+                   'node': hex(n)}
+
     def branches(**map):
         parity = paritygen(web.stripecount)
 
@@ -508,6 +522,7 @@
                 owner=get_contact(web.config) or "unknown",
                 lastchange=tip.date(),
                 tags=tagentries,
+                bookmarks=bookmarks,
                 branches=branches,
                 shortlog=changelist,
                 node=tip.hex(),
@@ -574,7 +589,7 @@
                 last = fnode
 
             yield {"parity": parity.next(),
-                   "node": hex(f.node()),
+                   "node": f.hex(),
                    "rev": f.rev(),
                    "author": f.user(),
                    "desc": f.description(),
@@ -590,7 +605,7 @@
                 annotate=annotate,
                 path=webutil.up(f),
                 rev=fctx.rev(),
-                node=hex(fctx.node()),
+                node=fctx.hex(),
                 author=fctx.user(),
                 date=fctx.date(),
                 desc=fctx.description(),
@@ -624,10 +639,11 @@
     revcount = web.maxshortchanges
     if 'revcount' in req.form:
         revcount = int(req.form.get('revcount', [revcount])[0])
+        revcount = max(revcount, 1)
         tmpl.defaults['sessionvars']['revcount'] = revcount
 
     lessvars = copy.copy(tmpl.defaults['sessionvars'])
-    lessvars['revcount'] = revcount / 2
+    lessvars['revcount'] = max(revcount / 2, 1)
     morevars = copy.copy(tmpl.defaults['sessionvars'])
     morevars['revcount'] = revcount * 2
 
@@ -646,7 +662,7 @@
             l.insert(0, {"parity": parity.next(),
                          "filerev": i,
                          "file": f,
-                         "node": hex(iterfctx.node()),
+                         "node": iterfctx.hex(),
                          "author": iterfctx.user(),
                          "date": iterfctx.date(),
                          "rename": webutil.renamelink(iterfctx),
@@ -668,7 +684,7 @@
 
     nodefunc = lambda x: fctx.filectx(fileid=x)
     nav = webutil.revnavgen(end - 1, revcount, count, nodefunc)
-    return tmpl("filelog", file=f, node=hex(fctx.node()), nav=nav,
+    return tmpl("filelog", file=f, node=fctx.hex(), nav=nav,
                 entries=lambda **x: entries(limit=0, **x),
                 latestentry=lambda **x: entries(limit=1, **x),
                 revcount=revcount, morevars=morevars, lessvars=lessvars)
@@ -725,10 +741,11 @@
     revcount = web.maxshortchanges
     if 'revcount' in req.form:
         revcount = int(req.form.get('revcount', [revcount])[0])
+        revcount = max(revcount, 1)
         tmpl.defaults['sessionvars']['revcount'] = revcount
 
     lessvars = copy.copy(tmpl.defaults['sessionvars'])
-    lessvars['revcount'] = revcount / 2
+    lessvars['revcount'] = max(revcount / 2, 1)
     morevars = copy.copy(tmpl.defaults['sessionvars'])
     morevars['revcount'] = revcount * 2
 
@@ -745,14 +762,14 @@
     if rev < web.maxshortchanges:
         startrev = uprev
 
-    dag = graphmod.revisions(web.repo, startrev, downrev)
+    dag = graphmod.dagwalker(web.repo, range(startrev, downrev - 1, -1))
     tree = list(graphmod.colored(dag))
     canvasheight = (len(tree) + 1) * bg_height - 27
     data = []
     for (id, type, ctx, vtx, edges) in tree:
         if type != graphmod.CHANGESET:
             continue
-        node = short(ctx.node())
+        node = str(ctx)
         age = templatefilters.age(ctx.date())
         desc = templatefilters.firstline(ctx.description())
         desc = cgi.escape(templatefilters.nonempty(desc))
@@ -780,8 +797,6 @@
 
     topicname = req.form.get('node', [None])[0]
     if not topicname:
-        topic = []
-
         def topics(**map):
             for entries, summary, _ in helpmod.helptable:
                 entries = sorted(entries, key=len)
--- a/mercurial/hgweb/webutil.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/hgweb/webutil.py	Sat Jun 18 17:03:01 2011 -0500
@@ -7,7 +7,8 @@
 # GNU General Public License version 2 or any later version.
 
 import os, copy
-from mercurial import match, patch, util, error, ui
+from mercurial import match, patch, scmutil, error, ui, util
+from mercurial.i18n import _
 from mercurial.node import hex, nullid
 
 def up(p):
@@ -66,7 +67,7 @@
     if len(siblings) == 1 and siblings[0].rev() == hiderev:
         return
     for s in siblings:
-        d = {'node': hex(s.node()), 'rev': s.rev()}
+        d = {'node': s.hex(), 'rev': s.rev()}
         d['user'] = s.user()
         d['date'] = s.date()
         d['description'] = s.description()
@@ -127,7 +128,7 @@
 
 def cleanpath(repo, path):
     path = path.lstrip('/')
-    return util.canonpath(repo.root, '', path)
+    return scmutil.canonpath(repo.root, '', path)
 
 def changectx(repo, req):
     changeid = "tip"
@@ -211,6 +212,41 @@
     yield tmpl('diffblock', parity=parity.next(),
                lines=prettyprintlines(''.join(block)))
 
+def diffstatgen(ctx):
+    '''Generator function that provides the diffstat data.'''
+
+    stats = patch.diffstatdata(util.iterlines(ctx.diff()))
+    maxname, maxtotal, addtotal, removetotal, binary = patch.diffstatsum(stats)
+    while True:
+        yield stats, maxname, maxtotal, addtotal, removetotal, binary
+
+def diffsummary(statgen):
+    '''Return a short summary of the diff.'''
+
+    stats, maxname, maxtotal, addtotal, removetotal, binary = statgen.next()
+    return _(' %d files changed, %d insertions(+), %d deletions(-)\n') % (
+             len(stats), addtotal, removetotal)
+
+def diffstat(tmpl, ctx, statgen, parity):
+    '''Return a diffstat template for each file in the diff.'''
+
+    stats, maxname, maxtotal, addtotal, removetotal, binary = statgen.next()
+    files = ctx.files()
+
+    def pct(i):
+        if maxtotal == 0:
+            return 0
+        return (float(i) / maxtotal) * 100
+
+    fileno = 0
+    for filename, adds, removes, isbinary in stats:
+        template = filename in files and 'diffstatlink' or 'diffstatnolink'
+        total = adds + removes
+        fileno += 1
+        yield tmpl(template, node=ctx.hex(), file=filename, fileno=fileno,
+                   total=total, addpct=pct(adds), removepct=pct(removes),
+                   parity=parity.next())
+
 class sessionvars(object):
     def __init__(self, vars, start='?'):
         self.start = start
--- a/mercurial/hgweb/wsgicgi.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/hgweb/wsgicgi.py	Sat Jun 18 17:03:01 2011 -0500
@@ -10,10 +10,11 @@
 
 import os, sys
 from mercurial import util
+from mercurial.hgweb import common
 
 def launch(application):
-    util.set_binary(sys.stdin)
-    util.set_binary(sys.stdout)
+    util.setbinary(sys.stdin)
+    util.setbinary(sys.stdout)
 
     environ = dict(os.environ.iteritems())
     environ.setdefault('PATH_INFO', '')
@@ -23,7 +24,11 @@
         if environ['PATH_INFO'].startswith(scriptname):
             environ['PATH_INFO'] = environ['PATH_INFO'][len(scriptname):]
 
-    environ['wsgi.input'] = sys.stdin
+    stdin = sys.stdin
+    if environ.get('HTTP_EXPECT', '').lower() == '100-continue':
+        stdin = common.continuereader(stdin, sys.stdout.write)
+
+    environ['wsgi.input'] = stdin
     environ['wsgi.errors'] = sys.stderr
     environ['wsgi.version'] = (1, 0)
     environ['wsgi.multithread'] = False
--- a/mercurial/hook.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/hook.py	Sat Jun 18 17:03:01 2011 -0500
@@ -109,7 +109,7 @@
     else:
         r = util.system(cmd, environ=env, cwd=cwd)
     if r:
-        desc, r = util.explain_exit(r)
+        desc, r = util.explainexit(r)
         if throw:
             raise util.Abort(_('%s hook %s') % (name, desc))
         ui.warn(_('warning: %s hook %s\n') % (name, desc))
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mercurial/httpclient/__init__.py	Sat Jun 18 17:03:01 2011 -0500
@@ -0,0 +1,698 @@
+# Copyright 2010, Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+"""Improved HTTP/1.1 client library
+
+This library contains an HTTPConnection which is similar to the one in
+httplib, but has several additional features:
+
+  * supports keepalives natively
+  * uses select() to block for incoming data
+  * notices when the server responds early to a request
+  * implements ssl inline instead of in a different class
+"""
+
+import cStringIO
+import errno
+import httplib
+import logging
+import rfc822
+import select
+import socket
+
+import socketutil
+
+logger = logging.getLogger(__name__)
+
+__all__ = ['HTTPConnection', 'HTTPResponse']
+
+HTTP_VER_1_0 = 'HTTP/1.0'
+HTTP_VER_1_1 = 'HTTP/1.1'
+
+_LEN_CLOSE_IS_END = -1
+
+OUTGOING_BUFFER_SIZE = 1 << 15
+INCOMING_BUFFER_SIZE = 1 << 20
+
+HDR_ACCEPT_ENCODING = 'accept-encoding'
+HDR_CONNECTION_CTRL = 'connection'
+HDR_CONTENT_LENGTH = 'content-length'
+HDR_XFER_ENCODING = 'transfer-encoding'
+
+XFER_ENCODING_CHUNKED = 'chunked'
+
+CONNECTION_CLOSE = 'close'
+
+EOL = '\r\n'
+_END_HEADERS = EOL * 2
+
+# Based on some searching around, 1 second seems like a reasonable
+# default here.
+TIMEOUT_ASSUME_CONTINUE = 1
+TIMEOUT_DEFAULT = None
+
+
+class HTTPResponse(object):
+    """Response from an HTTP server.
+
+    The response will continue to load as available. If you need the
+    complete response before continuing, check the .complete() method.
+    """
+    def __init__(self, sock, timeout):
+        self.sock = sock
+        self.raw_response = ''
+        self._body = None
+        self._headers_len = 0
+        self._content_len = 0
+        self.headers = None
+        self.will_close = False
+        self.status_line = ''
+        self.status = None
+        self.http_version = None
+        self.reason = None
+        self._chunked = False
+        self._chunked_done = False
+        self._chunked_until_next = 0
+        self._chunked_skip_bytes = 0
+        self._chunked_preloaded_block = None
+
+        self._read_location = 0
+        self._eol = EOL
+
+        self._timeout = timeout
+
+    @property
+    def _end_headers(self):
+        return self._eol * 2
+
+    def complete(self):
+        """Returns true if this response is completely loaded.
+
+        Note that if this is a connection where complete means the
+        socket is closed, this will nearly always return False, even
+        in cases where all the data has actually been loaded.
+        """
+        if self._chunked:
+            return self._chunked_done
+        if self._content_len == _LEN_CLOSE_IS_END:
+            return False
+        return self._body is not None and len(self._body) >= self._content_len
+
+    def readline(self):
+        """Read a single line from the response body.
+
+        This may block until either a line ending is found or the
+        response is complete.
+        """
+        eol = self._body.find('\n', self._read_location)
+        while eol == -1 and not self.complete():
+            self._select()
+            eol = self._body.find('\n', self._read_location)
+        if eol != -1:
+            eol += 1
+        else:
+            eol = len(self._body)
+        data = self._body[self._read_location:eol]
+        self._read_location = eol
+        return data
+
+    def read(self, length=None):
+        # if length is None, unbounded read
+        while (not self.complete()  # never select on a finished read
+               and (not length  # unbounded, so we wait for complete()
+                    or (self._read_location + length) > len(self._body))):
+            self._select()
+        if not length:
+            length = len(self._body) - self._read_location
+        elif len(self._body) < (self._read_location + length):
+            length = len(self._body) - self._read_location
+        r = self._body[self._read_location:self._read_location + length]
+        self._read_location += len(r)
+        if self.complete() and self.will_close:
+            self.sock.close()
+        return r
+
+    def _select(self):
+        r, _, _ = select.select([self.sock], [], [], self._timeout)
+        if not r:
+            # socket was not readable. If the response is not complete
+            # and we're not a _LEN_CLOSE_IS_END response, raise a timeout.
+            # If we are a _LEN_CLOSE_IS_END response and we have no data,
+            # raise a timeout.
+            if not (self.complete() or
+                    (self._content_len == _LEN_CLOSE_IS_END and self._body)):
+                logger.info('timed out with timeout of %s', self._timeout)
+                raise HTTPTimeoutException('timeout reading data')
+            logger.info('cl: %r body: %r', self._content_len, self._body)
+        try:
+            data = self.sock.recv(INCOMING_BUFFER_SIZE)
+        except socket.sslerror, e:
+            if e.args[0] != socket.SSL_ERROR_WANT_READ:
+                raise
+            logger.debug('SSL_WANT_READ in _select, should retry later')
+            return True
+        logger.debug('response read %d data during _select', len(data))
+        if not data:
+            if self.headers and self._content_len == _LEN_CLOSE_IS_END:
+                self._content_len = len(self._body)
+            return False
+        else:
+            self._load_response(data)
+            return True
+
+    def _chunked_parsedata(self, data):
+        if self._chunked_preloaded_block:
+            data = self._chunked_preloaded_block + data
+            self._chunked_preloaded_block = None
+        while data:
+            logger.debug('looping with %d data remaining', len(data))
+            # Slice out anything we should skip
+            if self._chunked_skip_bytes:
+                if len(data) <= self._chunked_skip_bytes:
+                    self._chunked_skip_bytes -= len(data)
+                    data = ''
+                    break
+                else:
+                    data = data[self._chunked_skip_bytes:]
+                    self._chunked_skip_bytes = 0
+
+            # determine how much is until the next chunk
+            if self._chunked_until_next:
+                amt = self._chunked_until_next
+                logger.debug('reading remaining %d of existing chunk', amt)
+                self._chunked_until_next = 0
+                body = data
+            else:
+                try:
+                    amt, body = data.split(self._eol, 1)
+                except ValueError:
+                    self._chunked_preloaded_block = data
+                    logger.debug('saving %r as a preloaded block for chunked',
+                                 self._chunked_preloaded_block)
+                    return
+                amt = int(amt, base=16)
+                logger.debug('reading chunk of length %d', amt)
+                if amt == 0:
+                    self._chunked_done = True
+
+            # read through end of what we have or the chunk
+            self._body += body[:amt]
+            if len(body) >= amt:
+                data = body[amt:]
+                self._chunked_skip_bytes = len(self._eol)
+            else:
+                self._chunked_until_next = amt - len(body)
+                self._chunked_skip_bytes = 0
+                data = ''
+
+    def _load_response(self, data):
+        if self._chunked:
+            self._chunked_parsedata(data)
+            return
+        elif self._body is not None:
+            self._body += data
+            return
+
+        # We haven't seen end of headers yet
+        self.raw_response += data
+        # This is a bogus server with bad line endings
+        if self._eol not in self.raw_response:
+            for bad_eol in ('\n', '\r'):
+                if (bad_eol in self.raw_response
+                    # verify that bad_eol is not the end of the incoming data
+                    # as this could be a response line that just got
+                    # split between \r and \n.
+                    and (self.raw_response.index(bad_eol) <
+                         (len(self.raw_response) - 1))):
+                    logger.info('bogus line endings detected, '
+                                'using %r for EOL', bad_eol)
+                    self._eol = bad_eol
+                    break
+        # exit early if not at end of headers
+        if self._end_headers not in self.raw_response or self.headers:
+            return
+
+        # handle 100-continue response
+        hdrs, body = self.raw_response.split(self._end_headers, 1)
+        http_ver, status = hdrs.split(' ', 1)
+        if status.startswith('100'):
+            self.raw_response = body
+            logger.debug('continue seen, setting body to %r', body)
+            return
+
+        # arriving here means we should parse response headers
+        # as all headers have arrived completely
+        hdrs, body = self.raw_response.split(self._end_headers, 1)
+        del self.raw_response
+        if self._eol in hdrs:
+            self.status_line, hdrs = hdrs.split(self._eol, 1)
+        else:
+            self.status_line = hdrs
+            hdrs = ''
+        # TODO HTTP < 1.0 support
+        (self.http_version, self.status,
+         self.reason) = self.status_line.split(' ', 2)
+        self.status = int(self.status)
+        if self._eol != EOL:
+            hdrs = hdrs.replace(self._eol, '\r\n')
+        headers = rfc822.Message(cStringIO.StringIO(hdrs))
+        if HDR_CONTENT_LENGTH in headers:
+            self._content_len = int(headers[HDR_CONTENT_LENGTH])
+        if self.http_version == HTTP_VER_1_0:
+            self.will_close = True
+        elif HDR_CONNECTION_CTRL in headers:
+            self.will_close = (
+                headers[HDR_CONNECTION_CTRL].lower() == CONNECTION_CLOSE)
+            if self._content_len == 0:
+                self._content_len = _LEN_CLOSE_IS_END
+        if (HDR_XFER_ENCODING in headers
+            and headers[HDR_XFER_ENCODING].lower() == XFER_ENCODING_CHUNKED):
+            self._body = ''
+            self._chunked_parsedata(body)
+            self._chunked = True
+        if self._body is None:
+            self._body = body
+        self.headers = headers
+
+
+class HTTPConnection(object):
+    """Connection to a single http server.
+
+    Supports 100-continue and keepalives natively. Uses select() for
+    non-blocking socket operations.
+    """
+    http_version = HTTP_VER_1_1
+    response_class = HTTPResponse
+
+    def __init__(self, host, port=None, use_ssl=None, ssl_validator=None,
+                 timeout=TIMEOUT_DEFAULT,
+                 continue_timeout=TIMEOUT_ASSUME_CONTINUE,
+                 proxy_hostport=None, **ssl_opts):
+        """Create a new HTTPConnection.
+
+        Args:
+          host: The host to which we'll connect.
+          port: Optional. The port over which we'll connect. Default 80 for
+                non-ssl, 443 for ssl.
+          use_ssl: Optional. Wether to use ssl. Defaults to False if port is
+                   not 443, true if port is 443.
+          ssl_validator: a function(socket) to validate the ssl cert
+          timeout: Optional. Connection timeout, default is TIMEOUT_DEFAULT.
+          continue_timeout: Optional. Timeout for waiting on an expected
+                   "100 Continue" response. Default is TIMEOUT_ASSUME_CONTINUE.
+          proxy_hostport: Optional. Tuple of (host, port) to use as an http
+                       proxy for the connection. Default is to not use a proxy.
+        """
+        if port is None and host.count(':') == 1 or ']:' in host:
+            host, port = host.rsplit(':', 1)
+            port = int(port)
+            if '[' in host:
+                host = host[1:-1]
+        if use_ssl is None and port is None:
+            use_ssl = False
+            port = 80
+        elif use_ssl is None:
+            use_ssl = (port == 443)
+        elif port is None:
+            port = (use_ssl and 443 or 80)
+        self.port = port
+        if use_ssl and not socketutil.have_ssl:
+            raise Exception('ssl requested but unavailable on this Python')
+        self.ssl = use_ssl
+        self.ssl_opts = ssl_opts
+        self._ssl_validator = ssl_validator
+        self.host = host
+        self.sock = None
+        self._current_response = None
+        self._current_response_taken = False
+        if proxy_hostport is None:
+            self._proxy_host = self._proxy_port = None
+        else:
+            self._proxy_host, self._proxy_port = proxy_hostport
+
+        self.timeout = timeout
+        self.continue_timeout = continue_timeout
+
+    def _connect(self):
+        """Connect to the host and port specified in __init__."""
+        if self.sock:
+            return
+        if self._proxy_host is not None:
+            logger.info('Connecting to http proxy %s:%s',
+                        self._proxy_host, self._proxy_port)
+            sock = socketutil.create_connection((self._proxy_host,
+                                                 self._proxy_port))
+            if self.ssl:
+                # TODO proxy header support
+                data = self.buildheaders('CONNECT', '%s:%d' % (self.host,
+                                                               self.port),
+                                         {}, HTTP_VER_1_0)
+                sock.send(data)
+                sock.setblocking(0)
+                r = self.response_class(sock, self.timeout)
+                timeout_exc = HTTPTimeoutException(
+                    'Timed out waiting for CONNECT response from proxy')
+                while not r.complete():
+                    try:
+                        if not r._select():
+                            raise timeout_exc
+                    except HTTPTimeoutException:
+                        # This raise/except pattern looks goofy, but
+                        # _select can raise the timeout as well as the
+                        # loop body. I wish it wasn't this convoluted,
+                        # but I don't have a better solution
+                        # immediately handy.
+                        raise timeout_exc
+                if r.status != 200:
+                    raise HTTPProxyConnectFailedException(
+                        'Proxy connection failed: %d %s' % (r.status,
+                                                            r.read()))
+                logger.info('CONNECT (for SSL) to %s:%s via proxy succeeded.',
+                            self.host, self.port)
+        else:
+            sock = socketutil.create_connection((self.host, self.port))
+        if self.ssl:
+            logger.debug('wrapping socket for ssl with options %r',
+                         self.ssl_opts)
+            sock = socketutil.wrap_socket(sock, **self.ssl_opts)
+            if self._ssl_validator:
+                self._ssl_validator(sock)
+        sock.setblocking(0)
+        self.sock = sock
+
+    def buildheaders(self, method, path, headers, http_ver):
+        if self.ssl and self.port == 443 or self.port == 80:
+            # default port for protocol, so leave it out
+            hdrhost = self.host
+        else:
+            # include nonstandard port in header
+            if ':' in self.host:  # must be IPv6
+                hdrhost = '[%s]:%d' % (self.host, self.port)
+            else:
+                hdrhost = '%s:%d' % (self.host, self.port)
+        if self._proxy_host and not self.ssl:
+            # When talking to a regular http proxy we must send the
+            # full URI, but in all other cases we must not (although
+            # technically RFC 2616 says servers must accept our
+            # request if we screw up, experimentally few do that
+            # correctly.)
+            assert path[0] == '/', 'path must start with a /'
+            path = 'http://%s%s' % (hdrhost, path)
+        outgoing = ['%s %s %s%s' % (method, path, http_ver, EOL)]
+        headers['host'] = ('Host', hdrhost)
+        headers[HDR_ACCEPT_ENCODING] = (HDR_ACCEPT_ENCODING, 'identity')
+        for hdr, val in headers.itervalues():
+            outgoing.append('%s: %s%s' % (hdr, val, EOL))
+        outgoing.append(EOL)
+        return ''.join(outgoing)
+
+    def close(self):
+        """Close the connection to the server.
+
+        This is a no-op if the connection is already closed. The
+        connection may automatically close if requessted by the server
+        or required by the nature of a response.
+        """
+        if self.sock is None:
+            return
+        self.sock.close()
+        self.sock = None
+        logger.info('closed connection to %s on %s', self.host, self.port)
+
+    def busy(self):
+        """Returns True if this connection object is currently in use.
+
+        If a response is still pending, this will return True, even if
+        the request has finished sending. In the future,
+        HTTPConnection may transparently juggle multiple connections
+        to the server, in which case this will be useful to detect if
+        any of those connections is ready for use.
+        """
+        cr = self._current_response
+        if cr is not None:
+            if self._current_response_taken:
+                if cr.will_close:
+                    self.sock = None
+                    self._current_response = None
+                    return False
+                elif cr.complete():
+                    self._current_response = None
+                    return False
+            return True
+        return False
+
+    def request(self, method, path, body=None, headers={},
+                expect_continue=False):
+        """Send a request to the server.
+
+        For increased flexibility, this does not return the response
+        object. Future versions of HTTPConnection that juggle multiple
+        sockets will be able to send (for example) 5 requests all at
+        once, and then let the requests arrive as data is
+        available. Use the `getresponse()` method to retrieve the
+        response.
+        """
+        if self.busy():
+            raise httplib.CannotSendRequest(
+                'Can not send another request before '
+                'current response is read!')
+        self._current_response_taken = False
+
+        logger.info('sending %s request for %s to %s on port %s',
+                    method, path, self.host, self.port)
+        hdrs = dict((k.lower(), (k, v)) for k, v in headers.iteritems())
+        if hdrs.get('expect', ('', ''))[1].lower() == '100-continue':
+            expect_continue = True
+        elif expect_continue:
+            hdrs['expect'] = ('Expect', '100-Continue')
+
+        chunked = False
+        if body and HDR_CONTENT_LENGTH not in hdrs:
+            if getattr(body, '__len__', False):
+                hdrs[HDR_CONTENT_LENGTH] = (HDR_CONTENT_LENGTH, len(body))
+            elif getattr(body, 'read', False):
+                hdrs[HDR_XFER_ENCODING] = (HDR_XFER_ENCODING,
+                                           XFER_ENCODING_CHUNKED)
+                chunked = True
+            else:
+                raise BadRequestData('body has no __len__() nor read()')
+
+        self._connect()
+        outgoing_headers = self.buildheaders(
+            method, path, hdrs, self.http_version)
+        response = None
+        first = True
+
+        def reconnect(where):
+            logger.info('reconnecting during %s', where)
+            self.close()
+            self._connect()
+
+        while ((outgoing_headers or body)
+               and not (response and response.complete())):
+            select_timeout = self.timeout
+            out = outgoing_headers or body
+            blocking_on_continue = False
+            if expect_continue and not outgoing_headers and not (
+                response and response.headers):
+                logger.info(
+                    'waiting up to %s seconds for'
+                    ' continue response from server',
+                    self.continue_timeout)
+                select_timeout = self.continue_timeout
+                blocking_on_continue = True
+                out = False
+            if out:
+                w = [self.sock]
+            else:
+                w = []
+            r, w, x = select.select([self.sock], w, [], select_timeout)
+            # if we were expecting a 100 continue and it's been long
+            # enough, just go ahead and assume it's ok. This is the
+            # recommended behavior from the RFC.
+            if r == w == x == []:
+                if blocking_on_continue:
+                    expect_continue = False
+                    logger.info('no response to continue expectation from '
+                                'server, optimistically sending request body')
+                else:
+                    raise HTTPTimeoutException('timeout sending data')
+            # TODO exceptional conditions with select? (what are those be?)
+            # TODO if the response is loading, must we finish sending at all?
+            #
+            # Certainly not if it's going to close the connection and/or
+            # the response is already done...I think.
+            was_first = first
+
+            # incoming data
+            if r:
+                try:
+                    try:
+                        data = r[0].recv(INCOMING_BUFFER_SIZE)
+                    except socket.sslerror, e:
+                        if e.args[0] != socket.SSL_ERROR_WANT_READ:
+                            raise
+                        logger.debug(
+                            'SSL_WANT_READ while sending data, retrying...')
+                        continue
+                    if not data:
+                        logger.info('socket appears closed in read')
+                        self.sock = None
+                        self._current_response = None
+                        # This if/elif ladder is a bit subtle,
+                        # comments in each branch should help.
+                        if response is not None and (
+                            response.complete() or
+                            response._content_len == _LEN_CLOSE_IS_END):
+                            # Server responded completely and then
+                            # closed the socket. We should just shut
+                            # things down and let the caller get their
+                            # response.
+                            logger.info('Got an early response, '
+                                        'aborting remaining request.')
+                            break
+                        elif was_first and response is None:
+                            # Most likely a keepalive that got killed
+                            # on the server's end. Commonly happens
+                            # after getting a really large response
+                            # from the server.
+                            logger.info(
+                                'Connection appeared closed in read on first'
+                                ' request loop iteration, will retry.')
+                            reconnect('read')
+                            continue
+                        else:
+                            # We didn't just send the first data hunk,
+                            # and either have a partial response or no
+                            # response at all. There's really nothing
+                            # meaningful we can do here.
+                            raise HTTPStateError(
+                                'Connection appears closed after '
+                                'some request data was written, but the '
+                                'response was missing or incomplete!')
+                    logger.debug('read %d bytes in request()', len(data))
+                    if response is None:
+                        response = self.response_class(r[0], self.timeout)
+                    response._load_response(data)
+                    # Jump to the next select() call so we load more
+                    # data if the server is still sending us content.
+                    continue
+                except socket.error, e:
+                    if e[0] != errno.EPIPE and not was_first:
+                        raise
+                    if (response._content_len
+                        and response._content_len != _LEN_CLOSE_IS_END):
+                        outgoing_headers = sent_data + outgoing_headers
+                        reconnect('read')
+
+            # outgoing data
+            if w and out:
+                try:
+                    if getattr(out, 'read', False):
+                        data = out.read(OUTGOING_BUFFER_SIZE)
+                        if not data:
+                            continue
+                        if len(data) < OUTGOING_BUFFER_SIZE:
+                            if chunked:
+                                body = '0' + EOL + EOL
+                            else:
+                                body = None
+                        if chunked:
+                            out = hex(len(data))[2:] + EOL + data + EOL
+                        else:
+                            out = data
+                    amt = w[0].send(out)
+                except socket.error, e:
+                    if e[0] == socket.SSL_ERROR_WANT_WRITE and self.ssl:
+                        # This means that SSL hasn't flushed its buffer into
+                        # the socket yet.
+                        # TODO: find a way to block on ssl flushing its buffer
+                        # similar to selecting on a raw socket.
+                        continue
+                    elif (e[0] not in (errno.ECONNRESET, errno.EPIPE)
+                          and not first):
+                        raise
+                    reconnect('write')
+                    amt = self.sock.send(out)
+                logger.debug('sent %d', amt)
+                first = False
+                # stash data we think we sent in case the socket breaks
+                # when we read from it
+                if was_first:
+                    sent_data = out[:amt]
+                if out is body:
+                    body = out[amt:]
+                else:
+                    outgoing_headers = out[amt:]
+
+        # close if the server response said to or responded before eating
+        # the whole request
+        if response is None:
+            response = self.response_class(self.sock, self.timeout)
+        complete = response.complete()
+        data_left = bool(outgoing_headers or body)
+        if data_left:
+            logger.info('stopped sending request early, '
+                         'will close the socket to be safe.')
+            response.will_close = True
+        if response.will_close:
+            # The socket will be closed by the response, so we disown
+            # the socket
+            self.sock = None
+        self._current_response = response
+
+    def getresponse(self):
+        if self._current_response is None:
+            raise httplib.ResponseNotReady()
+        r = self._current_response
+        while r.headers is None:
+            r._select()
+        if r.will_close:
+            self.sock = None
+            self._current_response = None
+        elif r.complete():
+            self._current_response = None
+        else:
+            self._current_response_taken = True
+        return r
+
+
+class HTTPTimeoutException(httplib.HTTPException):
+    """A timeout occurred while waiting on the server."""
+
+
+class BadRequestData(httplib.HTTPException):
+    """Request body object has neither __len__ nor read."""
+
+
+class HTTPProxyConnectFailedException(httplib.HTTPException):
+    """Connecting to the HTTP proxy failed."""
+
+class HTTPStateError(httplib.HTTPException):
+    """Invalid internal state encountered."""
+# no-check-code
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mercurial/httpclient/socketutil.py	Sat Jun 18 17:03:01 2011 -0500
@@ -0,0 +1,134 @@
+# Copyright 2010, Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+"""Abstraction to simplify socket use for Python < 2.6
+
+This will attempt to use the ssl module and the new
+socket.create_connection method, but fall back to the old
+methods if those are unavailable.
+"""
+import logging
+import socket
+
+logger = logging.getLogger(__name__)
+
+try:
+    import ssl
+    ssl.wrap_socket  # make demandimporters load the module
+    have_ssl = True
+except ImportError:
+    import httplib
+    import urllib2
+    have_ssl = getattr(urllib2, 'HTTPSHandler', False)
+    ssl = False
+
+
+try:
+    create_connection = socket.create_connection
+except AttributeError:
+    def create_connection(address):
+        host, port = address
+        msg = "getaddrinfo returns an empty list"
+        sock = None
+        for res in socket.getaddrinfo(host, port, 0,
+                                      socket.SOCK_STREAM):
+            af, socktype, proto, _canonname, sa = res
+            try:
+                sock = socket.socket(af, socktype, proto)
+                logger.info("connect: (%s, %s)", host, port)
+                sock.connect(sa)
+            except socket.error, msg:
+                logger.info('connect fail: %s %s', host, port)
+                if sock:
+                    sock.close()
+                sock = None
+                continue
+            break
+        if not sock:
+            raise socket.error, msg
+        return sock
+
+if ssl:
+    wrap_socket = ssl.wrap_socket
+    CERT_NONE = ssl.CERT_NONE
+    CERT_OPTIONAL = ssl.CERT_OPTIONAL
+    CERT_REQUIRED = ssl.CERT_REQUIRED
+    PROTOCOL_SSLv2 = ssl.PROTOCOL_SSLv2
+    PROTOCOL_SSLv3 = ssl.PROTOCOL_SSLv3
+    PROTOCOL_SSLv23 = ssl.PROTOCOL_SSLv23
+    PROTOCOL_TLSv1 = ssl.PROTOCOL_TLSv1
+else:
+    class FakeSocket(httplib.FakeSocket):
+        """Socket wrapper that supports SSL.
+        """
+        # backport the behavior from Python 2.6, which is to busy wait
+        # on the socket instead of anything nice. Sigh.
+        # See http://bugs.python.org/issue3890 for more info.
+        def recv(self, buflen=1024, flags=0):
+            """ssl-aware wrapper around socket.recv
+            """
+            if flags != 0:
+                raise ValueError(
+                    "non-zero flags not allowed in calls to recv() on %s" %
+                    self.__class__)
+            while True:
+                try:
+                    return self._ssl.read(buflen)
+                except socket.sslerror, x:
+                    if x.args[0] == socket.SSL_ERROR_WANT_READ:
+                        continue
+                    else:
+                        raise x
+
+    PROTOCOL_SSLv2 = 0
+    PROTOCOL_SSLv3 = 1
+    PROTOCOL_SSLv23 = 2
+    PROTOCOL_TLSv1 = 3
+
+    CERT_NONE = 0
+    CERT_OPTIONAL = 1
+    CERT_REQUIRED = 2
+
+    def wrap_socket(sock, keyfile=None, certfile=None,
+                server_side=False, cert_reqs=CERT_NONE,
+                ssl_version=PROTOCOL_SSLv23, ca_certs=None,
+                do_handshake_on_connect=True,
+                suppress_ragged_eofs=True):
+        if cert_reqs != CERT_NONE and ca_certs:
+            raise CertificateValidationUnsupported(
+                'SSL certificate validation requires the ssl module'
+                '(included in Python 2.6 and later.)')
+        sslob = socket.ssl(sock)
+        # borrow httplib's workaround for no ssl.wrap_socket
+        sock = FakeSocket(sock, sslob)
+        return sock
+
+
+class CertificateValidationUnsupported(Exception):
+    """Exception raised when cert validation is requested but unavailable."""
+# no-check-code
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mercurial/httpclient/tests/__init__.py	Sat Jun 18 17:03:01 2011 -0500
@@ -0,0 +1,1 @@
+# no-check-code
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mercurial/httpclient/tests/simple_http_test.py	Sat Jun 18 17:03:01 2011 -0500
@@ -0,0 +1,386 @@
+# Copyright 2010, Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+import socket
+import unittest
+
+import http
+
+# relative import to ease embedding the library
+import util
+
+
+class SimpleHttpTest(util.HttpTestBase, unittest.TestCase):
+
+    def _run_simple_test(self, host, server_data, expected_req, expected_data):
+        con = http.HTTPConnection(host)
+        con._connect()
+        con.sock.data = server_data
+        con.request('GET', '/')
+
+        self.assertStringEqual(expected_req, con.sock.sent)
+        self.assertEqual(expected_data, con.getresponse().read())
+
+    def test_broken_data_obj(self):
+        con = http.HTTPConnection('1.2.3.4:80')
+        con._connect()
+        self.assertRaises(http.BadRequestData,
+                          con.request, 'POST', '/', body=1)
+
+    def test_no_keepalive_http_1_0(self):
+        expected_request_one = """GET /remote/.hg/requires HTTP/1.1
+Host: localhost:9999
+range: bytes=0-
+accept-encoding: identity
+accept: application/mercurial-0.1
+user-agent: mercurial/proto-1.0
+
+""".replace('\n', '\r\n')
+        expected_response_headers = """HTTP/1.0 200 OK
+Server: SimpleHTTP/0.6 Python/2.6.1
+Date: Sun, 01 May 2011 13:56:57 GMT
+Content-type: application/octet-stream
+Content-Length: 33
+Last-Modified: Sun, 01 May 2011 13:56:56 GMT
+
+""".replace('\n', '\r\n')
+        expected_response_body = """revlogv1
+store
+fncache
+dotencode
+"""
+        con = http.HTTPConnection('localhost:9999')
+        con._connect()
+        con.sock.data = [expected_response_headers, expected_response_body]
+        con.request('GET', '/remote/.hg/requires',
+                    headers={'accept-encoding': 'identity',
+                             'range': 'bytes=0-',
+                             'accept': 'application/mercurial-0.1',
+                             'user-agent': 'mercurial/proto-1.0',
+                             })
+        self.assertStringEqual(expected_request_one, con.sock.sent)
+        self.assertEqual(con.sock.closed, False)
+        self.assertNotEqual(con.sock.data, [])
+        self.assert_(con.busy())
+        resp = con.getresponse()
+        self.assertStringEqual(resp.read(), expected_response_body)
+        self.failIf(con.busy())
+        self.assertEqual(con.sock, None)
+        self.assertEqual(resp.sock.data, [])
+        self.assert_(resp.sock.closed)
+
+    def test_multiline_header(self):
+        con = http.HTTPConnection('1.2.3.4:80')
+        con._connect()
+        con.sock.data = ['HTTP/1.1 200 OK\r\n',
+                         'Server: BogusServer 1.0\r\n',
+                         'Multiline: Value\r\n',
+                         '  Rest of value\r\n',
+                         'Content-Length: 10\r\n',
+                         '\r\n'
+                         '1234567890'
+                         ]
+        con.request('GET', '/')
+
+        expected_req = ('GET / HTTP/1.1\r\n'
+                        'Host: 1.2.3.4\r\n'
+                        'accept-encoding: identity\r\n\r\n')
+
+        self.assertEqual(('1.2.3.4', 80), con.sock.sa)
+        self.assertEqual(expected_req, con.sock.sent)
+        resp = con.getresponse()
+        self.assertEqual('1234567890', resp.read())
+        self.assertEqual(['Value\n Rest of value'],
+                         resp.headers.getheaders('multiline'))
+        # Socket should not be closed
+        self.assertEqual(resp.sock.closed, False)
+        self.assertEqual(con.sock.closed, False)
+
+    def testSimpleRequest(self):
+        con = http.HTTPConnection('1.2.3.4:80')
+        con._connect()
+        con.sock.data = ['HTTP/1.1 200 OK\r\n',
+                         'Server: BogusServer 1.0\r\n',
+                         'MultiHeader: Value\r\n'
+                         'MultiHeader: Other Value\r\n'
+                         'MultiHeader: One More!\r\n'
+                         'Content-Length: 10\r\n',
+                         '\r\n'
+                         '1234567890'
+                         ]
+        con.request('GET', '/')
+
+        expected_req = ('GET / HTTP/1.1\r\n'
+                        'Host: 1.2.3.4\r\n'
+                        'accept-encoding: identity\r\n\r\n')
+
+        self.assertEqual(('1.2.3.4', 80), con.sock.sa)
+        self.assertEqual(expected_req, con.sock.sent)
+        resp = con.getresponse()
+        self.assertEqual('1234567890', resp.read())
+        self.assertEqual(['Value', 'Other Value', 'One More!'],
+                         resp.headers.getheaders('multiheader'))
+        self.assertEqual(['BogusServer 1.0'],
+                         resp.headers.getheaders('server'))
+
+    def testHeaderlessResponse(self):
+        con = http.HTTPConnection('1.2.3.4', use_ssl=False)
+        con._connect()
+        con.sock.data = ['HTTP/1.1 200 OK\r\n',
+                         '\r\n'
+                         '1234567890'
+                         ]
+        con.request('GET', '/')
+
+        expected_req = ('GET / HTTP/1.1\r\n'
+                        'Host: 1.2.3.4\r\n'
+                        'accept-encoding: identity\r\n\r\n')
+
+        self.assertEqual(('1.2.3.4', 80), con.sock.sa)
+        self.assertEqual(expected_req, con.sock.sent)
+        resp = con.getresponse()
+        self.assertEqual('1234567890', resp.read())
+        self.assertEqual({}, dict(resp.headers))
+        self.assertEqual(resp.status, 200)
+
+    def testReadline(self):
+        con = http.HTTPConnection('1.2.3.4')
+        con._connect()
+        # make sure it trickles in one byte at a time
+        # so that we touch all the cases in readline
+        con.sock.data = list(''.join(
+            ['HTTP/1.1 200 OK\r\n',
+             'Server: BogusServer 1.0\r\n',
+             'Connection: Close\r\n',
+             '\r\n'
+             '1\n2\nabcdefg\n4\n5']))
+
+        expected_req = ('GET / HTTP/1.1\r\n'
+                        'Host: 1.2.3.4\r\n'
+                        'accept-encoding: identity\r\n\r\n')
+
+        con.request('GET', '/')
+        self.assertEqual(('1.2.3.4', 80), con.sock.sa)
+        self.assertEqual(expected_req, con.sock.sent)
+        r = con.getresponse()
+        for expected in ['1\n', '2\n', 'abcdefg\n', '4\n', '5']:
+            actual = r.readline()
+            self.assertEqual(expected, actual,
+                             'Expected %r, got %r' % (expected, actual))
+
+    def testIPv6(self):
+        self._run_simple_test('[::1]:8221',
+                        ['HTTP/1.1 200 OK\r\n',
+                         'Server: BogusServer 1.0\r\n',
+                         'Content-Length: 10',
+                         '\r\n\r\n'
+                         '1234567890'],
+                        ('GET / HTTP/1.1\r\n'
+                         'Host: [::1]:8221\r\n'
+                         'accept-encoding: identity\r\n\r\n'),
+                        '1234567890')
+        self._run_simple_test('::2',
+                        ['HTTP/1.1 200 OK\r\n',
+                         'Server: BogusServer 1.0\r\n',
+                         'Content-Length: 10',
+                         '\r\n\r\n'
+                         '1234567890'],
+                        ('GET / HTTP/1.1\r\n'
+                         'Host: ::2\r\n'
+                         'accept-encoding: identity\r\n\r\n'),
+                        '1234567890')
+        self._run_simple_test('[::3]:443',
+                        ['HTTP/1.1 200 OK\r\n',
+                         'Server: BogusServer 1.0\r\n',
+                         'Content-Length: 10',
+                         '\r\n\r\n'
+                         '1234567890'],
+                        ('GET / HTTP/1.1\r\n'
+                         'Host: ::3\r\n'
+                         'accept-encoding: identity\r\n\r\n'),
+                        '1234567890')
+
+    def testEarlyContinueResponse(self):
+        con = http.HTTPConnection('1.2.3.4:80')
+        con._connect()
+        sock = con.sock
+        sock.data = ['HTTP/1.1 403 Forbidden\r\n',
+                         'Server: BogusServer 1.0\r\n',
+                         'Content-Length: 18',
+                         '\r\n\r\n'
+                         "You can't do that."]
+        expected_req = self.doPost(con, expect_body=False)
+        self.assertEqual(('1.2.3.4', 80), sock.sa)
+        self.assertStringEqual(expected_req, sock.sent)
+        self.assertEqual("You can't do that.", con.getresponse().read())
+        self.assertEqual(sock.closed, True)
+
+    def testDeniedAfterContinueTimeoutExpires(self):
+        con = http.HTTPConnection('1.2.3.4:80')
+        con._connect()
+        sock = con.sock
+        sock.data = ['HTTP/1.1 403 Forbidden\r\n',
+                     'Server: BogusServer 1.0\r\n',
+                     'Content-Length: 18\r\n',
+                     'Connection: close',
+                     '\r\n\r\n'
+                     "You can't do that."]
+        sock.read_wait_sentinel = 'Dear server, send response!'
+        sock.close_on_empty = True
+        # send enough data out that we'll chunk it into multiple
+        # blocks and the socket will close before we can send the
+        # whole request.
+        post_body = ('This is some POST data\n' * 1024 * 32 +
+                     'Dear server, send response!\n' +
+                     'This is some POST data\n' * 1024 * 32)
+        expected_req = self.doPost(con, expect_body=False,
+                                   body_to_send=post_body)
+        self.assertEqual(('1.2.3.4', 80), sock.sa)
+        self.assert_('POST data\n' in sock.sent)
+        self.assert_('Dear server, send response!\n' in sock.sent)
+        # We expect not all of our data was sent.
+        self.assertNotEqual(sock.sent, expected_req)
+        self.assertEqual("You can't do that.", con.getresponse().read())
+        self.assertEqual(sock.closed, True)
+
+    def testPostData(self):
+        con = http.HTTPConnection('1.2.3.4:80')
+        con._connect()
+        sock = con.sock
+        sock.read_wait_sentinel = 'POST data'
+        sock.early_data = ['HTTP/1.1 100 Co', 'ntinue\r\n\r\n']
+        sock.data = ['HTTP/1.1 200 OK\r\n',
+                     'Server: BogusServer 1.0\r\n',
+                     'Content-Length: 16',
+                     '\r\n\r\n',
+                     "You can do that."]
+        expected_req = self.doPost(con, expect_body=True)
+        self.assertEqual(('1.2.3.4', 80), sock.sa)
+        self.assertEqual(expected_req, sock.sent)
+        self.assertEqual("You can do that.", con.getresponse().read())
+        self.assertEqual(sock.closed, False)
+
+    def testServerWithoutContinue(self):
+        con = http.HTTPConnection('1.2.3.4:80')
+        con._connect()
+        sock = con.sock
+        sock.read_wait_sentinel = 'POST data'
+        sock.data = ['HTTP/1.1 200 OK\r\n',
+                     'Server: BogusServer 1.0\r\n',
+                     'Content-Length: 16',
+                     '\r\n\r\n',
+                     "You can do that."]
+        expected_req = self.doPost(con, expect_body=True)
+        self.assertEqual(('1.2.3.4', 80), sock.sa)
+        self.assertEqual(expected_req, sock.sent)
+        self.assertEqual("You can do that.", con.getresponse().read())
+        self.assertEqual(sock.closed, False)
+
+    def testServerWithSlowContinue(self):
+        con = http.HTTPConnection('1.2.3.4:80')
+        con._connect()
+        sock = con.sock
+        sock.read_wait_sentinel = 'POST data'
+        sock.data = ['HTTP/1.1 100 ', 'Continue\r\n\r\n',
+                     'HTTP/1.1 200 OK\r\n',
+                     'Server: BogusServer 1.0\r\n',
+                     'Content-Length: 16',
+                     '\r\n\r\n',
+                     "You can do that."]
+        expected_req = self.doPost(con, expect_body=True)
+        self.assertEqual(('1.2.3.4', 80), sock.sa)
+        self.assertEqual(expected_req, sock.sent)
+        resp = con.getresponse()
+        self.assertEqual("You can do that.", resp.read())
+        self.assertEqual(200, resp.status)
+        self.assertEqual(sock.closed, False)
+
+    def testSlowConnection(self):
+        con = http.HTTPConnection('1.2.3.4:80')
+        con._connect()
+        # simulate one byte arriving at a time, to check for various
+        # corner cases
+        con.sock.data = list('HTTP/1.1 200 OK\r\n'
+                             'Server: BogusServer 1.0\r\n'
+                             'Content-Length: 10'
+                             '\r\n\r\n'
+                             '1234567890')
+        con.request('GET', '/')
+
+        expected_req = ('GET / HTTP/1.1\r\n'
+                        'Host: 1.2.3.4\r\n'
+                        'accept-encoding: identity\r\n\r\n')
+
+        self.assertEqual(('1.2.3.4', 80), con.sock.sa)
+        self.assertEqual(expected_req, con.sock.sent)
+        self.assertEqual('1234567890', con.getresponse().read())
+
+    def testTimeout(self):
+        con = http.HTTPConnection('1.2.3.4:80')
+        con._connect()
+        con.sock.data = []
+        con.request('GET', '/')
+        self.assertRaises(http.HTTPTimeoutException,
+                          con.getresponse)
+
+        expected_req = ('GET / HTTP/1.1\r\n'
+                        'Host: 1.2.3.4\r\n'
+                        'accept-encoding: identity\r\n\r\n')
+
+        self.assertEqual(('1.2.3.4', 80), con.sock.sa)
+        self.assertEqual(expected_req, con.sock.sent)
+
+    def test_conn_keep_alive_but_server_close_anyway(self):
+        sockets = []
+        def closingsocket(*args, **kwargs):
+            s = util.MockSocket(*args, **kwargs)
+            sockets.append(s)
+            s.data = ['HTTP/1.1 200 OK\r\n',
+                      'Server: BogusServer 1.0\r\n',
+                      'Connection: Keep-Alive\r\n',
+                      'Content-Length: 16',
+                      '\r\n\r\n',
+                      'You can do that.']
+            s.close_on_empty = True
+            return s
+
+        socket.socket = closingsocket
+        con = http.HTTPConnection('1.2.3.4:80')
+        con._connect()
+        con.request('GET', '/')
+        r1 = con.getresponse()
+        r1.read()
+        self.assertFalse(con.sock.closed)
+        self.assert_(con.sock.remote_closed)
+        con.request('GET', '/')
+        self.assertEqual(2, len(sockets))
+
+    def test_no_response_raises_response_not_ready(self):
+        con = http.HTTPConnection('foo')
+        self.assertRaises(http.httplib.ResponseNotReady, con.getresponse)
+# no-check-code
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mercurial/httpclient/tests/test_bogus_responses.py	Sat Jun 18 17:03:01 2011 -0500
@@ -0,0 +1,68 @@
+# Copyright 2010, Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+"""Tests against malformed responses.
+
+Server implementations that respond with only LF instead of CRLF have
+been observed. Checking against ones that use only CR is a hedge
+against that potential insanit.y
+"""
+import unittest
+
+import http
+
+# relative import to ease embedding the library
+import util
+
+
+class SimpleHttpTest(util.HttpTestBase, unittest.TestCase):
+
+    def bogusEOL(self, eol):
+        con = http.HTTPConnection('1.2.3.4:80')
+        con._connect()
+        con.sock.data = ['HTTP/1.1 200 OK%s' % eol,
+                         'Server: BogusServer 1.0%s' % eol,
+                         'Content-Length: 10',
+                         eol * 2,
+                         '1234567890']
+        con.request('GET', '/')
+
+        expected_req = ('GET / HTTP/1.1\r\n'
+                        'Host: 1.2.3.4\r\n'
+                        'accept-encoding: identity\r\n\r\n')
+
+        self.assertEqual(('1.2.3.4', 80), con.sock.sa)
+        self.assertEqual(expected_req, con.sock.sent)
+        self.assertEqual('1234567890', con.getresponse().read())
+
+    def testOnlyLinefeed(self):
+        self.bogusEOL('\n')
+
+    def testOnlyCarriageReturn(self):
+        self.bogusEOL('\r')
+# no-check-code
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mercurial/httpclient/tests/test_chunked_transfer.py	Sat Jun 18 17:03:01 2011 -0500
@@ -0,0 +1,137 @@
+# Copyright 2010, Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+import cStringIO
+import unittest
+
+import http
+
+# relative import to ease embedding the library
+import util
+
+
+def chunkedblock(x, eol='\r\n'):
+    r"""Make a chunked transfer-encoding block.
+
+    >>> chunkedblock('hi')
+    '2\r\nhi\r\n'
+    >>> chunkedblock('hi' * 10)
+    '14\r\nhihihihihihihihihihi\r\n'
+    >>> chunkedblock('hi', eol='\n')
+    '2\nhi\n'
+    """
+    return ''.join((hex(len(x))[2:], eol, x, eol))
+
+
+class ChunkedTransferTest(util.HttpTestBase, unittest.TestCase):
+    def testChunkedUpload(self):
+        con = http.HTTPConnection('1.2.3.4:80')
+        con._connect()
+        sock = con.sock
+        sock.read_wait_sentinel = '0\r\n\r\n'
+        sock.data = ['HTTP/1.1 200 OK\r\n',
+                     'Server: BogusServer 1.0\r\n',
+                     'Content-Length: 6',
+                     '\r\n\r\n',
+                     "Thanks"]
+
+        zz = 'zz\n'
+        con.request('POST', '/', body=cStringIO.StringIO(
+            (zz * (0x8010 / 3)) + 'end-of-body'))
+        expected_req = ('POST / HTTP/1.1\r\n'
+                        'transfer-encoding: chunked\r\n'
+                        'Host: 1.2.3.4\r\n'
+                        'accept-encoding: identity\r\n\r\n')
+        expected_req += chunkedblock('zz\n' * (0x8000 / 3) + 'zz')
+        expected_req += chunkedblock(
+            '\n' + 'zz\n' * ((0x1b - len('end-of-body')) / 3) + 'end-of-body')
+        expected_req += '0\r\n\r\n'
+        self.assertEqual(('1.2.3.4', 80), sock.sa)
+        self.assertStringEqual(expected_req, sock.sent)
+        self.assertEqual("Thanks", con.getresponse().read())
+        self.assertEqual(sock.closed, False)
+
+    def testChunkedDownload(self):
+        con = http.HTTPConnection('1.2.3.4:80')
+        con._connect()
+        sock = con.sock
+        sock.data = ['HTTP/1.1 200 OK\r\n',
+                     'Server: BogusServer 1.0\r\n',
+                     'transfer-encoding: chunked',
+                     '\r\n\r\n',
+                     chunkedblock('hi '),
+                     chunkedblock('there'),
+                     chunkedblock(''),
+                     ]
+        con.request('GET', '/')
+        self.assertStringEqual('hi there', con.getresponse().read())
+
+    def testChunkedDownloadBadEOL(self):
+        con = http.HTTPConnection('1.2.3.4:80')
+        con._connect()
+        sock = con.sock
+        sock.data = ['HTTP/1.1 200 OK\n',
+                     'Server: BogusServer 1.0\n',
+                     'transfer-encoding: chunked',
+                     '\n\n',
+                     chunkedblock('hi ', eol='\n'),
+                     chunkedblock('there', eol='\n'),
+                     chunkedblock('', eol='\n'),
+                     ]
+        con.request('GET', '/')
+        self.assertStringEqual('hi there', con.getresponse().read())
+
+    def testChunkedDownloadPartialChunkBadEOL(self):
+        con = http.HTTPConnection('1.2.3.4:80')
+        con._connect()
+        sock = con.sock
+        sock.data = ['HTTP/1.1 200 OK\n',
+                     'Server: BogusServer 1.0\n',
+                     'transfer-encoding: chunked',
+                     '\n\n',
+                     chunkedblock('hi ', eol='\n'),
+                     ] + list(chunkedblock('there\n' * 5, eol='\n')) + [
+                         chunkedblock('', eol='\n')]
+        con.request('GET', '/')
+        self.assertStringEqual('hi there\nthere\nthere\nthere\nthere\n',
+                               con.getresponse().read())
+
+    def testChunkedDownloadPartialChunk(self):
+        con = http.HTTPConnection('1.2.3.4:80')
+        con._connect()
+        sock = con.sock
+        sock.data = ['HTTP/1.1 200 OK\r\n',
+                     'Server: BogusServer 1.0\r\n',
+                     'transfer-encoding: chunked',
+                     '\r\n\r\n',
+                     chunkedblock('hi '),
+                     ] + list(chunkedblock('there\n' * 5)) + [chunkedblock('')]
+        con.request('GET', '/')
+        self.assertStringEqual('hi there\nthere\nthere\nthere\nthere\n',
+                               con.getresponse().read())
+# no-check-code
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mercurial/httpclient/tests/test_proxy_support.py	Sat Jun 18 17:03:01 2011 -0500
@@ -0,0 +1,135 @@
+# Copyright 2010, Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+import unittest
+import socket
+
+import http
+
+# relative import to ease embedding the library
+import util
+
+
+def make_preloaded_socket(data):
+    """Make a socket pre-loaded with data so it can be read during connect.
+
+    Useful for https proxy tests because we have to read from the
+    socket during _connect rather than later on.
+    """
+    def s(*args, **kwargs):
+        sock = util.MockSocket(*args, **kwargs)
+        sock.early_data = data[:]
+        return sock
+    return s
+
+
+class ProxyHttpTest(util.HttpTestBase, unittest.TestCase):
+
+    def _run_simple_test(self, host, server_data, expected_req, expected_data):
+        con = http.HTTPConnection(host)
+        con._connect()
+        con.sock.data = server_data
+        con.request('GET', '/')
+
+        self.assertEqual(expected_req, con.sock.sent)
+        self.assertEqual(expected_data, con.getresponse().read())
+
+    def testSimpleRequest(self):
+        con = http.HTTPConnection('1.2.3.4:80',
+                                  proxy_hostport=('magicproxy', 4242))
+        con._connect()
+        con.sock.data = ['HTTP/1.1 200 OK\r\n',
+                         'Server: BogusServer 1.0\r\n',
+                         'MultiHeader: Value\r\n'
+                         'MultiHeader: Other Value\r\n'
+                         'MultiHeader: One More!\r\n'
+                         'Content-Length: 10\r\n',
+                         '\r\n'
+                         '1234567890'
+                         ]
+        con.request('GET', '/')
+
+        expected_req = ('GET http://1.2.3.4/ HTTP/1.1\r\n'
+                        'Host: 1.2.3.4\r\n'
+                        'accept-encoding: identity\r\n\r\n')
+
+        self.assertEqual(('127.0.0.42', 4242), con.sock.sa)
+        self.assertStringEqual(expected_req, con.sock.sent)
+        resp = con.getresponse()
+        self.assertEqual('1234567890', resp.read())
+        self.assertEqual(['Value', 'Other Value', 'One More!'],
+                         resp.headers.getheaders('multiheader'))
+        self.assertEqual(['BogusServer 1.0'],
+                         resp.headers.getheaders('server'))
+
+    def testSSLRequest(self):
+        con = http.HTTPConnection('1.2.3.4:443',
+                                  proxy_hostport=('magicproxy', 4242))
+        socket.socket = make_preloaded_socket(
+            ['HTTP/1.1 200 OK\r\n',
+             'Server: BogusServer 1.0\r\n',
+             'Content-Length: 10\r\n',
+             '\r\n'
+             '1234567890'])
+        con._connect()
+        con.sock.data = ['HTTP/1.1 200 OK\r\n',
+                         'Server: BogusServer 1.0\r\n',
+                         'Content-Length: 10\r\n',
+                         '\r\n'
+                         '1234567890'
+                         ]
+        connect_sent = con.sock.sent
+        con.sock.sent = ''
+        con.request('GET', '/')
+
+        expected_connect = ('CONNECT 1.2.3.4:443 HTTP/1.0\r\n'
+                            'Host: 1.2.3.4\r\n'
+                            'accept-encoding: identity\r\n'
+                            '\r\n')
+        expected_request = ('GET / HTTP/1.1\r\n'
+                            'Host: 1.2.3.4\r\n'
+                            'accept-encoding: identity\r\n\r\n')
+
+        self.assertEqual(('127.0.0.42', 4242), con.sock.sa)
+        self.assertStringEqual(expected_connect, connect_sent)
+        self.assertStringEqual(expected_request, con.sock.sent)
+        resp = con.getresponse()
+        self.assertEqual(resp.status, 200)
+        self.assertEqual('1234567890', resp.read())
+        self.assertEqual(['BogusServer 1.0'],
+                         resp.headers.getheaders('server'))
+
+    def testSSLProxyFailure(self):
+        con = http.HTTPConnection('1.2.3.4:443',
+                                  proxy_hostport=('magicproxy', 4242))
+        socket.socket = make_preloaded_socket(
+            ['HTTP/1.1 407 Proxy Authentication Required\r\n\r\n'])
+        self.assertRaises(http.HTTPProxyConnectFailedException, con._connect)
+        self.assertRaises(http.HTTPProxyConnectFailedException,
+                          con.request, 'GET', '/')
+# no-check-code
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mercurial/httpclient/tests/test_ssl.py	Sat Jun 18 17:03:01 2011 -0500
@@ -0,0 +1,93 @@
+# Copyright 2011, Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+import unittest
+
+import http
+
+# relative import to ease embedding the library
+import util
+
+
+
+class HttpSslTest(util.HttpTestBase, unittest.TestCase):
+    def testSslRereadRequired(self):
+        con = http.HTTPConnection('1.2.3.4:443')
+        con._connect()
+        # extend the list instead of assign because of how
+        # MockSSLSocket works.
+        con.sock.data = ['HTTP/1.1 200 OK\r\n',
+                         'Server: BogusServer 1.0\r\n',
+                         'MultiHeader: Value\r\n'
+                         'MultiHeader: Other Value\r\n'
+                         'MultiHeader: One More!\r\n'
+                         'Content-Length: 10\r\n',
+                         '\r\n'
+                         '1234567890'
+                         ]
+        con.request('GET', '/')
+
+        expected_req = ('GET / HTTP/1.1\r\n'
+                        'Host: 1.2.3.4\r\n'
+                        'accept-encoding: identity\r\n\r\n')
+
+        self.assertEqual(('1.2.3.4', 443), con.sock.sa)
+        self.assertEqual(expected_req, con.sock.sent)
+        resp = con.getresponse()
+        self.assertEqual('1234567890', resp.read())
+        self.assertEqual(['Value', 'Other Value', 'One More!'],
+                         resp.headers.getheaders('multiheader'))
+        self.assertEqual(['BogusServer 1.0'],
+                         resp.headers.getheaders('server'))
+
+    def testSslRereadInEarlyResponse(self):
+        con = http.HTTPConnection('1.2.3.4:443')
+        con._connect()
+        con.sock.early_data = ['HTTP/1.1 200 OK\r\n',
+                               'Server: BogusServer 1.0\r\n',
+                               'MultiHeader: Value\r\n'
+                               'MultiHeader: Other Value\r\n'
+                               'MultiHeader: One More!\r\n'
+                               'Content-Length: 10\r\n',
+                               '\r\n'
+                               '1234567890'
+                               ]
+
+        expected_req = self.doPost(con, False)
+        self.assertEqual(None, con.sock,
+                         'Connection should have disowned socket')
+
+        resp = con.getresponse()
+        self.assertEqual(('1.2.3.4', 443), resp.sock.sa)
+        self.assertEqual(expected_req, resp.sock.sent)
+        self.assertEqual('1234567890', resp.read())
+        self.assertEqual(['Value', 'Other Value', 'One More!'],
+                         resp.headers.getheaders('multiheader'))
+        self.assertEqual(['BogusServer 1.0'],
+                         resp.headers.getheaders('server'))
+# no-check-code
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mercurial/httpclient/tests/util.py	Sat Jun 18 17:03:01 2011 -0500
@@ -0,0 +1,195 @@
+# Copyright 2010, Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+import difflib
+import socket
+
+import http
+
+
+class MockSocket(object):
+    """Mock non-blocking socket object.
+
+    This is ONLY capable of mocking a nonblocking socket.
+
+    Attributes:
+      early_data: data to always send as soon as end of headers is seen
+      data: a list of strings to return on recv(), with the
+            assumption that the socket would block between each
+            string in the list.
+      read_wait_sentinel: data that must be written to the socket before
+                          beginning the response.
+      close_on_empty: If true, close the socket when it runs out of data
+                      for the client.
+    """
+    def __init__(self, af, socktype, proto):
+        self.af = af
+        self.socktype = socktype
+        self.proto = proto
+
+        self.early_data = []
+        self.data = []
+        self.remote_closed = self.closed = False
+        self.close_on_empty = False
+        self.sent = ''
+        self.read_wait_sentinel = http._END_HEADERS
+
+    def close(self):
+        self.closed = True
+
+    def connect(self, sa):
+        self.sa = sa
+
+    def setblocking(self, timeout):
+        assert timeout == 0
+
+    def recv(self, amt=-1):
+        if self.early_data:
+            datalist = self.early_data
+        elif not self.data:
+            return ''
+        else:
+            datalist = self.data
+        if amt == -1:
+            return datalist.pop(0)
+        data = datalist.pop(0)
+        if len(data) > amt:
+            datalist.insert(0, data[amt:])
+        if not self.data and not self.early_data and self.close_on_empty:
+            self.remote_closed = True
+        return data[:amt]
+
+    @property
+    def ready_for_read(self):
+        return ((self.early_data and http._END_HEADERS in self.sent)
+                or (self.read_wait_sentinel in self.sent and self.data)
+                or self.closed or self.remote_closed)
+
+    def send(self, data):
+        # this is a horrible mock, but nothing needs us to raise the
+        # correct exception yet
+        assert not self.closed, 'attempted to write to a closed socket'
+        assert not self.remote_closed, ('attempted to write to a'
+                                        ' socket closed by the server')
+        if len(data) > 8192:
+            data = data[:8192]
+        self.sent += data
+        return len(data)
+
+
+def mockselect(r, w, x, timeout=0):
+    """Simple mock for select()
+    """
+    readable = filter(lambda s: s.ready_for_read, r)
+    return readable, w[:], []
+
+
+class MockSSLSocket(object):
+    def __init__(self, sock):
+        self._sock = sock
+        self._fail_recv = True
+
+    def __getattr__(self, key):
+        return getattr(self._sock, key)
+
+    def __setattr__(self, key, value):
+        if key not in ('_sock', '_fail_recv'):
+            return setattr(self._sock, key, value)
+        return object.__setattr__(self, key, value)
+
+    def recv(self, amt=-1):
+        try:
+            if self._fail_recv:
+                raise socket.sslerror(socket.SSL_ERROR_WANT_READ)
+            return self._sock.recv(amt=amt)
+        finally:
+            self._fail_recv = not self._fail_recv
+
+
+def mocksslwrap(sock, keyfile=None, certfile=None,
+                server_side=False, cert_reqs=http.socketutil.CERT_NONE,
+                ssl_version=http.socketutil.PROTOCOL_SSLv23, ca_certs=None,
+                do_handshake_on_connect=True,
+                suppress_ragged_eofs=True):
+    return MockSSLSocket(sock)
+
+
+def mockgetaddrinfo(host, port, unused, streamtype):
+    assert unused == 0
+    assert streamtype == socket.SOCK_STREAM
+    if host.count('.') != 3:
+        host = '127.0.0.42'
+    return [(socket.AF_INET, socket.SOCK_STREAM, socket.IPPROTO_TCP, '',
+             (host, port))]
+
+
+class HttpTestBase(object):
+    def setUp(self):
+        self.orig_socket = socket.socket
+        socket.socket = MockSocket
+
+        self.orig_getaddrinfo = socket.getaddrinfo
+        socket.getaddrinfo = mockgetaddrinfo
+
+        self.orig_select = http.select.select
+        http.select.select = mockselect
+
+        self.orig_sslwrap = http.socketutil.wrap_socket
+        http.socketutil.wrap_socket = mocksslwrap
+
+    def tearDown(self):
+        socket.socket = self.orig_socket
+        http.select.select = self.orig_select
+        http.socketutil.wrap_socket = self.orig_sslwrap
+        socket.getaddrinfo = self.orig_getaddrinfo
+
+    def assertStringEqual(self, l, r):
+        try:
+            self.assertEqual(l, r, ('failed string equality check, '
+                                    'see stdout for details'))
+        except:
+            add_nl = lambda li: map(lambda x: x + '\n', li)
+            print 'failed expectation:'
+            print ''.join(difflib.unified_diff(
+                add_nl(l.splitlines()), add_nl(r.splitlines()),
+                fromfile='expected', tofile='got'))
+            raise
+
+    def doPost(self, con, expect_body, body_to_send='This is some POST data'):
+        con.request('POST', '/', body=body_to_send,
+                    expect_continue=True)
+        expected_req = ('POST / HTTP/1.1\r\n'
+                        'Host: 1.2.3.4\r\n'
+                        'content-length: %d\r\n'
+                        'Expect: 100-Continue\r\n'
+                        'accept-encoding: identity\r\n\r\n' %
+                        len(body_to_send))
+        if expect_body:
+            expected_req += body_to_send
+        return expected_req
+# no-check-code
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mercurial/httpconnection.py	Sat Jun 18 17:03:01 2011 -0500
@@ -0,0 +1,268 @@
+# httpconnection.py - urllib2 handler for new http support
+#
+# Copyright 2005, 2006, 2007, 2008 Matt Mackall <mpm@selenic.com>
+# Copyright 2006, 2007 Alexis S. L. Carvalho <alexis@cecm.usp.br>
+# Copyright 2006 Vadim Gelfer <vadim.gelfer@gmail.com>
+# Copyright 2011 Google, Inc.
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2 or any later version.
+import logging
+import socket
+import urllib
+import urllib2
+import os
+
+from mercurial import httpclient
+from mercurial import sslutil
+from mercurial import util
+from mercurial.i18n import _
+
+# moved here from url.py to avoid a cycle
+class httpsendfile(object):
+    """This is a wrapper around the objects returned by python's "open".
+
+    Its purpose is to send file-like objects via HTTP and, to do so, it
+    defines a __len__ attribute to feed the Content-Length header.
+    """
+
+    def __init__(self, ui, *args, **kwargs):
+        # We can't just "self._data = open(*args, **kwargs)" here because there
+        # is an "open" function defined in this module that shadows the global
+        # one
+        self.ui = ui
+        self._data = open(*args, **kwargs)
+        self.seek = self._data.seek
+        self.close = self._data.close
+        self.write = self._data.write
+        self._len = os.fstat(self._data.fileno()).st_size
+        self._pos = 0
+        self._total = self._len / 1024 * 2
+
+    def read(self, *args, **kwargs):
+        try:
+            ret = self._data.read(*args, **kwargs)
+        except EOFError:
+            self.ui.progress(_('sending'), None)
+        self._pos += len(ret)
+        # We pass double the max for total because we currently have
+        # to send the bundle twice in the case of a server that
+        # requires authentication. Since we can't know until we try
+        # once whether authentication will be required, just lie to
+        # the user and maybe the push succeeds suddenly at 50%.
+        self.ui.progress(_('sending'), self._pos / 1024,
+                         unit=_('kb'), total=self._total)
+        return ret
+
+    def __len__(self):
+        return self._len
+
+# moved here from url.py to avoid a cycle
+def readauthforuri(ui, uri):
+    # Read configuration
+    config = dict()
+    for key, val in ui.configitems('auth'):
+        if '.' not in key:
+            ui.warn(_("ignoring invalid [auth] key '%s'\n") % key)
+            continue
+        group, setting = key.rsplit('.', 1)
+        gdict = config.setdefault(group, dict())
+        if setting in ('username', 'cert', 'key'):
+            val = util.expandpath(val)
+        gdict[setting] = val
+
+    # Find the best match
+    scheme, hostpath = uri.split('://', 1)
+    bestlen = 0
+    bestauth = None
+    for group, auth in config.iteritems():
+        prefix = auth.get('prefix')
+        if not prefix:
+            continue
+        p = prefix.split('://', 1)
+        if len(p) > 1:
+            schemes, prefix = [p[0]], p[1]
+        else:
+            schemes = (auth.get('schemes') or 'https').split()
+        if (prefix == '*' or hostpath.startswith(prefix)) and \
+            len(prefix) > bestlen and scheme in schemes:
+            bestlen = len(prefix)
+            bestauth = group, auth
+    return bestauth
+
+# Mercurial (at least until we can remove the old codepath) requires
+# that the http response object be sufficiently file-like, so we
+# provide a close() method here.
+class HTTPResponse(httpclient.HTTPResponse):
+    def close(self):
+        pass
+
+class HTTPConnection(httpclient.HTTPConnection):
+    response_class = HTTPResponse
+    def request(self, method, uri, body=None, headers={}):
+        if isinstance(body, httpsendfile):
+            body.seek(0)
+        httpclient.HTTPConnection.request(self, method, uri, body=body,
+                                          headers=headers)
+
+
+_configuredlogging = False
+LOGFMT = '%(levelname)s:%(name)s:%(lineno)d:%(message)s'
+# Subclass BOTH of these because otherwise urllib2 "helpfully"
+# reinserts them since it notices we don't include any subclasses of
+# them.
+class http2handler(urllib2.HTTPHandler, urllib2.HTTPSHandler):
+    def __init__(self, ui, pwmgr):
+        global _configuredlogging
+        urllib2.AbstractHTTPHandler.__init__(self)
+        self.ui = ui
+        self.pwmgr = pwmgr
+        self._connections = {}
+        loglevel = ui.config('ui', 'http2debuglevel', default=None)
+        if loglevel and not _configuredlogging:
+            _configuredlogging = True
+            logger = logging.getLogger('mercurial.httpclient')
+            logger.setLevel(getattr(logging, loglevel.upper()))
+            handler = logging.StreamHandler()
+            handler.setFormatter(logging.Formatter(LOGFMT))
+            logger.addHandler(handler)
+
+    def close_all(self):
+        """Close and remove all connection objects being kept for reuse."""
+        for openconns in self._connections.values():
+            for conn in openconns:
+                conn.close()
+        self._connections = {}
+
+    # shamelessly borrowed from urllib2.AbstractHTTPHandler
+    def do_open(self, http_class, req, use_ssl):
+        """Return an addinfourl object for the request, using http_class.
+
+        http_class must implement the HTTPConnection API from httplib.
+        The addinfourl return value is a file-like object.  It also
+        has methods and attributes including:
+            - info(): return a mimetools.Message object for the headers
+            - geturl(): return the original request URL
+            - code: HTTP status code
+        """
+        # If using a proxy, the host returned by get_host() is
+        # actually the proxy. On Python 2.6.1, the real destination
+        # hostname is encoded in the URI in the urllib2 request
+        # object. On Python 2.6.5, it's stored in the _tunnel_host
+        # attribute which has no accessor.
+        tunhost = getattr(req, '_tunnel_host', None)
+        host = req.get_host()
+        if tunhost:
+            proxyhost = host
+            host = tunhost
+        elif req.has_proxy():
+            proxyhost = req.get_host()
+            host = req.get_selector().split('://', 1)[1].split('/', 1)[0]
+        else:
+            proxyhost = None
+
+        if proxyhost:
+            if ':' in proxyhost:
+                # Note: this means we'll explode if we try and use an
+                # IPv6 http proxy. This isn't a regression, so we
+                # won't worry about it for now.
+                proxyhost, proxyport = proxyhost.rsplit(':', 1)
+            else:
+                proxyport = 3128 # squid default
+            proxy = (proxyhost, proxyport)
+        else:
+            proxy = None
+
+        if not host:
+            raise urllib2.URLError('no host given')
+
+        connkey = use_ssl, host, proxy
+        allconns = self._connections.get(connkey, [])
+        conns = [c for c in allconns if not c.busy()]
+        if conns:
+            h = conns[0]
+        else:
+            if allconns:
+                self.ui.debug('all connections for %s busy, making a new '
+                              'one\n' % host)
+            timeout = None
+            if req.timeout is not socket._GLOBAL_DEFAULT_TIMEOUT:
+                timeout = req.timeout
+            h = http_class(host, timeout=timeout, proxy_hostport=proxy)
+            self._connections.setdefault(connkey, []).append(h)
+
+        headers = dict(req.headers)
+        headers.update(req.unredirected_hdrs)
+        headers = dict(
+            (name.title(), val) for name, val in headers.items())
+        try:
+            path = req.get_selector()
+            if '://' in path:
+                path = path.split('://', 1)[1].split('/', 1)[1]
+            if path[0] != '/':
+                path = '/' + path
+            h.request(req.get_method(), path, req.data, headers)
+            r = h.getresponse()
+        except socket.error, err: # XXX what error?
+            raise urllib2.URLError(err)
+
+        # Pick apart the HTTPResponse object to get the addinfourl
+        # object initialized properly.
+        r.recv = r.read
+
+        resp = urllib.addinfourl(r, r.headers, req.get_full_url())
+        resp.code = r.status
+        resp.msg = r.reason
+        return resp
+
+    # httplib always uses the given host/port as the socket connect
+    # target, and then allows full URIs in the request path, which it
+    # then observes and treats as a signal to do proxying instead.
+    def http_open(self, req):
+        if req.get_full_url().startswith('https'):
+            return self.https_open(req)
+        return self.do_open(HTTPConnection, req, False)
+
+    def https_open(self, req):
+        res = readauthforuri(self.ui, req.get_full_url())
+        if res:
+            group, auth = res
+            self.auth = auth
+            self.ui.debug("using auth.%s.* for authentication\n" % group)
+        else:
+            self.auth = None
+        return self.do_open(self._makesslconnection, req, True)
+
+    def _makesslconnection(self, host, port=443, *args, **kwargs):
+        keyfile = None
+        certfile = None
+
+        if args: # key_file
+            keyfile = args.pop(0)
+        if args: # cert_file
+            certfile = args.pop(0)
+
+        # if the user has specified different key/cert files in
+        # hgrc, we prefer these
+        if self.auth and 'key' in self.auth and 'cert' in self.auth:
+            keyfile = self.auth['key']
+            certfile = self.auth['cert']
+
+        # let host port take precedence
+        if ':' in host and '[' not in host or ']:' in host:
+            host, port = host.rsplit(':', 1)
+            port = int(port)
+            if '[' in host:
+                host = host[1:-1]
+
+        if keyfile:
+            kwargs['keyfile'] = keyfile
+        if certfile:
+            kwargs['certfile'] = certfile
+
+        kwargs.update(sslutil.sslkwargs(self.ui, host))
+
+        con = HTTPConnection(host, port, use_ssl=True,
+                             ssl_validator=sslutil.validator(self.ui, host),
+                             **kwargs)
+        return con
--- a/mercurial/httprepo.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/httprepo.py	Sat Jun 18 17:03:01 2011 -0500
@@ -8,8 +8,8 @@
 
 from node import nullid
 from i18n import _
-import changegroup, statichttprepo, error, url, util, wireproto
-import os, urllib, urllib2, urlparse, zlib, httplib
+import changegroup, statichttprepo, error, httpconnection, url, util, wireproto
+import os, urllib, urllib2, zlib, httplib
 import errno, socket
 
 def zgenerator(f):
@@ -28,13 +28,13 @@
         self.path = path
         self.caps = None
         self.handler = None
-        scheme, netloc, urlpath, query, frag = urlparse.urlsplit(path)
-        if query or frag:
+        u = util.url(path)
+        if u.query or u.fragment:
             raise util.Abort(_('unsupported URL component: "%s"') %
-                             (query or frag))
+                             (u.query or u.fragment))
 
         # urllib cannot handle URLs with embedded user or passwd
-        self._url, authinfo = url.getauthinfo(path)
+        self._url, authinfo = u.authinfo()
 
         self.ui = ui
         self.ui.debug('using %s\n' % self._url)
@@ -52,10 +52,13 @@
 
     # look up capabilities only when needed
 
+    def _fetchcaps(self):
+        self.caps = set(self._call('capabilities').split())
+
     def get_caps(self):
         if self.caps is None:
             try:
-                self.caps = set(self._call('capabilities').split())
+                self._fetchcaps()
             except error.RepoError:
                 self.caps = set()
             self.ui.debug('capabilities: %s\n' %
@@ -72,9 +75,31 @@
             args['data'] = ''
         data = args.pop('data', None)
         headers = args.pop('headers', {})
+
+        if data and self.ui.configbool('ui', 'usehttp2', False):
+            headers['Expect'] = '100-Continue'
+
         self.ui.debug("sending %s command\n" % cmd)
-        q = {"cmd": cmd}
-        q.update(args)
+        q = [('cmd', cmd)]
+        headersize = 0
+        if len(args) > 0:
+            httpheader = self.capable('httpheader')
+            if httpheader:
+                headersize = int(httpheader.split(',')[0])
+        if headersize > 0:
+            # The headers can typically carry more data than the URL.
+            encargs = urllib.urlencode(sorted(args.items()))
+            headerfmt = 'X-HgArg-%s'
+            contentlen = headersize - len(headerfmt % '000' + ': \r\n')
+            headernum = 0
+            for i in xrange(0, len(encargs), contentlen):
+                headernum += 1
+                header = headerfmt % str(headernum)
+                headers[header] = encargs[i:i + contentlen]
+            varyheaders = [headerfmt % str(h) for h in range(1, headernum + 1)]
+            headers['Vary'] = ','.join(varyheaders)
+        else:
+            q += sorted(args.items())
         qs = '?%s' % urllib.urlencode(q)
         cu = "%s%s" % (self._url, qs)
         req = urllib2.Request(cu, data, headers)
@@ -110,12 +135,12 @@
         except AttributeError:
             proto = resp.headers.get('content-type', '')
 
-        safeurl = url.hidepassword(self._url)
+        safeurl = util.hidepassword(self._url)
         # accept old "text/plain" and "application/hg-changegroup" for now
         if not (proto.startswith('application/mercurial-') or
                 proto.startswith('text/plain') or
                 proto.startswith('application/hg-changegroup')):
-            self.ui.debug("requested URL: '%s'\n" % url.hidepassword(cu))
+            self.ui.debug("requested URL: '%s'\n" % util.hidepassword(cu))
             raise error.RepoError(
                 _("'%s' does not appear to be an hg repository:\n"
                   "---%%<--- (%s)\n%s\n---%%<---\n")
@@ -146,28 +171,30 @@
         # have to stream bundle to a temp file because we do not have
         # http 1.1 chunked transfer.
 
-        type = ""
         types = self.capable('unbundle')
-        # servers older than d1b16a746db6 will send 'unbundle' as a
-        # boolean capability
         try:
             types = types.split(',')
         except AttributeError:
+            # servers older than d1b16a746db6 will send 'unbundle' as a
+            # boolean capability. They only support headerless/uncompressed
+            # bundles.
             types = [""]
-        if types:
-            for x in types:
-                if x in changegroup.bundletypes:
-                    type = x
-                    break
+        for x in types:
+            if x in changegroup.bundletypes:
+                type = x
+                break
 
         tempname = changegroup.writebundle(cg, None, type)
-        fp = url.httpsendfile(self.ui, tempname, "rb")
+        fp = httpconnection.httpsendfile(self.ui, tempname, "rb")
         headers = {'Content-Type': 'application/mercurial-0.1'}
 
         try:
             try:
                 r = self._call(cmd, data=fp, headers=headers, **args)
-                return r.split('\n', 1)
+                vals = r.split('\n', 1)
+                if len(vals) < 2:
+                    raise error.ResponseError(_("unexpected response:"), r)
+                return vals
             except socket.error, err:
                 if err.args[0] in (errno.ECONNRESET, errno.EPIPE):
                     raise util.Abort(_('push failed: %s') % err.args[1])
@@ -197,8 +224,18 @@
             inst = httpsrepository(ui, path)
         else:
             inst = httprepository(ui, path)
-        inst.between([(nullid, nullid)])
+        try:
+            # Try to do useful work when checking compatibility.
+            # Usually saves a roundtrip since we want the caps anyway.
+            inst._fetchcaps()
+        except error.RepoError:
+            # No luck, try older compatibility check.
+            inst.between([(nullid, nullid)])
         return inst
-    except error.RepoError:
-        ui.note('(falling back to static-http)\n')
-        return statichttprepo.instance(ui, "static-" + path, create)
+    except error.RepoError, httpexception:
+        try:
+            r = statichttprepo.instance(ui, "static-" + path, create)
+            ui.note('(falling back to static-http)\n')
+            return r
+        except error.RepoError:
+            raise httpexception # use the original http RepoError instead
--- a/mercurial/i18n.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/i18n.py	Sat Jun 18 17:03:01 2011 -0500
@@ -51,7 +51,13 @@
         # An unknown encoding results in a LookupError.
         return message
 
-if 'HGPLAIN' in os.environ:
+def _plain():
+    if 'HGPLAIN' not in os.environ and 'HGPLAINEXCEPT' not in os.environ:
+        return False
+    exceptions = os.environ.get('HGPLAINEXCEPT', '').strip().split(',')
+    return 'i18n' not in exceptions
+
+if _plain():
     _ = lambda message: message
 else:
     _ = gettext
--- a/mercurial/keepalive.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/keepalive.py	Sat Jun 18 17:03:01 2011 -0500
@@ -507,7 +507,7 @@
     def readlines(self, sizehint = 0):
         total = 0
         list = []
-        while 1:
+        while True:
             line = self.readline()
             if not line:
                 break
@@ -654,7 +654,7 @@
 
     fo = urllib2.urlopen(url)
     foo = ''
-    while 1:
+    while True:
         f = fo.readline()
         if f:
             foo = foo + f
--- a/mercurial/localrepo.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/localrepo.py	Sat Jun 18 17:03:01 2011 -0500
@@ -10,29 +10,29 @@
 import repo, changegroup, subrepo, discovery, pushkey
 import changelog, dirstate, filelog, manifest, context, bookmarks
 import lock, transaction, store, encoding
-import util, extensions, hook, error
+import scmutil, util, extensions, hook, error
 import match as matchmod
 import merge as mergemod
 import tags as tagsmod
-import url as urlmod
 from lock import release
 import weakref, errno, os, time, inspect
 propertycache = util.propertycache
 
 class localrepository(repo.repository):
-    capabilities = set(('lookup', 'changegroupsubset', 'branchmap', 'pushkey'))
-    supportedformats = set(('revlogv1', 'parentdelta'))
+    capabilities = set(('lookup', 'changegroupsubset', 'branchmap', 'pushkey',
+                        'known', 'getbundle'))
+    supportedformats = set(('revlogv1', 'generaldelta'))
     supported = supportedformats | set(('store', 'fncache', 'shared',
                                         'dotencode'))
 
-    def __init__(self, baseui, path=None, create=0):
+    def __init__(self, baseui, path=None, create=False):
         repo.repository.__init__(self)
         self.root = os.path.realpath(util.expandpath(path))
         self.path = os.path.join(self.root, ".hg")
         self.origroot = path
-        self.auditor = util.path_auditor(self.root, self._checknested)
-        self.opener = util.opener(self.path)
-        self.wopener = util.opener(self.root)
+        self.auditor = scmutil.pathauditor(self.root, self._checknested)
+        self.opener = scmutil.opener(self.path)
+        self.wopener = scmutil.opener(self.root)
         self.baseui = baseui
         self.ui = baseui.copy()
 
@@ -46,7 +46,7 @@
             if create:
                 if not os.path.exists(path):
                     util.makedirs(path)
-                os.mkdir(self.path)
+                util.makedir(self.path, notindexed=True)
                 requirements = ["revlogv1"]
                 if self.ui.configbool('format', 'usestore', True):
                     os.mkdir(os.path.join(self.path, "store"))
@@ -56,31 +56,28 @@
                         if self.ui.configbool('format', 'dotencode', True):
                             requirements.append('dotencode')
                     # create an invalid changelog
-                    self.opener("00changelog.i", "a").write(
+                    self.opener.append(
+                        "00changelog.i",
                         '\0\0\0\2' # represents revlogv2
                         ' dummy changelog to prevent using the old repo layout'
                     )
-                if self.ui.configbool('format', 'parentdelta', False):
-                    requirements.append("parentdelta")
+                if self.ui.configbool('format', 'generaldelta', False):
+                    requirements.append("generaldelta")
             else:
                 raise error.RepoError(_("repository %s not found") % path)
         elif create:
             raise error.RepoError(_("repository %s already exists") % path)
         else:
-            # find requirements
-            requirements = set()
             try:
-                requirements = set(self.opener("requires").read().splitlines())
+                requirements = scmutil.readrequires(self.opener, self.supported)
             except IOError, inst:
                 if inst.errno != errno.ENOENT:
                     raise
-            for r in requirements - self.supported:
-                raise error.RequirementError(
-                          _("requirement '%s' not supported") % r)
+                requirements = set()
 
         self.sharedpath = self.path
         try:
-            s = os.path.realpath(self.opener("sharedpath").read())
+            s = os.path.realpath(self.opener.read("sharedpath"))
             if not os.path.exists(s):
                 raise error.RepoError(
                     _('.hg/sharedpath points to nonexistent directory %s') % s)
@@ -89,7 +86,7 @@
             if inst.errno != errno.ENOENT:
                 raise
 
-        self.store = store.store(requirements, self.sharedpath, util.opener)
+        self.store = store.store(requirements, self.sharedpath, scmutil.opener)
         self.spath = self.store.path
         self.sopener = self.store.opener
         self.sjoin = self.store.join
@@ -115,9 +112,9 @@
 
     def _applyrequirements(self, requirements):
         self.requirements = requirements
-        self.sopener.options = {}
-        if 'parentdelta' in requirements:
-            self.sopener.options['parentdelta'] = 1
+        openerreqs = set(('revlogv1', 'generaldelta'))
+        self.sopener.options = dict((r, 1) for r in requirements
+                                           if r in openerreqs)
 
     def _writerequirements(self):
         reqfile = self.opener("requires", "w")
@@ -177,7 +174,6 @@
             p = os.environ['HG_PENDING']
             if p.startswith(self.root):
                 c.readpending('00changelog.i.a')
-        self.sopener.options['defversion'] = c.version
         return c
 
     @propertycache
@@ -189,7 +185,7 @@
         warned = [0]
         def validate(node):
             try:
-                r = self.changelog.rev(node)
+                self.changelog.rev(node)
                 return node
             except error.LookupError:
                 if not warned[0]:
@@ -276,7 +272,9 @@
 
         try:
             fp = self.wfile('.hgtags', 'rb+')
-        except IOError:
+        except IOError, e:
+            if e.errno != errno.ENOENT:
+                raise
             fp = self.wfile('.hgtags', 'ab')
         else:
             prevtags = fp.read()
@@ -389,10 +387,7 @@
         '''return a list of tags ordered by revision'''
         l = []
         for t, n in self.tags().iteritems():
-            try:
-                r = self.changelog.rev(n)
-            except:
-                r = -2 # sort to the beginning of the list if unknown
+            r = self.changelog.rev(n)
             l.append((r, t, n))
         return [(t, n) for r, t, n in sorted(l)]
 
@@ -511,22 +506,24 @@
             bheads.extend(newnodes)
             if len(bheads) <= 1:
                 continue
+            bheads = sorted(bheads, key=lambda x: self[x].rev())
             # starting from tip means fewer passes over reachable
             while newnodes:
                 latest = newnodes.pop()
                 if latest not in bheads:
                     continue
-                minbhrev = self[min([self[bh].rev() for bh in bheads])].node()
+                minbhrev = self[bheads[0]].node()
                 reachable = self.changelog.reachable(latest, minbhrev)
                 reachable.remove(latest)
-                bheads = [b for b in bheads if b not in reachable]
+                if reachable:
+                    bheads = [b for b in bheads if b not in reachable]
             partial[branch] = bheads
 
     def lookup(self, key):
         if isinstance(key, int):
             return self.changelog.node(key)
         elif key == '.':
-            return self.dirstate.parents()[0]
+            return self.dirstate.p1()
         elif key == 'null':
             return nullid
         elif key == 'tip':
@@ -551,7 +548,7 @@
         try:
             if len(key) == 20:
                 key = hex(key)
-        except:
+        except TypeError:
             pass
         raise error.RepoLookupError(_("unknown revision '%s'") % key)
 
@@ -563,8 +560,12 @@
         repo = (remote and remote.local()) and remote or self
         return repo[key].branch()
 
+    def known(self, nodes):
+        nm = self.changelog.nodemap
+        return [(n in nm) for n in nodes]
+
     def local(self):
-        return True
+        return self
 
     def join(self, f):
         return os.path.join(self.path, f)
@@ -649,7 +650,7 @@
         if self._link(filename):
             data = os.readlink(self.wjoin(filename))
         else:
-            data = self.wopener(filename, 'r').read()
+            data = self.wopener.read(filename)
         return self._filter(self._encodefilterpats, filename, data)
 
     def wwrite(self, filename, data, flags):
@@ -657,9 +658,9 @@
         if 'l' in flags:
             self.wopener.symlink(data, filename)
         else:
-            self.wopener(filename, 'w').write(data)
+            self.wopener.write(filename, data)
             if 'x' in flags:
-                util.set_flags(self.wjoin(filename), False, True)
+                util.setflags(self.wjoin(filename), False, True)
 
     def wwritedata(self, filename, data):
         return self._filter(self._decodefilterpats, filename, data)
@@ -687,19 +688,20 @@
     def _writejournal(self, desc):
         # save dirstate for rollback
         try:
-            ds = self.opener("dirstate").read()
+            ds = self.opener.read("dirstate")
         except IOError:
             ds = ""
-        self.opener("journal.dirstate", "w").write(ds)
-        self.opener("journal.branch", "w").write(
-            encoding.fromlocal(self.dirstate.branch()))
-        self.opener("journal.desc", "w").write("%d\n%s\n" % (len(self), desc))
+        self.opener.write("journal.dirstate", ds)
+        self.opener.write("journal.branch",
+                          encoding.fromlocal(self.dirstate.branch()))
+        self.opener.write("journal.desc",
+                          "%d\n%s\n" % (len(self), desc))
 
         bkname = self.join('bookmarks')
         if os.path.exists(bkname):
             util.copyfile(bkname, self.join('journal.bookmarks'))
         else:
-            self.opener('journal.bookmarks', 'w').write('')
+            self.opener.write('journal.bookmarks', '')
 
         return (self.sjoin('journal'), self.join('journal.dirstate'),
                 self.join('journal.branch'), self.join('journal.desc'),
@@ -727,7 +729,7 @@
             lock = self.lock()
             if os.path.exists(self.sjoin("undo")):
                 try:
-                    args = self.opener("undo.desc", "r").read().splitlines()
+                    args = self.opener.read("undo.desc").splitlines()
                     if len(args) >= 3 and self.ui.verbose:
                         desc = _("repository tip rolled back to revision %s"
                                  " (undo %s: %s)\n") % (
@@ -748,7 +750,7 @@
                     util.rename(self.join('undo.bookmarks'),
                                 self.join('bookmarks'))
                 try:
-                    branch = self.opener("undo.branch").read()
+                    branch = self.opener.read("undo.branch")
                     self.dirstate.setbranch(branch)
                 except IOError:
                     self.ui.warn(_("named branch could not be reset, "
@@ -944,18 +946,28 @@
             # check subrepos
             subs = []
             removedsubs = set()
-            for p in wctx.parents():
-                removedsubs.update(s for s in p.substate if match(s))
-            for s in wctx.substate:
-                removedsubs.discard(s)
-                if match(s) and wctx.sub(s).dirty():
-                    subs.append(s)
-            if (subs or removedsubs):
-                if (not match('.hgsub') and
-                    '.hgsub' in (wctx.modified() + wctx.added())):
-                    raise util.Abort(_("can't commit subrepos without .hgsub"))
-                if '.hgsubstate' not in changes[0]:
-                    changes[0].insert(0, '.hgsubstate')
+            if '.hgsub' in wctx:
+                # only manage subrepos and .hgsubstate if .hgsub is present
+                for p in wctx.parents():
+                    removedsubs.update(s for s in p.substate if match(s))
+                for s in wctx.substate:
+                    removedsubs.discard(s)
+                    if match(s) and wctx.sub(s).dirty():
+                        subs.append(s)
+                if (subs or removedsubs):
+                    if (not match('.hgsub') and
+                        '.hgsub' in (wctx.modified() + wctx.added())):
+                        raise util.Abort(
+                            _("can't commit subrepos without .hgsub"))
+                    if '.hgsubstate' not in changes[0]:
+                        changes[0].insert(0, '.hgsubstate')
+                        if '.hgsubstate' in changes[2]:
+                            changes[2].remove('.hgsubstate')
+            elif '.hgsub' in changes[2]:
+                # clean up .hgsubstate when .hgsub is removed
+                if ('.hgsubstate' in wctx and
+                    '.hgsubstate' not in changes[0] + changes[1] + changes[2]):
+                    changes[2].insert(0, '.hgsubstate')
 
             if subs and not self.ui.configbool('ui', 'commitsubrepos', True):
                 changedsubs = [s for s in subs if wctx.sub(s).dirty(True)]
@@ -1012,9 +1024,7 @@
             # Save commit message in case this transaction gets rolled back
             # (e.g. by a pretxncommit hook).  Leave the content alone on
             # the assumption that the user will use the same editor again.
-            msgfile = self.opener('last-message.txt', 'wb')
-            msgfile.write(cctx._text)
-            msgfile.close()
+            msgfn = self.savecommitmessage(cctx._text)
 
             p1, p2 = self.dirstate.parents()
             hookp1, hookp2 = hex(p1), (p2 != nullid and hex(p2) or '')
@@ -1023,7 +1033,6 @@
                 ret = self.commitctx(cctx, True)
             except:
                 if edited:
-                    msgfn = self.pathto(msgfile.name[len(self.root)+1:])
                     self.ui.write(
                         _('note: commit message saved in %s\n') % msgfn)
                 raise
@@ -1033,7 +1042,7 @@
             for f in changes[0] + changes[1]:
                 self.dirstate.normal(f)
             for f in changes[2]:
-                self.dirstate.forget(f)
+                self.dirstate.drop(f)
             self.dirstate.setparents(ret)
             ms.reset()
         finally:
@@ -1050,8 +1059,6 @@
         tr = lock = None
         removed = list(ctx.removed())
         p1, p2 = ctx.p1(), ctx.p2()
-        m1 = p1.manifest().copy()
-        m2 = p2.manifest()
         user = ctx.user()
 
         lock = self.lock()
@@ -1059,40 +1066,48 @@
             tr = self.transaction("commit")
             trp = weakref.proxy(tr)
 
-            # check in files
-            new = {}
-            changed = []
-            linkrev = len(self)
-            for f in sorted(ctx.modified() + ctx.added()):
-                self.ui.note(f + "\n")
-                try:
-                    fctx = ctx[f]
-                    new[f] = self._filecommit(fctx, m1, m2, linkrev, trp,
-                                              changed)
-                    m1.set(f, fctx.flags())
-                except OSError, inst:
-                    self.ui.warn(_("trouble committing %s!\n") % f)
-                    raise
-                except IOError, inst:
-                    errcode = getattr(inst, 'errno', errno.ENOENT)
-                    if error or errcode and errcode != errno.ENOENT:
+            if ctx.files():
+                m1 = p1.manifest().copy()
+                m2 = p2.manifest()
+
+                # check in files
+                new = {}
+                changed = []
+                linkrev = len(self)
+                for f in sorted(ctx.modified() + ctx.added()):
+                    self.ui.note(f + "\n")
+                    try:
+                        fctx = ctx[f]
+                        new[f] = self._filecommit(fctx, m1, m2, linkrev, trp,
+                                                  changed)
+                        m1.set(f, fctx.flags())
+                    except OSError, inst:
                         self.ui.warn(_("trouble committing %s!\n") % f)
                         raise
-                    else:
-                        removed.append(f)
+                    except IOError, inst:
+                        errcode = getattr(inst, 'errno', errno.ENOENT)
+                        if error or errcode and errcode != errno.ENOENT:
+                            self.ui.warn(_("trouble committing %s!\n") % f)
+                            raise
+                        else:
+                            removed.append(f)
 
-            # update manifest
-            m1.update(new)
-            removed = [f for f in sorted(removed) if f in m1 or f in m2]
-            drop = [f for f in removed if f in m1]
-            for f in drop:
-                del m1[f]
-            mn = self.manifest.add(m1, trp, linkrev, p1.manifestnode(),
-                                   p2.manifestnode(), (new, drop))
+                # update manifest
+                m1.update(new)
+                removed = [f for f in sorted(removed) if f in m1 or f in m2]
+                drop = [f for f in removed if f in m1]
+                for f in drop:
+                    del m1[f]
+                mn = self.manifest.add(m1, trp, linkrev, p1.manifestnode(),
+                                       p2.manifestnode(), (new, drop))
+                files = changed + removed
+            else:
+                mn = p1.manifestnode()
+                files = []
 
             # update changelog
             self.changelog.delayupdate()
-            n = self.changelog.add(mn, changed + removed, ctx.description(),
+            n = self.changelog.add(mn, files, ctx.description(),
                                    trp, p1.node(), p2.node(),
                                    user, ctx.date(), ctx.extra().copy())
             p = lambda: self.changelog.writepending() and self.root or ""
@@ -1303,7 +1318,7 @@
         b = []
         for n in nodes:
             t = n
-            while 1:
+            while True:
                 p = self.changelog.parents(n)
                 if p[1] != nullid or p[0] == nullid:
                     b.append((t, n, p[0], p[1]))
@@ -1340,13 +1355,16 @@
                 self.ui.status(_("no changes found\n"))
                 result = 0
             else:
-                if heads is None and fetch == [nullid]:
+                if heads is None and list(common) == [nullid]:
                     self.ui.status(_("requesting all changes\n"))
                 elif heads is None and remote.capable('changegroupsubset'):
                     # issue1320, avoid a race if remote changed after discovery
                     heads = rheads
 
-                if heads is None:
+                if remote.capable('getbundle'):
+                    cg = remote.getbundle('pull', common=common,
+                                          heads=heads or rheads)
+                elif heads is None:
                     cg = remote.changegroup(fetch, 'pull')
                 elif not remote.capable('changegroupsubset'):
                     raise util.Abort(_("partial pull cannot be done because "
@@ -1359,27 +1377,6 @@
         finally:
             lock.release()
 
-        self.ui.debug("checking for updated bookmarks\n")
-        rb = remote.listkeys('bookmarks')
-        changed = False
-        for k in rb.keys():
-            if k in self._bookmarks:
-                nr, nl = rb[k], self._bookmarks[k]
-                if nr in self:
-                    cr = self[nr]
-                    cl = self[nl]
-                    if cl.rev() >= cr.rev():
-                        continue
-                    if cr in cl.descendants():
-                        self._bookmarks[k] = cr.node()
-                        changed = True
-                        self.ui.status(_("updating bookmark %s\n") % k)
-                    else:
-                        self.ui.warn(_("not updating divergent"
-                                       " bookmark %s\n") % k)
-        if changed:
-            bookmarks.write(self)
-
         return result
 
     def checkpush(self, force, revs):
@@ -1459,9 +1456,9 @@
             for node in nodes:
                 self.ui.debug("%s\n" % hex(node))
 
-    def changegroupsubset(self, bases, heads, source, extranodes=None):
+    def changegroupsubset(self, bases, heads, source):
         """Compute a changegroup consisting of all the nodes that are
-        descendents of any of the bases and ancestors of any of the heads.
+        descendants of any of the bases and ancestors of any of the heads.
         Return a chunkbuffer object whose read() method will return
         successive changegroup chunks.
 
@@ -1471,214 +1468,131 @@
 
         Another wrinkle is doing the reverse, figuring out which changeset in
         the changegroup a particular filenode or manifestnode belongs to.
-
-        The caller can specify some nodes that must be included in the
-        changegroup using the extranodes argument.  It should be a dict
-        where the keys are the filenames (or 1 for the manifest), and the
-        values are lists of (node, linknode) tuples, where node is a wanted
-        node and linknode is the changelog node that should be transmitted as
-        the linkrev.
         """
-
-        # Set up some initial variables
-        # Make it easy to refer to self.changelog
         cl = self.changelog
-        # Compute the list of changesets in this changegroup.
-        # Some bases may turn out to be superfluous, and some heads may be
-        # too.  nodesbetween will return the minimal set of bases and heads
-        # necessary to re-create the changegroup.
         if not bases:
             bases = [nullid]
-        msng_cl_lst, bases, heads = cl.nodesbetween(bases, heads)
+        csets, bases, heads = cl.nodesbetween(bases, heads)
+        # We assume that all ancestors of bases are known
+        common = set(cl.ancestors(*[cl.rev(n) for n in bases]))
+        return self._changegroupsubset(common, csets, heads, source)
+
+    def getbundle(self, source, heads=None, common=None):
+        """Like changegroupsubset, but returns the set difference between the
+        ancestors of heads and the ancestors common.
+
+        If heads is None, use the local heads. If common is None, use [nullid].
 
-        if extranodes is None:
-            # can we go through the fast path ?
-            heads.sort()
-            allheads = self.heads()
-            allheads.sort()
-            if heads == allheads:
-                return self._changegroup(msng_cl_lst, source)
+        The nodes in common might not all be known locally due to the way the
+        current discovery protocol works.
+        """
+        cl = self.changelog
+        if common:
+            nm = cl.nodemap
+            common = [n for n in common if n in nm]
+        else:
+            common = [nullid]
+        if not heads:
+            heads = cl.heads()
+        common, missing = cl.findcommonmissing(common, heads)
+        if not missing:
+            return None
+        return self._changegroupsubset(common, missing, heads, source)
+
+    def _changegroupsubset(self, commonrevs, csets, heads, source):
+
+        cl = self.changelog
+        mf = self.manifest
+        mfs = {} # needed manifests
+        fnodes = {} # needed file nodes
+        changedfiles = set()
+        fstate = ['', {}]
+        count = [0]
+
+        # can we go through the fast path ?
+        heads.sort()
+        if heads == sorted(self.heads()):
+            return self._changegroup(csets, source)
 
         # slow path
         self.hook('preoutgoing', throw=True, source=source)
-
-        self.changegroupinfo(msng_cl_lst, source)
-
-        # We assume that all ancestors of bases are known
-        commonrevs = set(cl.ancestors(*[cl.rev(n) for n in bases]))
+        self.changegroupinfo(csets, source)
 
-        # Make it easy to refer to self.manifest
-        mnfst = self.manifest
-        # We don't know which manifests are missing yet
-        msng_mnfst_set = {}
-        # Nor do we know which filenodes are missing.
-        msng_filenode_set = {}
-
-        # A changeset always belongs to itself, so the changenode lookup
-        # function for a changenode is identity.
-        def identity(x):
-            return x
+        # filter any nodes that claim to be part of the known set
+        def prune(revlog, missing):
+            return [n for n in missing
+                    if revlog.linkrev(revlog.rev(n)) not in commonrevs]
 
-        # A function generating function that sets up the initial environment
-        # the inner function.
-        def filenode_collector(changedfiles):
-            # This gathers information from each manifestnode included in the
-            # changegroup about which filenodes the manifest node references
-            # so we can include those in the changegroup too.
-            #
-            # It also remembers which changenode each filenode belongs to.  It
-            # does this by assuming the a filenode belongs to the changenode
-            # the first manifest that references it belongs to.
-            def collect_msng_filenodes(mnfstnode):
-                r = mnfst.rev(mnfstnode)
-                if mnfst.deltaparent(r) in mnfst.parentrevs(r):
-                    # If the previous rev is one of the parents,
-                    # we only need to see a diff.
-                    deltamf = mnfst.readdelta(mnfstnode)
-                    # For each line in the delta
-                    for f, fnode in deltamf.iteritems():
-                        # And if the file is in the list of files we care
-                        # about.
-                        if f in changedfiles:
-                            # Get the changenode this manifest belongs to
-                            clnode = msng_mnfst_set[mnfstnode]
-                            # Create the set of filenodes for the file if
-                            # there isn't one already.
-                            ndset = msng_filenode_set.setdefault(f, {})
-                            # And set the filenode's changelog node to the
-                            # manifest's if it hasn't been set already.
-                            ndset.setdefault(fnode, clnode)
-                else:
-                    # Otherwise we need a full manifest.
-                    m = mnfst.read(mnfstnode)
-                    # For every file in we care about.
-                    for f in changedfiles:
-                        fnode = m.get(f, None)
-                        # If it's in the manifest
-                        if fnode is not None:
-                            # See comments above.
-                            clnode = msng_mnfst_set[mnfstnode]
-                            ndset = msng_filenode_set.setdefault(f, {})
-                            ndset.setdefault(fnode, clnode)
-            return collect_msng_filenodes
+        def lookup(revlog, x):
+            if revlog == cl:
+                c = cl.read(x)
+                changedfiles.update(c[3])
+                mfs.setdefault(c[0], x)
+                count[0] += 1
+                self.ui.progress(_('bundling'), count[0],
+                                 unit=_('changesets'), total=len(csets))
+                return x
+            elif revlog == mf:
+                clnode = mfs[x]
+                mdata = mf.readfast(x)
+                for f in changedfiles:
+                    if f in mdata:
+                        fnodes.setdefault(f, {}).setdefault(mdata[f], clnode)
+                count[0] += 1
+                self.ui.progress(_('bundling'), count[0],
+                                 unit=_('manifests'), total=len(mfs))
+                return mfs[x]
+            else:
+                self.ui.progress(
+                    _('bundling'), count[0], item=fstate[0],
+                    unit=_('files'), total=len(changedfiles))
+                return fstate[1][x]
 
-        # If we determine that a particular file or manifest node must be a
-        # node that the recipient of the changegroup will already have, we can
-        # also assume the recipient will have all the parents.  This function
-        # prunes them from the set of missing nodes.
-        def prune(revlog, missingnodes):
-            hasset = set()
-            # If a 'missing' filenode thinks it belongs to a changenode we
-            # assume the recipient must have, then the recipient must have
-            # that filenode.
-            for n in missingnodes:
-                clrev = revlog.linkrev(revlog.rev(n))
-                if clrev in commonrevs:
-                    hasset.add(n)
-            for n in hasset:
-                missingnodes.pop(n, None)
-            for r in revlog.ancestors(*[revlog.rev(n) for n in hasset]):
-                missingnodes.pop(revlog.node(r), None)
+        bundler = changegroup.bundle10(lookup)
+        reorder = self.ui.config('bundle', 'reorder', 'auto')
+        if reorder == 'auto':
+            reorder = None
+        else:
+            reorder = util.parsebool(reorder)
 
-        # Add the nodes that were explicitly requested.
-        def add_extra_nodes(name, nodes):
-            if not extranodes or name not in extranodes:
-                return
-
-            for node, linknode in extranodes[name]:
-                if node not in nodes:
-                    nodes[node] = linknode
-
-        # Now that we have all theses utility functions to help out and
-        # logically divide up the task, generate the group.
         def gengroup():
-            # The set of changed files starts empty.
-            changedfiles = set()
-            collect = changegroup.collector(cl, msng_mnfst_set, changedfiles)
-
             # Create a changenode group generator that will call our functions
             # back to lookup the owning changenode and collect information.
-            group = cl.group(msng_cl_lst, identity, collect)
-            for cnt, chnk in enumerate(group):
-                yield chnk
-                # revlog.group yields three entries per node, so
-                # dividing by 3 gives an approximation of how many
-                # nodes have been processed.
-                self.ui.progress(_('bundling'), cnt / 3,
-                                 unit=_('changesets'))
-            changecount = cnt / 3
+            for chunk in cl.group(csets, bundler, reorder=reorder):
+                yield chunk
             self.ui.progress(_('bundling'), None)
 
-            prune(mnfst, msng_mnfst_set)
-            add_extra_nodes(1, msng_mnfst_set)
-            msng_mnfst_lst = msng_mnfst_set.keys()
-            # Sort the manifestnodes by revision number.
-            msng_mnfst_lst.sort(key=mnfst.rev)
             # Create a generator for the manifestnodes that calls our lookup
             # and data collection functions back.
-            group = mnfst.group(msng_mnfst_lst,
-                                lambda mnode: msng_mnfst_set[mnode],
-                                filenode_collector(changedfiles))
-            efiles = {}
-            for cnt, chnk in enumerate(group):
-                if cnt % 3 == 1:
-                    mnode = chnk[:20]
-                    efiles.update(mnfst.readdelta(mnode))
-                yield chnk
-                # see above comment for why we divide by 3
-                self.ui.progress(_('bundling'), cnt / 3,
-                                 unit=_('manifests'), total=changecount)
+            count[0] = 0
+            for chunk in mf.group(prune(mf, mfs), bundler, reorder=reorder):
+                yield chunk
             self.ui.progress(_('bundling'), None)
-            efiles = len(efiles)
 
-            # These are no longer needed, dereference and toss the memory for
-            # them.
-            msng_mnfst_lst = None
-            msng_mnfst_set.clear()
+            mfs.clear()
 
-            if extranodes:
-                for fname in extranodes:
-                    if isinstance(fname, int):
-                        continue
-                    msng_filenode_set.setdefault(fname, {})
-                    changedfiles.add(fname)
             # Go through all our files in order sorted by name.
-            for idx, fname in enumerate(sorted(changedfiles)):
+            count[0] = 0
+            for fname in sorted(changedfiles):
                 filerevlog = self.file(fname)
                 if not len(filerevlog):
                     raise util.Abort(_("empty or missing revlog for %s") % fname)
-                # Toss out the filenodes that the recipient isn't really
-                # missing.
-                missingfnodes = msng_filenode_set.pop(fname, {})
-                prune(filerevlog, missingfnodes)
-                add_extra_nodes(fname, missingfnodes)
-                # If any filenodes are left, generate the group for them,
-                # otherwise don't bother.
-                if missingfnodes:
-                    yield changegroup.chunkheader(len(fname))
-                    yield fname
-                    # Sort the filenodes by their revision # (topological order)
-                    nodeiter = list(missingfnodes)
-                    nodeiter.sort(key=filerevlog.rev)
-                    # Create a group generator and only pass in a changenode
-                    # lookup function as we need to collect no information
-                    # from filenodes.
-                    group = filerevlog.group(nodeiter,
-                                             lambda fnode: missingfnodes[fnode])
-                    for chnk in group:
-                        # even though we print the same progress on
-                        # most loop iterations, put the progress call
-                        # here so that time estimates (if any) can be updated
-                        self.ui.progress(
-                            _('bundling'), idx, item=fname,
-                            unit=_('files'), total=efiles)
-                        yield chnk
+                fstate[0] = fname
+                fstate[1] = fnodes.pop(fname, {})
+
+                nodelist = prune(filerevlog, fstate[1])
+                if nodelist:
+                    count[0] += 1
+                    yield bundler.fileheader(fname)
+                    for chunk in filerevlog.group(nodelist, bundler, reorder):
+                        yield chunk
+
             # Signal that no more groups are left.
-            yield changegroup.closechunk()
+            yield bundler.close()
             self.ui.progress(_('bundling'), None)
 
-            if msng_cl_lst:
-                self.hook('outgoing', node=hex(msng_cl_lst[0]), source=source)
+            if csets:
+                self.hook('outgoing', node=hex(csets[0]), source=source)
 
         return changegroup.unbundle10(util.chunkbuffer(gengroup()), 'UN')
 
@@ -1696,75 +1610,76 @@
 
         nodes is the set of nodes to send"""
 
-        self.hook('preoutgoing', throw=True, source=source)
+        cl = self.changelog
+        mf = self.manifest
+        mfs = {}
+        changedfiles = set()
+        fstate = ['']
+        count = [0]
 
-        cl = self.changelog
-        revset = set([cl.rev(n) for n in nodes])
+        self.hook('preoutgoing', throw=True, source=source)
         self.changegroupinfo(nodes, source)
 
-        def identity(x):
-            return x
+        revset = set([cl.rev(n) for n in nodes])
 
         def gennodelst(log):
-            for r in log:
-                if log.linkrev(r) in revset:
-                    yield log.node(r)
+            return [log.node(r) for r in log if log.linkrev(r) in revset]
 
-        def lookuplinkrev_func(revlog):
-            def lookuplinkrev(n):
-                return cl.node(revlog.linkrev(revlog.rev(n)))
-            return lookuplinkrev
+        def lookup(revlog, x):
+            if revlog == cl:
+                c = cl.read(x)
+                changedfiles.update(c[3])
+                mfs.setdefault(c[0], x)
+                count[0] += 1
+                self.ui.progress(_('bundling'), count[0],
+                                 unit=_('changesets'), total=len(nodes))
+                return x
+            elif revlog == mf:
+                count[0] += 1
+                self.ui.progress(_('bundling'), count[0],
+                                 unit=_('manifests'), total=len(mfs))
+                return cl.node(revlog.linkrev(revlog.rev(x)))
+            else:
+                self.ui.progress(
+                    _('bundling'), count[0], item=fstate[0],
+                    total=len(changedfiles), unit=_('files'))
+                return cl.node(revlog.linkrev(revlog.rev(x)))
+
+        bundler = changegroup.bundle10(lookup)
+        reorder = self.ui.config('bundle', 'reorder', 'auto')
+        if reorder == 'auto':
+            reorder = None
+        else:
+            reorder = util.parsebool(reorder)
 
         def gengroup():
             '''yield a sequence of changegroup chunks (strings)'''
             # construct a list of all changed files
-            changedfiles = set()
-            mmfs = {}
-            collect = changegroup.collector(cl, mmfs, changedfiles)
 
-            for cnt, chnk in enumerate(cl.group(nodes, identity, collect)):
-                # revlog.group yields three entries per node, so
-                # dividing by 3 gives an approximation of how many
-                # nodes have been processed.
-                self.ui.progress(_('bundling'), cnt / 3, unit=_('changesets'))
-                yield chnk
-            changecount = cnt / 3
+            for chunk in cl.group(nodes, bundler, reorder=reorder):
+                yield chunk
             self.ui.progress(_('bundling'), None)
 
-            mnfst = self.manifest
-            nodeiter = gennodelst(mnfst)
-            efiles = {}
-            for cnt, chnk in enumerate(mnfst.group(nodeiter,
-                                                   lookuplinkrev_func(mnfst))):
-                if cnt % 3 == 1:
-                    mnode = chnk[:20]
-                    efiles.update(mnfst.readdelta(mnode))
-                # see above comment for why we divide by 3
-                self.ui.progress(_('bundling'), cnt / 3,
-                                 unit=_('manifests'), total=changecount)
-                yield chnk
-            efiles = len(efiles)
+            count[0] = 0
+            for chunk in mf.group(gennodelst(mf), bundler, reorder=reorder):
+                yield chunk
             self.ui.progress(_('bundling'), None)
 
-            for idx, fname in enumerate(sorted(changedfiles)):
+            count[0] = 0
+            for fname in sorted(changedfiles):
                 filerevlog = self.file(fname)
                 if not len(filerevlog):
                     raise util.Abort(_("empty or missing revlog for %s") % fname)
-                nodeiter = gennodelst(filerevlog)
-                nodeiter = list(nodeiter)
-                if nodeiter:
-                    yield changegroup.chunkheader(len(fname))
-                    yield fname
-                    lookup = lookuplinkrev_func(filerevlog)
-                    for chnk in filerevlog.group(nodeiter, lookup):
-                        self.ui.progress(
-                            _('bundling'), idx, item=fname,
-                            total=efiles, unit=_('files'))
-                        yield chnk
+                fstate[0] = fname
+                nodelist = gennodelst(filerevlog)
+                if nodelist:
+                    count[0] += 1
+                    yield bundler.fileheader(fname)
+                    for chunk in filerevlog.group(nodelist, bundler, reorder):
+                        yield chunk
+            yield bundler.close()
             self.ui.progress(_('bundling'), None)
 
-            yield changegroup.closechunk()
-
             if nodes:
                 self.hook('outgoing', node=hex(nodes[0]), source=source)
 
@@ -1802,9 +1717,9 @@
         # inconsistent view
         cl = self.changelog
         cl.delayupdate()
-        oldheads = len(cl.heads())
+        oldheads = cl.heads()
 
-        tr = self.transaction("\n".join([srctype, urlmod.hidepassword(url)]))
+        tr = self.transaction("\n".join([srctype, util.hidepassword(url)]))
         try:
             trp = weakref.proxy(tr)
             # pull off the changeset group
@@ -1822,6 +1737,7 @@
             pr = prog()
             source.callback = pr
 
+            source.changelogheader()
             if (cl.addgroup(source, csmap, trp) is None
                 and not emptyok):
                 raise util.Abort(_("received changelog group is empty"))
@@ -1841,6 +1757,7 @@
             # if the result of the merge of 1 and 2 is the same in 3 and 4,
             # no new manifest will be created and the manifest group will
             # be empty during the pull
+            source.manifestheader()
             self.manifest.addgroup(source, revmap, trp)
             self.ui.progress(_('manifests'), None)
 
@@ -1861,10 +1778,11 @@
             pr.total = efiles
             source.callback = None
 
-            while 1:
-                f = source.chunk()
-                if not f:
+            while True:
+                chunkdata = source.filelogheader()
+                if not chunkdata:
                     break
+                f = chunkdata["filename"]
                 self.ui.debug("adding %s revisions\n" % f)
                 pr()
                 fl = self.file(f)
@@ -1893,14 +1811,20 @@
                             _('missing file data for %s:%s - run hg verify') %
                             (f, hex(n)))
 
-            newheads = len(cl.heads())
-            heads = ""
-            if oldheads and newheads != oldheads:
-                heads = _(" (%+d heads)") % (newheads - oldheads)
+            dh = 0
+            if oldheads:
+                heads = cl.heads()
+                dh = len(heads) - len(oldheads)
+                for h in heads:
+                    if h not in oldheads and 'close' in self[h].extra():
+                        dh -= 1
+            htext = ""
+            if dh:
+                htext = _(" (%+d heads)") % dh
 
             self.ui.status(_("added %d changesets"
                              " with %d changes to %d files%s\n")
-                             % (changesets, revisions, files, heads))
+                             % (changesets, revisions, files, htext))
 
             if changesets > 0:
                 p = lambda: cl.writepending() and self.root or ""
@@ -1928,16 +1852,11 @@
                 self.hook("incoming", node=hex(cl.node(i)),
                           source=srctype, url=url)
 
-        # FIXME - why does this care about tip?
-        if newheads == oldheads:
-            bookmarks.update(self, self.dirstate.parents(), self['tip'].node())
-
         # never return 0 here:
-        if newheads < oldheads:
-            return newheads - oldheads - 1
+        if dh < 0:
+            return dh - 1
         else:
-            return newheads - oldheads + 1
-
+            return dh + 1
 
     def stream_in(self, remote, requirements):
         lock = self.lock()
@@ -2027,10 +1946,30 @@
         return self.pull(remote, heads)
 
     def pushkey(self, namespace, key, old, new):
-        return pushkey.push(self, namespace, key, old, new)
+        self.hook('prepushkey', throw=True, namespace=namespace, key=key,
+                  old=old, new=new)
+        ret = pushkey.push(self, namespace, key, old, new)
+        self.hook('pushkey', namespace=namespace, key=key, old=old, new=new,
+                  ret=ret)
+        return ret
 
     def listkeys(self, namespace):
-        return pushkey.list(self, namespace)
+        self.hook('prelistkeys', throw=True, namespace=namespace)
+        values = pushkey.list(self, namespace)
+        self.hook('listkeys', namespace=namespace, values=values)
+        return values
+
+    def debugwireargs(self, one, two, three=None, four=None, five=None):
+        '''used to test argument passing over the wire'''
+        return "%s %s %s %s %s" % (one, two, three, four, five)
+
+    def savecommitmessage(self, text):
+        fp = self.opener('last-message.txt', 'wb')
+        try:
+            fp.write(text)
+        finally:
+            fp.close()
+        return self.pathto(fp.name[len(self.root)+1:])
 
 # used to avoid circular references so destructors work
 def aftertrans(files):
@@ -2046,7 +1985,7 @@
     return os.path.join(base, name.replace('journal', 'undo', 1))
 
 def instance(ui, path, create):
-    return localrepository(ui, util.drop_scheme('file', path), create)
+    return localrepository(ui, util.localpath(path), create)
 
 def islocal(path):
     return True
--- a/mercurial/lock.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/lock.py	Sat Jun 18 17:03:01 2011 -0500
@@ -51,7 +51,7 @@
 
     def lock(self):
         timeout = self.timeout
-        while 1:
+        while True:
             try:
                 self.trylock()
                 return 1
--- a/mercurial/mail.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/mail.py	Sat Jun 18 17:03:01 2011 -0500
@@ -91,7 +91,7 @@
     if ret:
         raise util.Abort('%s %s' % (
             os.path.basename(program.split(None, 1)[0]),
-            util.explain_exit(ret)[0]))
+            util.explainexit(ret)[0]))
 
 def connect(ui):
     '''make a mail connection. return a function to send mail.
@@ -112,7 +112,7 @@
             raise util.Abort(_('smtp specified as email transport, '
                                'but no smtp host configured'))
     else:
-        if not util.find_exe(method):
+        if not util.findexe(method):
             raise util.Abort(_('%r specified as email transport, '
                                'but not in PATH') % method)
 
--- a/mercurial/manifest.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/manifest.py	Sat Jun 18 17:03:01 2011 -0500
@@ -38,6 +38,14 @@
         r = self.rev(node)
         return self.parse(mdiff.patchtext(self.revdiff(self.deltaparent(r), r)))
 
+    def readfast(self, node):
+        '''use the faster of readdelta or read'''
+        r = self.rev(node)
+        deltaparent = self.deltaparent(r)
+        if deltaparent != revlog.nullrev and deltaparent in self.parentrevs(r):
+            return self.readdelta(node)
+        return self.read(node)
+
     def read(self, node):
         if node == revlog.nullid:
             return manifestdict() # don't upset local cache
@@ -134,7 +142,7 @@
             # if this is changed to support newlines in filenames,
             # be sure to check the templates/ dir again (especially *-raw.tmpl)
             hex, flags = revlog.hex, map.flags
-            text = ''.join("%s\000%s%s\n" % (f, hex(map[f]), flags(f))
+            text = ''.join("%s\0%s%s\n" % (f, hex(map[f]), flags(f))
                            for f in files)
             arraytext = array.array('c', text)
             cachedelta = None
@@ -164,7 +172,7 @@
                 # bs will either be the index of the item or the insert point
                 start, end = self._search(addbuf, f, start)
                 if not todelete:
-                    l = "%s\000%s%s\n" % (f, revlog.hex(map[f]), map.flags(f))
+                    l = "%s\0%s%s\n" % (f, revlog.hex(map[f]), map.flags(f))
                 else:
                     if start == end:
                         # item we want to delete was not found, error out
--- a/mercurial/match.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/match.py	Sat Jun 18 17:03:01 2011 -0500
@@ -6,12 +6,27 @@
 # GNU General Public License version 2 or any later version.
 
 import re
-import util
+import scmutil, util, fileset
 from i18n import _
 
+def _expandsets(pats, ctx):
+    '''convert set: patterns into a list of files in the given context'''
+    fset = set()
+    other = []
+
+    for kind, expr in pats:
+        if kind == 'set':
+            if not ctx:
+                raise util.Abort("fileset expression with no context")
+            s = fileset.getfileset(ctx, expr)
+            fset.update(s)
+            continue
+        other.append((kind, expr))
+    return fset, other
+
 class match(object):
     def __init__(self, root, cwd, patterns, include=[], exclude=[],
-                 default='glob', exact=False, auditor=None):
+                 default='glob', exact=False, auditor=None, ctx=None):
         """build an object to match a set of file patterns
 
         arguments:
@@ -30,20 +45,23 @@
         'relglob:<glob>' - an unrooted glob (*.c matches C files in all dirs)
         'relpath:<path>' - a path relative to cwd
         'relre:<regexp>' - a regexp that needn't match the start of a name
+        'set:<fileset>' - a fileset expression
         '<something>' - a pattern of the specified default type
         """
 
+        self._ctx = None
         self._root = root
         self._cwd = cwd
         self._files = []
         self._anypats = bool(include or exclude)
+        self._ctx = ctx
 
         if include:
             pats = _normalize(include, 'glob', root, cwd, auditor)
-            self.includepat, im = _buildmatch(pats, '(?:/|$)')
+            self.includepat, im = _buildmatch(ctx, pats, '(?:/|$)')
         if exclude:
             pats = _normalize(exclude, 'glob', root, cwd, auditor)
-            self.excludepat, em = _buildmatch(pats, '(?:/|$)')
+            self.excludepat, em = _buildmatch(ctx, pats, '(?:/|$)')
         if exact:
             self._files = patterns
             pm = self.exact
@@ -51,7 +69,7 @@
             pats = _normalize(patterns, default, root, cwd, auditor)
             self._files = _roots(pats)
             self._anypats = self._anypats or _anypats(pats)
-            self.patternspat, pm = _buildmatch(pats, '$')
+            self.patternspat, pm = _buildmatch(ctx, pats, '$')
 
         if patterns or exact:
             if include:
@@ -162,7 +180,7 @@
     if ':' in pat:
         kind, val = pat.split(':', 1)
         if kind in ('re', 'glob', 'path', 'relglob', 'relpath', 'relre',
-                    'listfile', 'listfile0'):
+                    'listfile', 'listfile0', 'set'):
             return kind, val
     return default, pat
 
@@ -240,7 +258,17 @@
         return '.*' + name
     return _globre(name) + tail
 
-def _buildmatch(pats, tail):
+def _buildmatch(ctx, pats, tail):
+    fset, pats = _expandsets(pats, ctx)
+    if not pats:
+        return "", fset.__contains__
+
+    pat, mf = _buildregexmatch(pats, tail)
+    if fset:
+        return pat, lambda f: f in fset or mf(f)
+    return pat, mf
+
+def _buildregexmatch(pats, tail):
     """build a matching function from a set of patterns"""
     try:
         pat = '(?:%s)' % '|'.join([_regex(k, p, tail) for (k, p) in pats])
@@ -269,13 +297,16 @@
     pats = []
     for kind, name in [_patsplit(p, default) for p in names]:
         if kind in ('glob', 'relpath'):
-            name = util.canonpath(root, cwd, name, auditor)
+            name = scmutil.canonpath(root, cwd, name, auditor)
         elif kind in ('relglob', 'path'):
             name = util.normpath(name)
         elif kind in ('listfile', 'listfile0'):
-            delimiter = kind == 'listfile0' and '\0' or '\n'
             try:
-                files = open(name, 'r').read().split(delimiter)
+                files = util.readfile(name)
+                if kind == 'listfile0':
+                    files = files.split('\0')
+                else:
+                    files = files.splitlines()
                 files = [f for f in files if f]
             except EnvironmentError:
                 raise util.Abort(_("unable to read file list (%s)") % name)
--- a/mercurial/merge.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/merge.py	Sat Jun 18 17:03:01 2011 -0500
@@ -7,7 +7,7 @@
 
 from node import nullid, nullrev, hex, bin
 from i18n import _
-import util, filemerge, copies, subrepo
+import scmutil, util, filemerge, copies, subrepo
 import errno, os, shutil
 
 class mergestate(object):
@@ -47,7 +47,7 @@
             self._dirty = False
     def add(self, fcl, fco, fca, fd, flags):
         hash = util.sha1(fcl.path()).hexdigest()
-        self._repo.opener("merge/" + hash, "w").write(fcl.data())
+        self._repo.opener.write("merge/" + hash, fcl.data())
         self._state[fd] = ['u', hash, fcl.path(), fca.path(),
                            hex(fca.filenode()), fco.path(), flags]
         self._dirty = True
@@ -268,10 +268,9 @@
 
     updated, merged, removed, unresolved = 0, 0, 0, 0
     ms = mergestate(repo)
-    ms.reset(wctx.parents()[0].node())
+    ms.reset(wctx.p1().node())
     moves = []
     action.sort(key=actionkey)
-    substate = wctx.substate # prime
 
     # prescan for merges
     u = repo.ui
@@ -286,7 +285,7 @@
             fco = mctx[f2]
             if mctx == actx: # backwards, use working dir parent as ancestor
                 if fcl.parents():
-                    fca = fcl.parents()[0]
+                    fca = fcl.p1()
                 else:
                     fca = repo.filectx(f, fileid=nullrev)
             else:
@@ -297,14 +296,15 @@
             if f != fd and move:
                 moves.append(f)
 
+    audit = scmutil.pathauditor(repo.root)
+
     # remove renamed files after safely stored
     for f in moves:
         if os.path.lexists(repo.wjoin(f)):
             repo.ui.debug("removing %s\n" % f)
+            audit(f)
             os.unlink(repo.wjoin(f))
 
-    audit_path = util.path_auditor(repo.root)
-
     numupdates = len(action)
     for i, a in enumerate(action):
         f, m = a[:2]
@@ -314,7 +314,7 @@
             continue
         if m == "r": # remove
             repo.ui.note(_("removing %s\n") % f)
-            audit_path(f)
+            audit(f)
             if f == '.hgsubstate': # subrepo states need updating
                 subrepo.submerge(repo, wctx, mctx, wctx, overwrite)
             try:
@@ -329,6 +329,7 @@
                 subrepo.submerge(repo, wctx, mctx, wctx.ancestor(mctx), overwrite)
                 continue
             f2, fd, flags, move = a[2:]
+            repo.wopener.audit(fd)
             r = ms.resolve(fd, wctx, mctx)
             if r is not None and r > 0:
                 unresolved += 1
@@ -337,10 +338,11 @@
                     updated += 1
                 else:
                     merged += 1
-            util.set_flags(repo.wjoin(fd), 'l' in flags, 'x' in flags)
+            util.setflags(repo.wjoin(fd), 'l' in flags, 'x' in flags)
             if (move and repo.dirstate.normalize(fd) != f
                 and os.path.lexists(repo.wjoin(f))):
                 repo.ui.debug("removing %s\n" % f)
+                audit(f)
                 os.unlink(repo.wjoin(f))
         elif m == "g": # get
             flags = a[2]
@@ -355,6 +357,7 @@
             f2, fd, flags = a[2:]
             if f:
                 repo.ui.note(_("moving %s to %s\n") % (f, fd))
+                audit(f)
                 t = wctx.filectx(f).data()
                 repo.wwrite(fd, t, flags)
                 util.unlinkpath(repo.wjoin(f))
@@ -371,7 +374,8 @@
                 repo.ui.warn(" %s\n" % nf)
         elif m == "e": # exec
             flags = a[2]
-            util.set_flags(repo.wjoin(f), 'l' in flags, 'x' in flags)
+            repo.wopener.audit(f)
+            util.setflags(repo.wjoin(f), 'l' in flags, 'x' in flags)
     ms.commit()
     u.progress(_('updating'), None, total=numupdates, unit=_('files'))
 
@@ -386,12 +390,12 @@
             if branchmerge:
                 repo.dirstate.remove(f)
             else:
-                repo.dirstate.forget(f)
+                repo.dirstate.drop(f)
         elif m == "a": # re-add
             if not branchmerge:
                 repo.dirstate.add(f)
         elif m == "f": # forget
-            repo.dirstate.forget(f)
+            repo.dirstate.drop(f)
         elif m == "e": # exec change
             repo.dirstate.normallookup(f)
         elif m == "g": # get
@@ -421,7 +425,7 @@
                 if f2 == fd: # file not locally copied/moved
                     repo.dirstate.normallookup(fd)
                 if move:
-                    repo.dirstate.forget(f)
+                    repo.dirstate.drop(f)
         elif m == "d": # directory rename
             f2, fd, flag = a[2:]
             if not f2 and f not in repo.dirstate:
@@ -437,9 +441,9 @@
             else:
                 repo.dirstate.normal(fd)
                 if f:
-                    repo.dirstate.forget(f)
+                    repo.dirstate.drop(f)
 
-def update(repo, node, branchmerge, force, partial):
+def update(repo, node, branchmerge, force, partial, ancestor=None):
     """
     Perform a merge between the working directory and the given node
 
@@ -492,9 +496,12 @@
         overwrite = force and not branchmerge
         pl = wc.parents()
         p1, p2 = pl[0], repo[node]
-        pa = p1.ancestor(p2)
+        if ancestor:
+            pa = repo[ancestor]
+        else:
+            pa = p1.ancestor(p2)
+
         fp1, fp2, xp1, xp2 = p1.node(), p2.node(), str(p1), str(p2)
-        fastforward = False
 
         ### check phase
         if not overwrite and len(pl) > 1:
@@ -504,9 +511,7 @@
                 raise util.Abort(_("merging with a working directory ancestor"
                                    " has no effect"))
             elif pa == p1:
-                if p1.branch() != p2.branch():
-                    fastforward = True
-                else:
+                if p1.branch() == p2.branch():
                     raise util.Abort(_("nothing to merge (use 'hg update'"
                                        " or check 'hg heads')"))
             if not force and (wc.files() or wc.deleted()):
@@ -520,11 +525,11 @@
         elif not overwrite:
             if pa == p1 or pa == p2: # linear
                 pass # all good
-            elif wc.files() or wc.deleted():
+            elif wc.dirty(missing=True):
                 raise util.Abort(_("crosses branches (merge branches or use"
                                    " --clean to discard changes)"))
             elif onode is None:
-                raise util.Abort(_("crosses branches (merge branches or use"
+                raise util.Abort(_("crosses branches (merge branches or update"
                                    " --check to force update)"))
             else:
                 # Allow jumping branches if clean and specific rev given
@@ -551,7 +556,7 @@
         if not partial:
             repo.dirstate.setparents(fp1, fp2)
             recordupdates(repo, action, branchmerge)
-            if not branchmerge and not fastforward:
+            if not branchmerge:
                 repo.dirstate.setbranch(p2.branch())
     finally:
         wlock.release()
--- a/mercurial/minirst.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/minirst.py	Sat Jun 18 17:03:01 2011 -0500
@@ -467,10 +467,10 @@
         print
         return blocks
 
-    text = open(sys.argv[1]).read()
+    text = sys.stdin.read()
     blocks = debug(findblocks, text)
     blocks = debug(findliteralblocks, blocks)
-    blocks, pruned = debug(prunecontainers, blocks, sys.argv[2:])
+    blocks, pruned = debug(prunecontainers, blocks, sys.argv[1:])
     blocks = debug(inlineliterals, blocks)
     blocks = debug(splitparagraphs, blocks)
     blocks = debug(updatefieldlists, blocks)
--- a/mercurial/osutil.c	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/osutil.c	Sat Jun 18 17:03:01 2011 -0500
@@ -514,6 +514,22 @@
 }
 #endif
 
+#ifdef __APPLE__
+#include <ApplicationServices/ApplicationServices.h>
+
+static PyObject *isgui(PyObject *self)
+{
+	CFDictionaryRef dict = CGSessionCopyCurrentDictionary();
+
+	if (dict != NULL) {
+		CFRelease(dict);
+		return Py_True;
+	} else {
+		return Py_False;
+	}
+}
+#endif
+
 static char osutil_doc[] = "Native operating system services.";
 
 static PyMethodDef methods[] = {
@@ -524,6 +540,12 @@
 	 "Open a file with POSIX-like semantics.\n"
 "On error, this function may raise either a WindowsError or an IOError."},
 #endif
+#ifdef __APPLE__
+	{
+		"isgui", (PyCFunction)isgui, METH_NOARGS,
+		"Is a CoreGraphics session available?"
+	},
+#endif
 	{NULL, NULL}
 };
 
--- a/mercurial/patch.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/patch.py	Sat Jun 18 17:03:01 2011 -0500
@@ -7,35 +7,18 @@
 # GNU General Public License version 2 or any later version.
 
 import cStringIO, email.Parser, os, errno, re
-import tempfile, zlib
+import tempfile, zlib, shutil
 
 from i18n import _
 from node import hex, nullid, short
-import base85, mdiff, util, diffhelpers, copies, encoding
+import base85, mdiff, scmutil, util, diffhelpers, copies, encoding, error
+import context
 
 gitre = re.compile('diff --git a/(.*) b/(.*)')
 
 class PatchError(Exception):
     pass
 
-# helper functions
-
-def copyfile(src, dst, basedir):
-    abssrc, absdst = [util.canonpath(basedir, basedir, x) for x in [src, dst]]
-    if os.path.lexists(absdst):
-        raise util.Abort(_("cannot create %s: destination already exists") %
-                         dst)
-
-    dstdir = os.path.dirname(absdst)
-    if dstdir and not os.path.isdir(dstdir):
-        try:
-            os.makedirs(dstdir)
-        except IOError:
-            raise util.Abort(
-                _("cannot create %s: unable to create destination directory")
-                % dst)
-
-    util.copyfile(abssrc, absdst)
 
 # public functions
 
@@ -299,6 +282,14 @@
         isexec = mode & 0100
         self.mode = (islink, isexec)
 
+    def copy(self):
+        other = patchmeta(self.path)
+        other.oldpath = self.oldpath
+        other.mode = self.mode
+        other.op = self.op
+        other.binary = self.binary
+        return other
+
     def __repr__(self):
         return "<patchmeta %s %r>" % (self.op, self.path)
 
@@ -348,11 +339,9 @@
 
 class linereader(object):
     # simple class to allow pushing lines back into the input stream
-    def __init__(self, fp, textmode=False):
+    def __init__(self, fp):
         self.fp = fp
         self.buf = []
-        self.textmode = textmode
-        self.eol = None
 
     def push(self, line):
         if line is not None:
@@ -363,46 +352,270 @@
             l = self.buf[0]
             del self.buf[0]
             return l
-        l = self.fp.readline()
-        if not self.eol:
-            if l.endswith('\r\n'):
-                self.eol = '\r\n'
-            elif l.endswith('\n'):
-                self.eol = '\n'
-        if self.textmode and l.endswith('\r\n'):
-            l = l[:-2] + '\n'
-        return l
+        return self.fp.readline()
 
     def __iter__(self):
-        while 1:
+        while True:
             l = self.readline()
             if not l:
                 break
             yield l
 
+class abstractbackend(object):
+    def __init__(self, ui):
+        self.ui = ui
+
+    def getfile(self, fname):
+        """Return target file data and flags as a (data, (islink,
+        isexec)) tuple.
+        """
+        raise NotImplementedError
+
+    def setfile(self, fname, data, mode, copysource):
+        """Write data to target file fname and set its mode. mode is a
+        (islink, isexec) tuple. If data is None, the file content should
+        be left unchanged. If the file is modified after being copied,
+        copysource is set to the original file name.
+        """
+        raise NotImplementedError
+
+    def unlink(self, fname):
+        """Unlink target file."""
+        raise NotImplementedError
+
+    def writerej(self, fname, failed, total, lines):
+        """Write rejected lines for fname. total is the number of hunks
+        which failed to apply and total the total number of hunks for this
+        files.
+        """
+        pass
+
+    def exists(self, fname):
+        raise NotImplementedError
+
+class fsbackend(abstractbackend):
+    def __init__(self, ui, basedir):
+        super(fsbackend, self).__init__(ui)
+        self.opener = scmutil.opener(basedir)
+
+    def _join(self, f):
+        return os.path.join(self.opener.base, f)
+
+    def getfile(self, fname):
+        path = self._join(fname)
+        if os.path.islink(path):
+            return (os.readlink(path), (True, False))
+        isexec = False
+        try:
+            isexec = os.lstat(path).st_mode & 0100 != 0
+        except OSError, e:
+            if e.errno != errno.ENOENT:
+                raise
+        return (self.opener.read(fname), (False, isexec))
+
+    def setfile(self, fname, data, mode, copysource):
+        islink, isexec = mode
+        if data is None:
+            util.setflags(self._join(fname), islink, isexec)
+            return
+        if islink:
+            self.opener.symlink(data, fname)
+        else:
+            self.opener.write(fname, data)
+            if isexec:
+                util.setflags(self._join(fname), False, True)
+
+    def unlink(self, fname):
+        try:
+            util.unlinkpath(self._join(fname))
+        except OSError, inst:
+            if inst.errno != errno.ENOENT:
+                raise
+
+    def writerej(self, fname, failed, total, lines):
+        fname = fname + ".rej"
+        self.ui.warn(
+            _("%d out of %d hunks FAILED -- saving rejects to file %s\n") %
+            (failed, total, fname))
+        fp = self.opener(fname, 'w')
+        fp.writelines(lines)
+        fp.close()
+
+    def exists(self, fname):
+        return os.path.lexists(self._join(fname))
+
+class workingbackend(fsbackend):
+    def __init__(self, ui, repo, similarity):
+        super(workingbackend, self).__init__(ui, repo.root)
+        self.repo = repo
+        self.similarity = similarity
+        self.removed = set()
+        self.changed = set()
+        self.copied = []
+
+    def _checkknown(self, fname):
+        if self.repo.dirstate[fname] == '?' and self.exists(fname):
+            raise PatchError(_('cannot patch %s: file is not tracked') % fname)
+
+    def setfile(self, fname, data, mode, copysource):
+        self._checkknown(fname)
+        super(workingbackend, self).setfile(fname, data, mode, copysource)
+        if copysource is not None:
+            self.copied.append((copysource, fname))
+        self.changed.add(fname)
+
+    def unlink(self, fname):
+        self._checkknown(fname)
+        super(workingbackend, self).unlink(fname)
+        self.removed.add(fname)
+        self.changed.add(fname)
+
+    def close(self):
+        wctx = self.repo[None]
+        addremoved = set(self.changed)
+        for src, dst in self.copied:
+            scmutil.dirstatecopy(self.ui, self.repo, wctx, src, dst)
+            addremoved.discard(src)
+        if (not self.similarity) and self.removed:
+            wctx.forget(sorted(self.removed))
+        if addremoved:
+            cwd = self.repo.getcwd()
+            if cwd:
+                addremoved = [util.pathto(self.repo.root, cwd, f)
+                              for f in addremoved]
+            scmutil.addremove(self.repo, addremoved, similarity=self.similarity)
+        return sorted(self.changed)
+
+class filestore(object):
+    def __init__(self, maxsize=None):
+        self.opener = None
+        self.files = {}
+        self.created = 0
+        self.maxsize = maxsize
+        if self.maxsize is None:
+            self.maxsize = 4*(2**20)
+        self.size = 0
+        self.data = {}
+
+    def setfile(self, fname, data, mode, copied=None):
+        if self.maxsize < 0 or (len(data) + self.size) <= self.maxsize:
+            self.data[fname] = (data, mode, copied)
+            self.size += len(data)
+        else:
+            if self.opener is None:
+                root = tempfile.mkdtemp(prefix='hg-patch-')
+                self.opener = scmutil.opener(root)
+            # Avoid filename issues with these simple names
+            fn = str(self.created)
+            self.opener.write(fn, data)
+            self.created += 1
+            self.files[fname] = (fn, mode, copied)
+
+    def getfile(self, fname):
+        if fname in self.data:
+            return self.data[fname]
+        if not self.opener or fname not in self.files:
+            raise IOError()
+        fn, mode, copied = self.files[fname]
+        return self.opener.read(fn), mode, copied
+
+    def close(self):
+        if self.opener:
+            shutil.rmtree(self.opener.base)
+
+class repobackend(abstractbackend):
+    def __init__(self, ui, repo, ctx, store):
+        super(repobackend, self).__init__(ui)
+        self.repo = repo
+        self.ctx = ctx
+        self.store = store
+        self.changed = set()
+        self.removed = set()
+        self.copied = {}
+
+    def _checkknown(self, fname):
+        if fname not in self.ctx:
+            raise PatchError(_('cannot patch %s: file is not tracked') % fname)
+
+    def getfile(self, fname):
+        try:
+            fctx = self.ctx[fname]
+        except error.LookupError:
+            raise IOError()
+        flags = fctx.flags()
+        return fctx.data(), ('l' in flags, 'x' in flags)
+
+    def setfile(self, fname, data, mode, copysource):
+        if copysource:
+            self._checkknown(copysource)
+        if data is None:
+            data = self.ctx[fname].data()
+        self.store.setfile(fname, data, mode, copysource)
+        self.changed.add(fname)
+        if copysource:
+            self.copied[fname] = copysource
+
+    def unlink(self, fname):
+        self._checkknown(fname)
+        self.removed.add(fname)
+
+    def exists(self, fname):
+        return fname in self.ctx
+
+    def close(self):
+        return self.changed | self.removed
+
 # @@ -start,len +start,len @@ or @@ -start +start @@ if len is 1
 unidesc = re.compile('@@ -(\d+)(,(\d+))? \+(\d+)(,(\d+))? @@')
 contextdesc = re.compile('(---|\*\*\*) (\d+)(,(\d+))? (---|\*\*\*)')
 eolmodes = ['strict', 'crlf', 'lf', 'auto']
 
 class patchfile(object):
-    def __init__(self, ui, fname, opener, missing=False, eolmode='strict'):
-        self.fname = fname
+    def __init__(self, ui, gp, backend, store, eolmode='strict'):
+        self.fname = gp.path
         self.eolmode = eolmode
         self.eol = None
-        self.opener = opener
+        self.backend = backend
         self.ui = ui
         self.lines = []
         self.exists = False
-        self.missing = missing
-        if not missing:
-            try:
-                self.lines = self.readlines(fname)
+        self.missing = True
+        self.mode = gp.mode
+        self.copysource = gp.oldpath
+        self.create = gp.op in ('ADD', 'COPY', 'RENAME')
+        self.remove = gp.op == 'DELETE'
+        try:
+            if self.copysource is None:
+                data, mode = backend.getfile(self.fname)
                 self.exists = True
-            except IOError:
-                pass
-        else:
-            self.ui.warn(_("unable to find '%s' for patching\n") % self.fname)
+            else:
+                data, mode = store.getfile(self.copysource)[:2]
+                self.exists = backend.exists(self.fname)
+            self.missing = False
+            if data:
+                self.lines = data.splitlines(True)
+            if self.mode is None:
+                self.mode = mode
+            if self.lines:
+                # Normalize line endings
+                if self.lines[0].endswith('\r\n'):
+                    self.eol = '\r\n'
+                elif self.lines[0].endswith('\n'):
+                    self.eol = '\n'
+                if eolmode != 'strict':
+                    nlines = []
+                    for l in self.lines:
+                        if l.endswith('\r\n'):
+                            l = l[:-2] + '\n'
+                        nlines.append(l)
+                    self.lines = nlines
+        except IOError:
+            if self.create:
+                self.missing = False
+            if self.mode is None:
+                self.mode = (False, False)
+        if self.missing:
+             self.ui.warn(_("unable to find '%s' for patching\n") % self.fname)
 
         self.hash = {}
         self.dirty = 0
@@ -413,57 +626,23 @@
         self.printfile(False)
         self.hunks = 0
 
-    def readlines(self, fname):
-        if os.path.islink(fname):
-            return [os.readlink(fname)]
-        fp = self.opener(fname, 'r')
-        try:
-            lr = linereader(fp, self.eolmode != 'strict')
-            lines = list(lr)
-            self.eol = lr.eol
-            return lines
-        finally:
-            fp.close()
-
-    def writelines(self, fname, lines):
-        # Ensure supplied data ends in fname, being a regular file or
-        # a symlink. cmdutil.updatedir will -too magically- take care
-        # of setting it to the proper type afterwards.
-        st_mode = None
-        islink = os.path.islink(fname)
-        if islink:
-            fp = cStringIO.StringIO()
+    def writelines(self, fname, lines, mode):
+        if self.eolmode == 'auto':
+            eol = self.eol
+        elif self.eolmode == 'crlf':
+            eol = '\r\n'
         else:
-            try:
-                st_mode = os.lstat(fname).st_mode & 0777
-            except OSError, e:
-                if e.errno != errno.ENOENT:
-                    raise
-            fp = self.opener(fname, 'w')
-        try:
-            if self.eolmode == 'auto':
-                eol = self.eol
-            elif self.eolmode == 'crlf':
-                eol = '\r\n'
-            else:
-                eol = '\n'
+            eol = '\n'
 
-            if self.eolmode != 'strict' and eol and eol != '\n':
-                for l in lines:
-                    if l and l[-1] == '\n':
-                        l = l[:-1] + eol
-                    fp.write(l)
-            else:
-                fp.writelines(lines)
-            if islink:
-                self.opener.symlink(fp.getvalue(), fname)
-            if st_mode is not None:
-                os.chmod(fname, st_mode)
-        finally:
-            fp.close()
+        if self.eolmode != 'strict' and eol and eol != '\n':
+            rawlines = []
+            for l in lines:
+                if l and l[-1] == '\n':
+                    l = l[:-1] + eol
+                rawlines.append(l)
+            lines = rawlines
 
-    def unlink(self, fname):
-        os.unlink(fname)
+        self.backend.setfile(fname, ''.join(lines), mode, self.copysource)
 
     def printfile(self, warn):
         if self.fileprinted:
@@ -488,37 +667,21 @@
             cand.sort(key=lambda x: abs(x - linenum))
         return cand
 
-    def hashlines(self):
-        self.hash = {}
-        for x, s in enumerate(self.lines):
-            self.hash.setdefault(s, []).append(x)
-
-    def makerejlines(self, fname):
-        base = os.path.basename(fname)
-        yield "--- %s\n+++ %s\n" % (base, base)
-        for x in self.rej:
-            for l in x.hunk:
-                yield l
-                if l[-1] != '\n':
-                    yield "\n\ No newline at end of file\n"
-
     def write_rej(self):
         # our rejects are a little different from patch(1).  This always
         # creates rejects in the same form as the original patch.  A file
         # header is inserted so that you can run the reject through patch again
         # without having to type the filename.
-
         if not self.rej:
             return
-
-        fname = self.fname + ".rej"
-        self.ui.warn(
-            _("%d out of %d hunks FAILED -- saving rejects to file %s\n") %
-            (len(self.rej), self.hunks, fname))
-
-        fp = self.opener(fname, 'w')
-        fp.writelines(self.makerejlines(self.fname))
-        fp.close()
+        base = os.path.basename(self.fname)
+        lines = ["--- %s\n+++ %s\n" % (base, base)]
+        for x in self.rej:
+            for l in x.hunk:
+                lines.append(l)
+                if l[-1] != '\n':
+                    lines.append("\n\ No newline at end of file\n")
+        self.backend.writerej(self.fname, len(self.rej), self.hunks, lines)
 
     def apply(self, h):
         if not h.complete():
@@ -532,18 +695,22 @@
             self.rej.append(h)
             return -1
 
-        if self.exists and h.createfile():
-            self.ui.warn(_("file %s already exists\n") % self.fname)
+        if self.exists and self.create:
+            if self.copysource:
+                self.ui.warn(_("cannot create %s: destination already "
+                               "exists\n" % self.fname))
+            else:
+                self.ui.warn(_("file %s already exists\n") % self.fname)
             self.rej.append(h)
             return -1
 
         if isinstance(h, binhunk):
-            if h.rmfile():
-                self.unlink(self.fname)
+            if self.remove:
+                self.backend.unlink(self.fname)
             else:
                 self.lines[:] = h.new()
                 self.offset += len(h.new())
-                self.dirty = 1
+                self.dirty = True
             return 0
 
         horig = h
@@ -566,16 +733,18 @@
         # when the hunk cleanly applies at start + skew, so skip the
         # fast case code
         if self.skew == 0 and diffhelpers.testhunk(old, self.lines, start) == 0:
-            if h.rmfile():
-                self.unlink(self.fname)
+            if self.remove:
+                self.backend.unlink(self.fname)
             else:
                 self.lines[start : start + h.lena] = h.new()
                 self.offset += h.lenb - h.lena
-                self.dirty = 1
+                self.dirty = True
             return 0
 
-        # ok, we couldn't match the hunk.  Lets look for offsets and fuzz it
-        self.hashlines()
+        # ok, we couldn't match the hunk. Lets look for offsets and fuzz it
+        self.hash = {}
+        for x, s in enumerate(self.lines):
+            self.hash.setdefault(s, []).append(x)
         if h.hunk[-1][0] != ' ':
             # if the hunk tried to put something at the bottom of the file
             # override the start line and use eof here
@@ -594,7 +763,7 @@
                         self.lines[l : l + len(old)] = newlines
                         self.offset += len(newlines) - len(old)
                         self.skew = l - orig_start
-                        self.dirty = 1
+                        self.dirty = True
                         offset = l - orig_start - fuzzlen
                         if fuzzlen:
                             msg = _("Hunk #%d succeeded at %d "
@@ -613,8 +782,14 @@
         self.rej.append(horig)
         return -1
 
+    def close(self):
+        if self.dirty:
+            self.writelines(self.fname, self.lines, self.mode)
+        self.write_rej()
+        return len(self.rej)
+
 class hunk(object):
-    def __init__(self, desc, num, lr, context, create=False, remove=False):
+    def __init__(self, desc, num, lr, context):
         self.number = num
         self.desc = desc
         self.hunk = [desc]
@@ -627,8 +802,6 @@
                 self.read_context_hunk(lr)
             else:
                 self.read_unified_hunk(lr)
-        self.create = create
-        self.remove = remove and not create
 
     def getnormalized(self):
         """Return a copy with line endings normalized to LF."""
@@ -642,7 +815,7 @@
             return nlines
 
         # Dummy object, it is rebuilt manually
-        nh = hunk(self.desc, self.number, None, None, False, False)
+        nh = hunk(self.desc, self.number, None, None)
         nh.number = self.number
         nh.desc = self.desc
         nh.hunk = self.hunk
@@ -652,8 +825,6 @@
         nh.startb = self.startb
         nh.lena = self.lena
         nh.lenb = self.lenb
-        nh.create = self.create
-        nh.remove = self.remove
         return nh
 
     def read_unified_hunk(self, lr):
@@ -680,6 +851,7 @@
             del self.b[-1]
             self.lena -= 1
             self.lenb -= 1
+        self._fixnewline(lr)
 
     def read_context_hunk(self, lr):
         self.desc = lr.readline()
@@ -782,19 +954,18 @@
         self.desc = "@@ -%d,%d +%d,%d @@\n" % (self.starta, self.lena,
                                              self.startb, self.lenb)
         self.hunk[0] = self.desc
+        self._fixnewline(lr)
 
-    def fix_newline(self):
-        diffhelpers.fix_newline(self.hunk, self.a, self.b)
+    def _fixnewline(self, lr):
+        l = lr.readline()
+        if l.startswith('\ '):
+            diffhelpers.fix_newline(self.hunk, self.a, self.b)
+        else:
+            lr.push(l)
 
     def complete(self):
         return len(self.a) == self.lena and len(self.b) == self.lenb
 
-    def createfile(self):
-        return self.starta == 0 and self.lena == 0 and self.create
-
-    def rmfile(self):
-        return self.startb == 0 and self.lenb == 0 and self.remove
-
     def fuzzit(self, l, fuzz, toponly):
         # this removes context lines from the top and bottom of list 'l'.  It
         # checks the hunk to make sure only context lines are removed, and then
@@ -840,16 +1011,10 @@
 
 class binhunk:
     'A binary patch file. Only understands literals so far.'
-    def __init__(self, gitpatch):
-        self.gitpatch = gitpatch
+    def __init__(self, lr):
         self.text = None
         self.hunk = ['GIT binary patch\n']
-
-    def createfile(self):
-        return self.gitpatch.op in ('ADD', 'RENAME', 'COPY')
-
-    def rmfile(self):
-        return self.gitpatch.op == 'DELETE'
+        self._read(lr)
 
     def complete(self):
         return self.text is not None
@@ -857,7 +1022,7 @@
     def new(self):
         return [self.text]
 
-    def extract(self, lr):
+    def _read(self, lr):
         line = lr.readline()
         self.hunk.append(line)
         while line and not line.startswith('literal '):
@@ -912,30 +1077,28 @@
         count -= 1
     return path[:i].lstrip(), path[i:].rstrip()
 
-def selectfile(afile_orig, bfile_orig, hunk, strip):
+def makepatchmeta(backend, afile_orig, bfile_orig, hunk, strip):
     nulla = afile_orig == "/dev/null"
     nullb = bfile_orig == "/dev/null"
+    create = nulla and hunk.starta == 0 and hunk.lena == 0
+    remove = nullb and hunk.startb == 0 and hunk.lenb == 0
     abase, afile = pathstrip(afile_orig, strip)
-    gooda = not nulla and os.path.lexists(afile)
+    gooda = not nulla and backend.exists(afile)
     bbase, bfile = pathstrip(bfile_orig, strip)
     if afile == bfile:
         goodb = gooda
     else:
-        goodb = not nullb and os.path.lexists(bfile)
-    createfunc = hunk.createfile
-    missing = not goodb and not gooda and not createfunc()
+        goodb = not nullb and backend.exists(bfile)
+    missing = not goodb and not gooda and not create
 
     # some diff programs apparently produce patches where the afile is
     # not /dev/null, but afile starts with bfile
     abasedir = afile[:afile.rfind('/') + 1]
     bbasedir = bfile[:bfile.rfind('/') + 1]
-    if missing and abasedir == bbasedir and afile.startswith(bfile):
-        # this isn't very pretty
-        hunk.create = True
-        if createfunc():
-            missing = False
-        else:
-            hunk.create = False
+    if (missing and abasedir == bbasedir and afile.startswith(bfile)
+        and hunk.starta == 0 and hunk.lena == 0):
+        create = True
+        missing = False
 
     # If afile is "a/b/foo" and bfile is "a/b/foo.orig" we assume the
     # diff is between a file and its backup. In this case, the original
@@ -956,7 +1119,12 @@
         else:
             raise PatchError(_("undefined source and destination files"))
 
-    return fname, missing
+    gp = patchmeta(fname)
+    if create:
+        gp.op = 'ADD'
+    elif remove:
+        gp.op = 'DELETE'
+    return gp
 
 def scangitpatch(lr, firstline):
     """
@@ -978,13 +1146,13 @@
         fp = lr.fp
     except IOError:
         fp = cStringIO.StringIO(lr.fp.read())
-    gitlr = linereader(fp, lr.textmode)
+    gitlr = linereader(fp)
     gitlr.push(firstline)
     gitpatches = readgitpatch(gitlr)
     fp.seek(pos)
     return gitpatches
 
-def iterhunks(ui, fp):
+def iterhunks(fp):
     """Read a patch and yield the following events:
     - ("file", afile, bfile, firsthunk): select a new target file.
     - ("hunk", hunk): a new hunk is ready to be applied, follows a
@@ -992,14 +1160,12 @@
     - ("git", gitchanges): current diff is in git format, gitchanges
     maps filenames to gitpatch records. Unique event.
     """
-    changed = {}
-    current_hunk = None
     afile = ""
     bfile = ""
     state = None
     hunknum = 0
-    emitfile = False
-    git = False
+    emitfile = newfile = False
+    gitpatches = None
 
     # our states
     BFILE = 1
@@ -1007,52 +1173,49 @@
     lr = linereader(fp)
 
     while True:
-        newfile = newgitfile = False
         x = lr.readline()
         if not x:
             break
-        if current_hunk:
-            if x.startswith('\ '):
-                current_hunk.fix_newline()
-            yield 'hunk', current_hunk
-            current_hunk = None
-        if (state == BFILE and ((not context and x[0] == '@') or
-            ((context is not False) and x.startswith('***************')))):
-            if context is None and x.startswith('***************'):
-                context = True
-            gpatch = changed.get(bfile)
-            create = afile == '/dev/null' or gpatch and gpatch.op == 'ADD'
-            remove = bfile == '/dev/null' or gpatch and gpatch.op == 'DELETE'
-            current_hunk = hunk(x, hunknum + 1, lr, context, create, remove)
+        if state == BFILE and (
+            (not context and x[0] == '@')
+            or (context is not False and x.startswith('***************'))
+            or x.startswith('GIT binary patch')):
+            gp = None
+            if (gitpatches and
+                (gitpatches[-1][0] == afile or gitpatches[-1][1] == bfile)):
+                gp = gitpatches.pop()[2]
+            if x.startswith('GIT binary patch'):
+                h = binhunk(lr)
+            else:
+                if context is None and x.startswith('***************'):
+                    context = True
+                h = hunk(x, hunknum + 1, lr, context)
             hunknum += 1
             if emitfile:
                 emitfile = False
-                yield 'file', (afile, bfile, current_hunk)
-        elif state == BFILE and x.startswith('GIT binary patch'):
-            current_hunk = binhunk(changed[bfile])
-            hunknum += 1
-            if emitfile:
-                emitfile = False
-                yield 'file', ('a/' + afile, 'b/' + bfile, current_hunk)
-            current_hunk.extract(lr)
+                yield 'file', (afile, bfile, h, gp and gp.copy() or None)
+            yield 'hunk', h
         elif x.startswith('diff --git'):
-            # check for git diff, scanning the whole patch file if needed
             m = gitre.match(x)
-            if m:
-                afile, bfile = m.group(1, 2)
-                if not git:
-                    git = True
-                    gitpatches = scangitpatch(lr, x)
-                    yield 'git', gitpatches
-                    for gp in gitpatches:
-                        changed[gp.path] = gp
-                # else error?
-                # copy/rename + modify should modify target, not source
-                gp = changed.get(bfile)
-                if gp and (gp.op in ('COPY', 'DELETE', 'RENAME', 'ADD')
-                           or gp.mode):
-                    afile = bfile
-                newgitfile = True
+            if not m:
+                continue
+            if gitpatches is None:
+                # scan whole input for git metadata
+                gitpatches = [('a/' + gp.path, 'b/' + gp.path, gp) for gp
+                              in scangitpatch(lr, x)]
+                yield 'git', [g[2].copy() for g in gitpatches
+                              if g[2].op in ('COPY', 'RENAME')]
+                gitpatches.reverse()
+            afile = 'a/' + m.group(1)
+            bfile = 'b/' + m.group(2)
+            while afile != gitpatches[-1][0] and bfile != gitpatches[-1][1]:
+                gp = gitpatches.pop()[2]
+                yield 'file', ('a/' + gp.path, 'b/' + gp.path, None, gp.copy())
+            gp = gitpatches[-1][2]
+            # copy/rename + modify should modify target, not source
+            if gp.op in ('COPY', 'DELETE', 'RENAME', 'ADD') or gp.mode:
+                afile = bfile
+            newfile = True
         elif x.startswith('---'):
             # check for a unified diff
             l2 = lr.readline()
@@ -1079,158 +1242,205 @@
             afile = parsefilename(x)
             bfile = parsefilename(l2)
 
-        if newgitfile or newfile:
+        if newfile:
+            newfile = False
             emitfile = True
             state = BFILE
             hunknum = 0
-    if current_hunk:
-        if current_hunk.complete():
-            yield 'hunk', current_hunk
-        else:
-            raise PatchError(_("malformed patch %s %s") % (afile,
-                             current_hunk.desc))
 
-def applydiff(ui, fp, changed, strip=1, eolmode='strict'):
+    while gitpatches:
+        gp = gitpatches.pop()[2]
+        yield 'file', ('a/' + gp.path, 'b/' + gp.path, None, gp.copy())
+
+def applydiff(ui, fp, backend, store, strip=1, eolmode='strict'):
     """Reads a patch from fp and tries to apply it.
 
-    The dict 'changed' is filled in with all of the filenames changed
-    by the patch. Returns 0 for a clean patch, -1 if any rejects were
-    found and 1 if there was any fuzz.
+    Returns 0 for a clean patch, -1 if any rejects were found and 1 if
+    there was any fuzz.
 
     If 'eolmode' is 'strict', the patch content and patched file are
     read in binary mode. Otherwise, line endings are ignored when
     patching then normalized according to 'eolmode'.
-
-    Callers probably want to call 'cmdutil.updatedir' after this to
-    apply certain categories of changes not done by this function.
     """
-    return _applydiff(ui, fp, patchfile, copyfile, changed, strip=strip,
+    return _applydiff(ui, fp, patchfile, backend, store, strip=strip,
                       eolmode=eolmode)
 
-def _applydiff(ui, fp, patcher, copyfn, changed, strip=1, eolmode='strict'):
+def _applydiff(ui, fp, patcher, backend, store, strip=1,
+               eolmode='strict'):
+
+    def pstrip(p):
+        return pathstrip(p, strip - 1)[1]
+
     rejects = 0
     err = 0
     current_file = None
-    cwd = os.getcwd()
-    opener = util.opener(cwd)
 
-    def closefile():
-        if not current_file:
-            return 0
-        if current_file.dirty:
-            current_file.writelines(current_file.fname, current_file.lines)
-        current_file.write_rej()
-        return len(current_file.rej)
-
-    for state, values in iterhunks(ui, fp):
+    for state, values in iterhunks(fp):
         if state == 'hunk':
             if not current_file:
                 continue
             ret = current_file.apply(values)
-            if ret >= 0:
-                changed.setdefault(current_file.fname, None)
-                if ret > 0:
-                    err = 1
+            if ret > 0:
+                err = 1
         elif state == 'file':
-            rejects += closefile()
-            afile, bfile, first_hunk = values
+            if current_file:
+                rejects += current_file.close()
+                current_file = None
+            afile, bfile, first_hunk, gp = values
+            if gp:
+                path = pstrip(gp.path)
+                gp.path = pstrip(gp.path)
+                if gp.oldpath:
+                    gp.oldpath = pstrip(gp.oldpath)
+            else:
+                gp = makepatchmeta(backend, afile, bfile, first_hunk, strip)
+            if gp.op == 'RENAME':
+                backend.unlink(gp.oldpath)
+            if not first_hunk:
+                if gp.op == 'DELETE':
+                    backend.unlink(gp.path)
+                    continue
+                data, mode = None, None
+                if gp.op in ('RENAME', 'COPY'):
+                    data, mode = store.getfile(gp.oldpath)[:2]
+                if gp.mode:
+                    mode = gp.mode
+                    if gp.op == 'ADD':
+                        # Added files without content have no hunk and
+                        # must be created
+                        data = ''
+                if data or mode:
+                    if (gp.op in ('ADD', 'RENAME', 'COPY')
+                        and backend.exists(gp.path)):
+                        raise PatchError(_("cannot create %s: destination "
+                                           "already exists") % gp.path)
+                    backend.setfile(gp.path, data, mode, gp.oldpath)
+                continue
             try:
-                current_file, missing = selectfile(afile, bfile,
-                                                   first_hunk, strip)
-                current_file = patcher(ui, current_file, opener,
-                                       missing=missing, eolmode=eolmode)
-            except PatchError, err:
-                ui.warn(str(err) + '\n')
+                current_file = patcher(ui, gp, backend, store,
+                                       eolmode=eolmode)
+            except PatchError, inst:
+                ui.warn(str(inst) + '\n')
                 current_file = None
                 rejects += 1
                 continue
         elif state == 'git':
             for gp in values:
-                gp.path = pathstrip(gp.path, strip - 1)[1]
-                if gp.oldpath:
-                    gp.oldpath = pathstrip(gp.oldpath, strip - 1)[1]
-                # Binary patches really overwrite target files, copying them
-                # will just make it fails with "target file exists"
-                if gp.op in ('COPY', 'RENAME') and not gp.binary:
-                    copyfn(gp.oldpath, gp.path, cwd)
-                changed[gp.path] = gp
+                path = pstrip(gp.oldpath)
+                data, mode = backend.getfile(path)
+                store.setfile(path, data, mode)
         else:
             raise util.Abort(_('unsupported parser state: %s') % state)
 
-    rejects += closefile()
+    if current_file:
+        rejects += current_file.close()
 
     if rejects:
         return -1
     return err
 
-def externalpatch(patcher, patchname, ui, strip, cwd, files):
+def _externalpatch(ui, repo, patcher, patchname, strip, files,
+                   similarity):
     """use <patcher> to apply <patchname> to the working directory.
     returns whether patch was applied with fuzz factor."""
 
     fuzz = False
     args = []
+    cwd = repo.root
     if cwd:
         args.append('-d %s' % util.shellquote(cwd))
     fp = util.popen('%s %s -p%d < %s' % (patcher, ' '.join(args), strip,
                                        util.shellquote(patchname)))
-
-    for line in fp:
-        line = line.rstrip()
-        ui.note(line + '\n')
-        if line.startswith('patching file '):
-            pf = util.parse_patch_output(line)
-            printed_file = False
-            files.setdefault(pf, None)
-        elif line.find('with fuzz') >= 0:
-            fuzz = True
-            if not printed_file:
-                ui.warn(pf + '\n')
-                printed_file = True
-            ui.warn(line + '\n')
-        elif line.find('saving rejects to file') >= 0:
-            ui.warn(line + '\n')
-        elif line.find('FAILED') >= 0:
-            if not printed_file:
-                ui.warn(pf + '\n')
-                printed_file = True
-            ui.warn(line + '\n')
+    try:
+        for line in fp:
+            line = line.rstrip()
+            ui.note(line + '\n')
+            if line.startswith('patching file '):
+                pf = util.parsepatchoutput(line)
+                printed_file = False
+                files.add(pf)
+            elif line.find('with fuzz') >= 0:
+                fuzz = True
+                if not printed_file:
+                    ui.warn(pf + '\n')
+                    printed_file = True
+                ui.warn(line + '\n')
+            elif line.find('saving rejects to file') >= 0:
+                ui.warn(line + '\n')
+            elif line.find('FAILED') >= 0:
+                if not printed_file:
+                    ui.warn(pf + '\n')
+                    printed_file = True
+                ui.warn(line + '\n')
+    finally:
+        if files:
+            cfiles = list(files)
+            cwd = repo.getcwd()
+            if cwd:
+                cfiles = [util.pathto(repo.root, cwd, f)
+                          for f in cfile]
+            scmutil.addremove(repo, cfiles, similarity=similarity)
     code = fp.close()
     if code:
         raise PatchError(_("patch command failed: %s") %
-                         util.explain_exit(code)[0])
+                         util.explainexit(code)[0])
     return fuzz
 
-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."""
-
+def patchbackend(ui, backend, patchobj, strip, files=None, eolmode='strict'):
     if files is None:
-        files = {}
+        files = set()
     if eolmode is None:
         eolmode = ui.config('patch', 'eol', 'strict')
     if eolmode.lower() not in eolmodes:
         raise util.Abort(_('unsupported line endings type: %s') % eolmode)
     eolmode = eolmode.lower()
 
+    store = filestore()
     try:
         fp = open(patchobj, 'rb')
     except TypeError:
         fp = patchobj
-    if cwd:
-        curdir = os.getcwd()
-        os.chdir(cwd)
     try:
-        ret = applydiff(ui, fp, files, strip=strip, eolmode=eolmode)
+        ret = applydiff(ui, fp, backend, store, strip=strip,
+                        eolmode=eolmode)
     finally:
-        if cwd:
-            os.chdir(curdir)
         if fp != patchobj:
             fp.close()
+        files.update(backend.close())
+        store.close()
     if ret < 0:
         raise PatchError(_('patch failed to apply'))
     return ret > 0
 
-def patch(patchname, ui, strip=1, cwd=None, files=None, eolmode='strict'):
+def internalpatch(ui, repo, patchobj, strip, files=None, eolmode='strict',
+                  similarity=0):
+    """use builtin patch to apply <patchobj> to the working directory.
+    returns whether patch was applied with fuzz factor."""
+    backend = workingbackend(ui, repo, similarity)
+    return patchbackend(ui, backend, patchobj, strip, files, eolmode)
+
+def patchrepo(ui, repo, ctx, store, patchobj, strip, files=None,
+              eolmode='strict'):
+    backend = repobackend(ui, repo, ctx, store)
+    return patchbackend(ui, backend, patchobj, strip, files, eolmode)
+
+def makememctx(repo, parents, text, user, date, branch, files, store,
+               editor=None):
+    def getfilectx(repo, memctx, path):
+        data, (islink, isexec), copied = store.getfile(path)
+        return context.memfilectx(path, data, islink=islink, isexec=isexec,
+                                  copied=copied)
+    extra = {}
+    if branch:
+        extra['branch'] = encoding.fromlocal(branch)
+    ctx =  context.memctx(repo, parents, text, files, getfilectx, user,
+                          date, extra)
+    if editor:
+        ctx._text = editor(repo, ctx, [])
+    return ctx
+
+def patch(ui, repo, patchname, strip=1, files=None, eolmode='strict',
+          similarity=0):
     """Apply <patchname> to the working directory.
 
     'eolmode' specifies how end of lines should be handled. It can be:
@@ -1244,14 +1454,39 @@
     """
     patcher = ui.config('ui', 'patch')
     if files is None:
-        files = {}
+        files = set()
     try:
         if patcher:
-            return externalpatch(patcher, patchname, ui, strip, cwd, files)
-        return internalpatch(patchname, ui, strip, cwd, files, eolmode)
+            return _externalpatch(ui, repo, patcher, patchname, strip,
+                                  files, similarity)
+        return internalpatch(ui, repo, patchname, strip, files, eolmode,
+                             similarity)
     except PatchError, err:
         raise util.Abort(str(err))
 
+def changedfiles(ui, repo, patchpath, strip=1):
+    backend = fsbackend(ui, repo.root)
+    fp = open(patchpath, 'rb')
+    try:
+        changed = set()
+        for state, values in iterhunks(fp):
+            if state == 'file':
+                afile, bfile, first_hunk, gp = values
+                if gp:
+                    gp.path = pathstrip(gp.path, strip - 1)[1]
+                    if gp.oldpath:
+                        gp.oldpath = pathstrip(gp.oldpath, strip - 1)[1]
+                else:
+                    gp = makepatchmeta(backend, afile, bfile, first_hunk, strip)
+                changed.add(gp.path)
+                if gp.op == 'RENAME':
+                    changed.add(gp.oldpath)
+            elif state not in ('hunk', 'git'):
+                raise util.Abort(_('unsupported parser state: %s') % state)
+        return changed
+    finally:
+        fp.close()
+
 def b85diff(to, tn):
     '''print base85-encoded binary diff'''
     def gitindex(text):
@@ -1331,7 +1566,7 @@
         opts = mdiff.defaultopts
 
     if not node1 and not node2:
-        node1 = repo.dirstate.parents()[0]
+        node1 = repo.dirstate.p1()
 
     def lrugetfilectx():
         cache = {}
@@ -1528,15 +1763,31 @@
             if text:
                 yield text
 
+def diffstatsum(stats):
+    maxfile, maxtotal, addtotal, removetotal, binary = 0, 0, 0, 0, False
+    for f, a, r, b in stats:
+        maxfile = max(maxfile, encoding.colwidth(f))
+        maxtotal = max(maxtotal, a + r)
+        addtotal += a
+        removetotal += r
+        binary = binary or b
+
+    return maxfile, maxtotal, addtotal, removetotal, binary
+
 def diffstatdata(lines):
     diffre = re.compile('^diff .*-r [a-z0-9]+\s(.*)$')
 
+    results = []
     filename, adds, removes = None, 0, 0
+
+    def addresult():
+        if filename:
+            isbinary = adds == 0 and removes == 0
+            results.append((filename, adds, removes, isbinary))
+
     for line in lines:
         if line.startswith('diff'):
-            if filename:
-                isbinary = adds == 0 and removes == 0
-                yield (filename, adds, removes, isbinary)
+            addresult()
             # set numbers to 0 anyway when starting new file
             adds, removes = 0, 0
             if line.startswith('diff --git'):
@@ -1548,28 +1799,13 @@
             adds += 1
         elif line.startswith('-') and not line.startswith('---'):
             removes += 1
-    if filename:
-        isbinary = adds == 0 and removes == 0
-        yield (filename, adds, removes, isbinary)
+    addresult()
+    return results
 
 def diffstat(lines, width=80, git=False):
     output = []
-    stats = list(diffstatdata(lines))
-
-    maxtotal, maxname = 0, 0
-    totaladds, totalremoves = 0, 0
-    hasbinary = False
-
-    sized = [(filename, adds, removes, isbinary, encoding.colwidth(filename))
-             for filename, adds, removes, isbinary in stats]
-
-    for filename, adds, removes, isbinary, namewidth in sized:
-        totaladds += adds
-        totalremoves += removes
-        maxname = max(maxname, namewidth)
-        maxtotal = max(maxtotal, adds + removes)
-        if isbinary:
-            hasbinary = True
+    stats = diffstatdata(lines)
+    maxname, maxtotal, totaladds, totalremoves, hasbinary = diffstatsum(stats)
 
     countwidth = len(str(maxtotal))
     if hasbinary and countwidth < 3:
@@ -1586,7 +1822,7 @@
         # if there were at least some changes.
         return max(i * graphwidth // maxtotal, int(bool(i)))
 
-    for filename, adds, removes, isbinary, namewidth in sized:
+    for filename, adds, removes, isbinary in stats:
         if git and isbinary:
             count = 'Bin'
         else:
@@ -1594,9 +1830,8 @@
         pluses = '+' * scale(adds)
         minuses = '-' * scale(removes)
         output.append(' %s%s |  %*s %s%s\n' %
-                      (filename, ' ' * (maxname - namewidth),
-                       countwidth, count,
-                       pluses, minuses))
+                      (filename, ' ' * (maxname - encoding.colwidth(filename)),
+                       countwidth, count, pluses, minuses))
 
     if stats:
         output.append(_(' %d files changed, %d insertions(+), %d deletions(-)\n')
--- a/mercurial/posix.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/posix.py	Sat Jun 18 17:03:01 2011 -0500
@@ -6,14 +6,13 @@
 # GNU General Public License version 2 or any later version.
 
 from i18n import _
-import osutil
-import os, sys, errno, stat, getpass, pwd, grp
+import os, sys, errno, stat, getpass, pwd, grp, tempfile
 
 posixfile = open
 nulldev = '/dev/null'
 normpath = os.path.normpath
 samestat = os.path.samestat
-os_link = os.link
+oslink = os.link
 unlink = os.unlink
 rename = os.rename
 expandglobs = False
@@ -29,30 +28,7 @@
     '''return number of hardlinks for the given file'''
     return os.lstat(name).st_nlink
 
-def rcfiles(path):
-    rcs = [os.path.join(path, 'hgrc')]
-    rcdir = os.path.join(path, 'hgrc.d')
-    try:
-        rcs.extend([os.path.join(rcdir, f)
-                    for f, kind in osutil.listdir(rcdir)
-                    if f.endswith(".rc")])
-    except OSError:
-        pass
-    return rcs
-
-def system_rcpath():
-    path = []
-    # old mod_python does not set sys.argv
-    if len(getattr(sys, 'argv', [])) > 0:
-        path.extend(rcfiles(os.path.dirname(sys.argv[0]) +
-                              '/../etc/mercurial'))
-    path.extend(rcfiles('/etc/mercurial'))
-    return path
-
-def user_rcpath():
-    return [os.path.expanduser('~/.hgrc')]
-
-def parse_patch_output(output_line):
+def parsepatchoutput(output_line):
     """parses the output produced by patch and returns the filename"""
     pf = output_line[14:]
     if os.sys.platform == 'OpenVMS':
@@ -68,11 +44,11 @@
     args = user and ("%s@%s" % (user, host)) or host
     return port and ("%s -p %s" % (args, port)) or args
 
-def is_exec(f):
+def isexec(f):
     """check whether a file is executable"""
     return (os.lstat(f).st_mode & 0100 != 0)
 
-def set_flags(f, l, x):
+def setflags(f, l, x):
     s = os.lstat(f).st_mode
     if l:
         if not stat.S_ISLNK(s):
@@ -83,7 +59,7 @@
             os.unlink(f)
             try:
                 os.symlink(data, f)
-            except:
+            except OSError:
                 # failed to make a link, rewrite file
                 fp = open(f, "w")
                 fp.write(data)
@@ -108,7 +84,51 @@
         # Turn off all +x bits
         os.chmod(f, s & 0666)
 
-def set_binary(fd):
+def checkexec(path):
+    """
+    Check whether the given path is on a filesystem with UNIX-like exec flags
+
+    Requires a directory (like /foo/.hg)
+    """
+
+    # VFAT on some Linux versions can flip mode but it doesn't persist
+    # a FS remount. Frequently we can detect it if files are created
+    # with exec bit on.
+
+    try:
+        EXECFLAGS = stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH
+        fh, fn = tempfile.mkstemp(dir=path, prefix='hg-checkexec-')
+        try:
+            os.close(fh)
+            m = os.stat(fn).st_mode & 0777
+            new_file_has_exec = m & EXECFLAGS
+            os.chmod(fn, m ^ EXECFLAGS)
+            exec_flags_cannot_flip = ((os.stat(fn).st_mode & 0777) == m)
+        finally:
+            os.unlink(fn)
+    except (IOError, OSError):
+        # we don't care, the user probably won't be able to commit anyway
+        return False
+    return not (new_file_has_exec or exec_flags_cannot_flip)
+
+def checklink(path):
+    """check whether the given path is on a symlink-capable filesystem"""
+    # mktemp is not racy because symlink creation will fail if the
+    # file already exists
+    name = tempfile.mktemp(dir=path, prefix='hg-checklink-')
+    try:
+        os.symlink(".", name)
+        os.unlink(name)
+        return True
+    except (OSError, AttributeError):
+        return False
+
+def checkosfilename(path):
+    '''Check that the base-relative path is a valid filename on this platform.
+    Returns None if the path is ok, or a UI string describing the problem.'''
+    pass # on posix platforms, every path is ok
+
+def setbinary(fd):
     pass
 
 def pconvert(path):
@@ -190,7 +210,7 @@
     except OSError, inst:
         return inst.errno != errno.ESRCH
 
-def explain_exit(code):
+def explainexit(code):
     """return a 2-tuple (desc, code) describing a subprocess status
     (codes from kill are negative - not os.system/wait encoding)"""
     if code >= 0:
@@ -201,7 +221,7 @@
     """Return True if the stat object st is from the current user."""
     return st.st_uid == os.getuid()
 
-def find_exe(command):
+def findexe(command):
     '''Find executable for command searching like which does.
     If command is a basename then PATH is searched for command.
     PATH isn't searched if command is an absolute or relative path.
@@ -224,7 +244,7 @@
             return executable
     return None
 
-def set_signal_handler():
+def setsignalhandler():
     pass
 
 def statfiles(files):
@@ -243,10 +263,6 @@
     '''return name of current user'''
     return getpass.getuser()
 
-def expand_glob(pats):
-    '''On Windows, expand the implicit globs in a list of patterns'''
-    return list(pats)
-
 def username(uid=None):
     """Return the name of the user with the given uid.
 
@@ -296,7 +312,9 @@
                 if not os.isatty(fd):
                     continue
                 arri = fcntl.ioctl(fd, termios.TIOCGWINSZ, '\0' * 8)
-                return array.array('h', arri)[1]
+                width = array.array('h', arri)[1]
+                if width > 0:
+                    return width
             except ValueError:
                 pass
             except IOError, e:
--- a/mercurial/pure/bdiff.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/pure/bdiff.py	Sat Jun 18 17:03:01 2011 -0500
@@ -19,6 +19,7 @@
 
 def _normalizeblocks(a, b, blocks):
     prev = None
+    r = []
     for curr in blocks:
         if prev is None:
             prev = curr
@@ -40,9 +41,10 @@
             while (b1end + shift < b2end and
                    a[a1end + shift] == b[b1end + shift]):
                 shift += 1
-        yield a1, b1, l1 + shift
+        r.append((a1, b1, l1 + shift))
         prev = a2 + shift, b2 + shift, l2 - shift
-    yield prev
+    r.append(prev)
+    return r
 
 def bdiff(a, b):
     a = str(a).splitlines(True)
--- a/mercurial/pure/mpatch.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/pure/mpatch.py	Sat Jun 18 17:03:01 2011 -0500
@@ -56,9 +56,9 @@
 
     def pull(dst, src, l): # pull l bytes from src
         while l:
-            f = src.pop(0)
+            f = src.pop()
             if f[0] > l: # do we need to split?
-                src.insert(0, (f[0] - l, f[1] + l))
+                src.append((f[0] - l, f[1] + l))
                 dst.append((l, f[1]))
                 return
             dst.append(f)
@@ -66,7 +66,7 @@
 
     def collect(buf, list):
         start = buf
-        for l, p in list:
+        for l, p in reversed(list):
             move(buf, p, l)
             buf += l
         return (buf - start, start)
@@ -88,7 +88,7 @@
             new.append((l, pos + 12))        # what got added
             pos += l + 12
             last = p2
-        frags = new + frags                    # what was left at the end
+        frags.extend(reversed(new))                    # what was left at the end
 
     t = collect(b2, frags)
 
--- a/mercurial/pure/osutil.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/pure/osutil.py	Sat Jun 18 17:03:01 2011 -0500
@@ -8,8 +8,6 @@
 import os
 import stat as statmod
 
-posixfile = open
-
 def _mode_to_kind(mode):
     if statmod.S_ISREG(mode):
         return statmod.S_IFREG
@@ -57,3 +55,131 @@
             result.append((fn, _mode_to_kind(st.st_mode)))
     return result
 
+if os.name != 'nt':
+    posixfile = open
+else:
+    import ctypes, ctypes.util
+
+    _kernel32 = ctypes.windll.kernel32
+
+    _DWORD = ctypes.c_ulong
+    _LPCSTR = _LPSTR = ctypes.c_char_p
+    _HANDLE = ctypes.c_void_p
+
+    _INVALID_HANDLE_VALUE = _HANDLE(-1).value
+
+    def _crtname():
+        try:
+            # find_msvcrt was introduced in Python 2.6
+            return ctypes.util.find_msvcrt()
+        except AttributeError:
+            return 'msvcr80.dll' # CPython 2.5
+
+    _crt = ctypes.PyDLL(_crtname())
+
+    # CreateFile 
+    _FILE_SHARE_READ = 0x00000001
+    _FILE_SHARE_WRITE = 0x00000002
+    _FILE_SHARE_DELETE = 0x00000004
+
+    _CREATE_ALWAYS = 2
+    _OPEN_EXISTING = 3
+    _OPEN_ALWAYS = 4
+
+    _GENERIC_READ = 0x80000000
+    _GENERIC_WRITE = 0x40000000
+
+    _FILE_ATTRIBUTE_NORMAL = 0x80
+
+    # _open_osfhandle
+    _O_RDONLY = 0x0000
+    _O_RDWR = 0x0002
+    _O_APPEND = 0x0008
+
+    _O_TEXT = 0x4000
+    _O_BINARY = 0x8000
+
+    # types of parameters of C functions used (required by pypy)
+
+    _kernel32.CreateFileA.argtypes = [_LPCSTR, _DWORD, _DWORD, ctypes.c_void_p,
+        _DWORD, _DWORD, _HANDLE]
+    _kernel32.CreateFileA.restype = _HANDLE
+
+    _crt._open_osfhandle.argtypes = [_HANDLE, ctypes.c_int]
+    _crt._open_osfhandle.restype = ctypes.c_int
+
+    def _raiseioerror(name):
+        err = ctypes.WinError()
+        raise IOError(err.errno, '%s: %s' % (name, err.strerror))
+
+    class posixfile(object):
+        '''a file object aiming for POSIX-like semantics
+
+        CPython's open() returns a file that was opened *without* setting the
+        _FILE_SHARE_DELETE flag, which causes rename and unlink to abort.
+        This even happens if any hardlinked copy of the file is in open state.
+        We set _FILE_SHARE_DELETE here, so files opened with posixfile can be
+        renamed and deleted while they are held open.
+        Note that if a file opened with posixfile is unlinked, the file
+        remains but cannot be opened again or be recreated under the same name,
+        until all reading processes have closed the file.'''
+
+        def __init__(self, name, mode='r', bufsize=-1):
+            if 'b' in mode:
+                flags = _O_BINARY
+            else:
+                flags = _O_TEXT
+
+            m0 = mode[0]
+            if m0 == 'r' and not '+' in mode:
+                flags |= _O_RDONLY
+                access = _GENERIC_READ
+            else:
+                # work around http://support.microsoft.com/kb/899149 and
+                # set _O_RDWR for 'w' and 'a', even if mode has no '+'
+                flags |= _O_RDWR
+                access = _GENERIC_READ | _GENERIC_WRITE
+
+            if m0 == 'r':
+                creation = _OPEN_EXISTING
+            elif m0 == 'w':
+                creation = _CREATE_ALWAYS
+            elif m0 == 'a':
+                creation = _OPEN_ALWAYS
+                flags |= _O_APPEND
+            else:
+                raise ValueError("invalid mode: %s" % mode)
+
+            fh = _kernel32.CreateFileA(name, access,
+                    _FILE_SHARE_READ | _FILE_SHARE_WRITE | _FILE_SHARE_DELETE,
+                    None, creation, _FILE_ATTRIBUTE_NORMAL, None)
+            if fh == _INVALID_HANDLE_VALUE:
+                _raiseioerror(name)
+
+            # for CPython we must use the same CRT as Python uses,
+            # or the os.fdopen call below will abort with
+            #   "OSError: [Errno 9] Bad file descriptor"
+            fd = _crt._open_osfhandle(fh, flags)
+            if fd == -1:
+                _kernel32.CloseHandle(fh)
+                _raiseioerror(name)
+
+            f = os.fdopen(fd, mode, bufsize)
+            # unfortunately, f.name is '<fdopen>' at this point -- so we store
+            # the name on this wrapper. We cannot just assign to f.name,
+            # because that attribute is read-only.
+            object.__setattr__(self, 'name', name)
+            object.__setattr__(self, '_file', f)
+
+        def __iter__(self):
+            return self._file
+
+        def __getattr__(self, name):
+            return getattr(self._file, name)
+
+        def __setattr__(self, name, value):
+            '''mimics the read-only attributes of Python file objects
+            by raising 'TypeError: readonly attribute' if someone tries:
+              f = posixfile('foo.txt')
+              f.name = 'bla'  '''
+            return self._file.__setattr__(name, value)
--- a/mercurial/pure/parsers.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/pure/parsers.py	Sat Jun 18 17:03:01 2011 -0500
@@ -5,7 +5,7 @@
 # This software may be used and distributed according to the terms of the
 # GNU General Public License version 2 or any later version.
 
-from mercurial.node import bin, nullid, nullrev
+from mercurial.node import bin, nullid
 from mercurial import util
 import struct, zlib
 
@@ -56,6 +56,9 @@
             n += 1
             off += s
 
+    if off != len(data):
+        raise ValueError('corrupt index file')
+
     if index:
         e = list(index[0])
         type = gettype(e[0])
--- a/mercurial/repair.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/repair.py	Sat Jun 18 17:03:01 2011 -0500
@@ -6,14 +6,14 @@
 # This software may be used and distributed according to the terms of the
 # GNU General Public License version 2 or any later version.
 
-import changegroup, bookmarks
-from node import nullrev, short
-from i18n import _
+from mercurial import changegroup, bookmarks
+from mercurial.node import short
+from mercurial.i18n import _
 import os
 
-def _bundle(repo, bases, heads, node, suffix, extranodes=None, compress=True):
+def _bundle(repo, bases, heads, node, suffix, compress=True):
     """create a bundle with the specified revisions as a backup"""
-    cg = repo.changegroupsubset(bases, heads, 'strip', extranodes)
+    cg = repo.changegroupsubset(bases, heads, 'strip')
     backupdir = repo.join("strip-backup")
     if not os.path.isdir(backupdir):
         os.mkdir(backupdir)
@@ -33,40 +33,26 @@
 
     return sorted(files)
 
-def _collectextranodes(repo, files, link):
-    """return the nodes that have to be saved before the strip"""
-    def collectone(cl, revlog):
-        extra = []
-        startrev = count = len(revlog)
+def _collectbrokencsets(repo, files, striprev):
+    """return the changesets which will be broken by the truncation"""
+    s = set()
+    def collectone(revlog):
+        links = (revlog.linkrev(i) for i in revlog)
         # find the truncation point of the revlog
-        for i in xrange(count):
-            lrev = revlog.linkrev(i)
-            if lrev >= link:
-                startrev = i + 1
+        for lrev in links:
+            if lrev >= striprev:
                 break
+        # see if any revision after this point has a linkrev
+        # less than striprev (those will be broken by strip)
+        for lrev in links:
+            if lrev < striprev:
+                s.add(lrev)
 
-        # see if any revision after that point has a linkrev less than link
-        # (we have to manually save these guys)
-        for i in xrange(startrev, count):
-            node = revlog.node(i)
-            lrev = revlog.linkrev(i)
-            if lrev < link:
-                extra.append((node, cl.node(lrev)))
-
-        return extra
+    collectone(repo.manifest)
+    for fname in files:
+        collectone(repo.file(fname))
 
-    extranodes = {}
-    cl = repo.changelog
-    extra = collectone(cl, repo.manifest)
-    if extra:
-        extranodes[1] = extra
-    for fname in files:
-        f = repo.file(fname)
-        extra = collectone(cl, f)
-        if extra:
-            extranodes[fname] = extra
-
-    return extranodes
+    return s
 
 def strip(ui, repo, node, backup="all"):
     cl = repo.changelog
@@ -82,28 +68,26 @@
     # the list of heads and bases of the set of interesting revisions.
     # (head = revision in the set that has no descendant in the set;
     #  base = revision in the set that has no ancestor in the set)
-    tostrip = set((striprev,))
-    saveheads = set()
-    savebases = []
+    tostrip = set(cl.descendants(striprev))
+    tostrip.add(striprev)
+
+    files = _collectfiles(repo, striprev)
+    saverevs = _collectbrokencsets(repo, files, striprev)
+
+    # compute heads
+    saveheads = set(saverevs)
     for r in xrange(striprev + 1, len(cl)):
-        parents = cl.parentrevs(r)
-        if parents[0] in tostrip or parents[1] in tostrip:
-            # r is a descendant of striprev
-            tostrip.add(r)
-            # if this is a merge and one of the parents does not descend
-            # from striprev, mark that parent as a savehead.
-            if parents[1] != nullrev:
-                for p in parents:
-                    if p not in tostrip and p > striprev:
-                        saveheads.add(p)
-        else:
-            # if no parents of this revision will be stripped, mark it as
-            # a savebase
-            if parents[0] < striprev and parents[1] < striprev:
-                savebases.append(cl.node(r))
+        if r not in tostrip:
+            saverevs.add(r)
+            saveheads.difference_update(cl.parentrevs(r))
+            saveheads.add(r)
+    saveheads = [cl.node(r) for r in saveheads]
 
-            saveheads.difference_update(parents)
-            saveheads.add(r)
+    # compute base nodes
+    if saverevs:
+        descendants = set(cl.descendants(*saverevs))
+        saverevs.difference_update(descendants)
+    savebases = [cl.node(r) for r in saverevs]
 
     bm = repo._bookmarks
     updatebm = []
@@ -112,20 +96,15 @@
         if rev in tostrip:
             updatebm.append(m)
 
-    saveheads = [cl.node(r) for r in saveheads]
-    files = _collectfiles(repo, striprev)
-
-    extranodes = _collectextranodes(repo, files, striprev)
-
     # create a changegroup for all the branches we need to keep
     backupfile = None
     if backup == "all":
         backupfile = _bundle(repo, [node], cl.heads(), node, 'backup')
         repo.ui.status(_("saved backup bundle to %s\n") % backupfile)
-    if saveheads or extranodes:
+    if saveheads or savebases:
         # do not compress partial bundle if we remove it from disk later
         chgrpfile = _bundle(repo, savebases, saveheads, node, 'temp',
-                            extranodes=extranodes, compress=keeppartialbundle)
+                            compress=keeppartialbundle)
 
     mfst = repo.manifest
 
@@ -149,7 +128,7 @@
             tr.abort()
             raise
 
-        if saveheads or extranodes:
+        if saveheads or savebases:
             ui.note(_("adding branch\n"))
             f = open(chgrpfile, "rb")
             gen = changegroup.readbundle(f, chgrpfile)
--- a/mercurial/revlog.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/revlog.py	Sat Jun 18 17:03:01 2011 -0500
@@ -12,9 +12,9 @@
 """
 
 # import stuff from node for others to import from revlog
-from node import bin, hex, nullid, nullrev, short #@UnusedImport
+from node import bin, hex, nullid, nullrev
 from i18n import _
-import changegroup, ancestor, mdiff, parsers, error, util
+import ancestor, mdiff, parsers, error, util, dagutil
 import struct, zlib, errno
 
 _pack = struct.pack
@@ -27,16 +27,14 @@
 REVLOGV0 = 0
 REVLOGNG = 1
 REVLOGNGINLINEDATA = (1 << 16)
-REVLOGSHALLOW = (1 << 17)
+REVLOGGENERALDELTA = (1 << 17)
 REVLOG_DEFAULT_FLAGS = REVLOGNGINLINEDATA
 REVLOG_DEFAULT_FORMAT = REVLOGNG
 REVLOG_DEFAULT_VERSION = REVLOG_DEFAULT_FORMAT | REVLOG_DEFAULT_FLAGS
-REVLOGNG_FLAGS = REVLOGNGINLINEDATA | REVLOGSHALLOW
+REVLOGNG_FLAGS = REVLOGNGINLINEDATA | REVLOGGENERALDELTA
 
 # revlog index flags
-REVIDX_PARENTDELTA  = 1
-REVIDX_PUNCHED_FLAG = 2
-REVIDX_KNOWN_FLAGS = REVIDX_PUNCHED_FLAG | REVIDX_PARENTDELTA
+REVIDX_KNOWN_FLAGS = 0
 
 # max size of revlog with inline data
 _maxinline = 131072
@@ -209,7 +207,7 @@
     remove data, and can use some simple techniques to avoid the need
     for locking while reading.
     """
-    def __init__(self, opener, indexfile, shallowroot=None):
+    def __init__(self, opener, indexfile):
         """
         create a revlog object
 
@@ -220,39 +218,37 @@
         self.datafile = indexfile[:-2] + ".d"
         self.opener = opener
         self._cache = None
+        self._basecache = (0, 0)
         self._chunkcache = (0, '')
         self.index = []
-        self._shallowroot = shallowroot
-        self._parentdelta = 0
         self._pcache = {}
         self._nodecache = {nullid: nullrev}
         self._nodepos = None
 
         v = REVLOG_DEFAULT_VERSION
-        if hasattr(opener, 'options') and 'defversion' in opener.options:
-            v = opener.options['defversion']
-            if v & REVLOGNG:
-                v |= REVLOGNGINLINEDATA
-            if v & REVLOGNG and 'parentdelta' in opener.options:
-                self._parentdelta = 1
-
-        if shallowroot:
-            v |= REVLOGSHALLOW
+        if hasattr(opener, 'options'):
+            if 'revlogv1' in opener.options:
+                if 'generaldelta' in opener.options:
+                    v |= REVLOGGENERALDELTA
+            else:
+                v = 0
 
         i = ''
+        self._initempty = True
         try:
             f = self.opener(self.indexfile)
             i = f.read()
             f.close()
             if len(i) > 0:
                 v = struct.unpack(versionformat, i[:4])[0]
+                self._initempty = False
         except IOError, inst:
             if inst.errno != errno.ENOENT:
                 raise
 
         self.version = v
         self._inline = v & REVLOGNGINLINEDATA
-        self._shallow = v & REVLOGSHALLOW
+        self._generaldelta = v & REVLOGGENERALDELTA
         flags = v & ~0xFFFF
         fmt = v & 0xFFFF
         if fmt == REVLOGV0 and flags:
@@ -288,7 +284,7 @@
 
     @util.propertycache
     def nodemap(self):
-        n = self.rev(self.node(0))
+        self.rev(self.node(0))
         return self._nodecache
 
     def rev(self, node):
@@ -324,8 +320,13 @@
         return self.start(rev) + self.length(rev)
     def length(self, rev):
         return self.index[rev][1]
-    def base(self, rev):
-        return self.index[rev][3]
+    def chainbase(self, rev):
+        index = self.index
+        base = index[rev][3]
+        while base != rev:
+            rev = base
+            base = index[rev][3]
+        return base
     def flags(self, rev):
         return self.index[rev][0] & 0xFFFF
     def rawsize(self, rev):
@@ -399,11 +400,12 @@
                     yield i
                     break
 
-    def findmissing(self, common=None, heads=None):
-        """Return the ancestors of heads that are not ancestors of common.
+    def findcommonmissing(self, common=None, heads=None):
+        """Return a tuple of the ancestors of common and the ancestors of heads
+        that are not ancestors of common.
 
-        More specifically, return a list of nodes N such that every N
-        satisfies the following constraints:
+        More specifically, the second element is a list of nodes N such that
+        every N satisfies the following constraints:
 
           1. N is an ancestor of some node in 'heads'
           2. N is not an ancestor of any node in 'common'
@@ -441,7 +443,25 @@
                         visit.append(p)
         missing = list(missing)
         missing.sort()
-        return [self.node(r) for r in missing]
+        return has, [self.node(r) for r in missing]
+
+    def findmissing(self, common=None, heads=None):
+        """Return the ancestors of heads that are not ancestors of common.
+
+        More specifically, return a list of nodes N such that every N
+        satisfies the following constraints:
+
+          1. N is an ancestor of some node in 'heads'
+          2. N is not an ancestor of any node in 'common'
+
+        The list is sorted by revision number, meaning it is
+        topologically sorted.
+
+        'heads' and 'common' are both lists of node IDs.  If heads is
+        not supplied, uses all of the revlog's heads.  If common is not
+        supplied, uses nullid."""
+        _common, missing = self.findcommonmissing(common, heads)
+        return missing
 
     def nodesbetween(self, roots=None, heads=None):
         """Return a topological path from 'roots' to 'heads'.
@@ -471,7 +491,7 @@
                 return nonodes
             lowestrev = min([self.rev(n) for n in roots])
         else:
-            roots = [nullid] # Everybody's a descendent of nullid
+            roots = [nullid] # Everybody's a descendant of nullid
             lowestrev = nullrev
         if (lowestrev == nullrev) and (heads is None):
             # We want _all_ the nodes!
@@ -492,7 +512,7 @@
             # Turn heads into a dictionary so we can remove 'fake' heads.
             # Also, later we will be using it to filter out the heads we can't
             # find from roots.
-            heads = dict.fromkeys(heads, 0)
+            heads = dict.fromkeys(heads, False)
             # Start at the top and keep marking parents until we're done.
             nodestotag = set(heads)
             # Remember where the top was so we can use it as a limit later.
@@ -508,7 +528,7 @@
                 r = self.rev(n)
                 if r >= lowestrev:
                     if n not in ancestors:
-                        # If we are possibly a descendent of one of the roots
+                        # If we are possibly a descendant of one of the roots
                         # and we haven't already been marked as an ancestor
                         ancestors.add(n) # Mark as ancestor
                         # Add non-nullid parents to list of nodes to tag.
@@ -542,62 +562,73 @@
                 lowestrev = nullrev
                 roots = [nullid]
         # Transform our roots list into a set.
-        descendents = set(roots)
+        descendants = set(roots)
         # Also, keep the original roots so we can filter out roots that aren't
         # 'real' roots (i.e. are descended from other roots).
-        roots = descendents.copy()
+        roots = descendants.copy()
         # Our topologically sorted list of output nodes.
         orderedout = []
         # Don't start at nullid since we don't want nullid in our output list,
         # and if nullid shows up in descedents, empty parents will look like
-        # they're descendents.
+        # they're descendants.
         for r in xrange(max(lowestrev, 0), highestrev + 1):
             n = self.node(r)
-            isdescendent = False
-            if lowestrev == nullrev:  # Everybody is a descendent of nullid
-                isdescendent = True
-            elif n in descendents:
-                # n is already a descendent
-                isdescendent = True
+            isdescendant = False
+            if lowestrev == nullrev:  # Everybody is a descendant of nullid
+                isdescendant = True
+            elif n in descendants:
+                # n is already a descendant
+                isdescendant = True
                 # This check only needs to be done here because all the roots
-                # will start being marked is descendents before the loop.
+                # will start being marked is descendants before the loop.
                 if n in roots:
                     # If n was a root, check if it's a 'real' root.
                     p = tuple(self.parents(n))
-                    # If any of its parents are descendents, it's not a root.
-                    if (p[0] in descendents) or (p[1] in descendents):
+                    # If any of its parents are descendants, it's not a root.
+                    if (p[0] in descendants) or (p[1] in descendants):
                         roots.remove(n)
             else:
                 p = tuple(self.parents(n))
-                # A node is a descendent if either of its parents are
-                # descendents.  (We seeded the dependents list with the roots
+                # A node is a descendant if either of its parents are
+                # descendants.  (We seeded the dependents list with the roots
                 # up there, remember?)
-                if (p[0] in descendents) or (p[1] in descendents):
-                    descendents.add(n)
-                    isdescendent = True
-            if isdescendent and ((ancestors is None) or (n in ancestors)):
-                # Only include nodes that are both descendents and ancestors.
+                if (p[0] in descendants) or (p[1] in descendants):
+                    descendants.add(n)
+                    isdescendant = True
+            if isdescendant and ((ancestors is None) or (n in ancestors)):
+                # Only include nodes that are both descendants and ancestors.
                 orderedout.append(n)
                 if (ancestors is not None) and (n in heads):
                     # We're trying to figure out which heads are reachable
                     # from roots.
                     # Mark this head as having been reached
-                    heads[n] = 1
+                    heads[n] = True
                 elif ancestors is None:
                     # Otherwise, we're trying to discover the heads.
                     # Assume this is a head because if it isn't, the next step
                     # will eventually remove it.
-                    heads[n] = 1
+                    heads[n] = True
                     # But, obviously its parents aren't.
                     for p in self.parents(n):
                         heads.pop(p, None)
-        heads = [n for n in heads.iterkeys() if heads[n] != 0]
+        heads = [n for n, flag in heads.iteritems() if flag]
         roots = list(roots)
         assert orderedout
         assert roots
         assert heads
         return (orderedout, roots, heads)
 
+    def headrevs(self):
+        count = len(self)
+        if not count:
+            return [nullrev]
+        ishead = [1] * (count + 1)
+        index = self.index
+        for r in xrange(count):
+            e = index[r]
+            ishead[e[5]] = ishead[e[6]] = 0
+        return [r for r in xrange(count) if ishead[r]]
+
     def heads(self, start=None, stop=None):
         """return the list of all nodes that have no children
 
@@ -607,15 +638,9 @@
         as if they had no children
         """
         if start is None and stop is None:
-            count = len(self)
-            if not count:
+            if not len(self):
                 return [nullid]
-            ishead = [1] * (count + 1)
-            index = self.index
-            for r in xrange(count):
-                e = index[r]
-                ishead[e[5]] = ishead[e[6]] = 0
-            return [self.node(r) for r in xrange(count) if ishead[r]]
+            return [self.node(r) for r in self.headrevs()]
 
         if start is None:
             start = nullid
@@ -803,19 +828,25 @@
     def _chunk(self, rev):
         return decompress(self._chunkraw(rev, rev))
 
+    def _chunkbase(self, rev):
+        return self._chunk(rev)
+
     def _chunkclear(self):
         self._chunkcache = (0, '')
 
     def deltaparent(self, rev):
-        """return previous revision or parentrev according to flags"""
-        if self.flags(rev) & REVIDX_PARENTDELTA:
-            return self.parentrevs(rev)[0]
+        """return deltaparent of the given revision"""
+        base = self.index[rev][3]
+        if base == rev:
+            return nullrev
+        elif self._generaldelta:
+            return base
         else:
             return rev - 1
 
     def revdiff(self, rev1, rev2):
         """return or calculate a delta between two revisions"""
-        if self.base(rev2) != rev2 and self.deltaparent(rev2) == rev1:
+        if rev1 != nullrev and self.deltaparent(rev2) == rev1:
             return self._chunk(rev2)
 
         return mdiff.textdiff(self.revision(self.node(rev1)),
@@ -834,7 +865,6 @@
         # look up what we need to read
         text = None
         rev = self.rev(node)
-        base = self.base(rev)
 
         # check rev flags
         if self.flags(rev) & ~REVIDX_KNOWN_FLAGS:
@@ -844,12 +874,13 @@
         # build delta chain
         chain = []
         index = self.index # for performance
+        generaldelta = self._generaldelta
         iterrev = rev
         e = index[iterrev]
-        while iterrev != base and iterrev != cachedrev:
+        while iterrev != e[3] and iterrev != cachedrev:
             chain.append(iterrev)
-            if e[0] & REVIDX_PARENTDELTA:
-                iterrev = e[5]
+            if generaldelta:
+                iterrev = e[3]
             else:
                 iterrev -= 1
             e = index[iterrev]
@@ -865,7 +896,7 @@
 
         self._chunkraw(base, rev)
         if text is None:
-            text = self._chunk(base)
+            text = self._chunkbase(base)
 
         bins = [self._chunk(r) for r in chain]
         text = mdiff.patches(text, bins)
@@ -877,8 +908,7 @@
 
     def _checkhash(self, text, node, rev):
         p1, p2 = self.parents(node)
-        if (node != hash(text, p1, p2) and
-            not (self.flags(rev) & REVIDX_PUNCHED_FLAG)):
+        if node != hash(text, p1, p2):
             raise RevlogError(_("integrity check failed on %s:%d")
                               % (self.indexfile, rev))
         return text
@@ -932,8 +962,7 @@
         cachedelta - an optional precomputed delta
         """
         node = hash(text, p1, p2)
-        if (node in self.nodemap and
-            (not self.flags(self.rev(node)) & REVIDX_PUNCHED_FLAG)):
+        if node in self.nodemap:
             return node
 
         dfh = None
@@ -950,7 +979,13 @@
 
     def _addrevision(self, node, text, transaction, link, p1, p2,
                      cachedelta, ifh, dfh):
+        """internal function to add revisions to the log
 
+        see addrevision for argument descriptions.
+        invariants:
+        - text is optional (can be None); if not set, cachedelta must be set.
+          if both are set, they must correspond to eachother.
+        """
         btext = [text]
         def buildtext():
             if btext[0] is not None:
@@ -976,42 +1011,51 @@
                 delta = mdiff.textdiff(ptext, t)
             data = compress(delta)
             l = len(data[1]) + len(data[0])
-            base = self.base(rev)
-            dist = l + offset - self.start(base)
-            return dist, l, data, base
+            if basecache[0] == rev:
+                chainbase = basecache[1]
+            else:
+                chainbase = self.chainbase(rev)
+            dist = l + offset - self.start(chainbase)
+            if self._generaldelta:
+                base = rev
+            else:
+                base = chainbase
+            return dist, l, data, base, chainbase
 
         curr = len(self)
         prev = curr - 1
-        base = curr
+        base = chainbase = curr
         offset = self.end(prev)
         flags = 0
         d = None
+        basecache = self._basecache
         p1r, p2r = self.rev(p1), self.rev(p2)
 
         # should we try to build a delta?
         if prev != nullrev:
-            d = builddelta(prev)
-            if self._parentdelta and prev != p1r:
-                d2 = builddelta(p1r)
-                if d2 < d:
-                    d = d2
-                    flags = REVIDX_PARENTDELTA
-            dist, l, data, base = d
+            if self._generaldelta:
+                if p1r >= basecache[1]:
+                    d = builddelta(p1r)
+                elif p2r >= basecache[1]:
+                    d = builddelta(p2r)
+                else:
+                    d = builddelta(prev)
+            else:
+                d = builddelta(prev)
+            dist, l, data, base, chainbase = d
 
         # full versions are inserted when the needed deltas
         # become comparable to the uncompressed text
-        # or the base revision is punched
         if text is None:
             textlen = mdiff.patchedsize(self.rawsize(cachedelta[0]),
                                         cachedelta[1])
         else:
             textlen = len(text)
-        if (d is None or dist > textlen * 2 or
-            (self.flags(base) & REVIDX_PUNCHED_FLAG)):
+        if d is None or dist > textlen * 2:
             text = buildtext()
             data = compress(text)
             l = len(data[1]) + len(data[0])
-            base = curr
+            base = chainbase = curr
 
         e = (offset_type(offset, flags), l, textlen,
              base, link, p1r, p2r, node)
@@ -1037,9 +1081,10 @@
 
         if type(text) == str: # only accept immutable objects
             self._cache = (node, curr, text)
+        self._basecache = (curr, chainbase)
         return node
 
-    def group(self, nodelist, lookup, infocollect=None, fullrev=False):
+    def group(self, nodelist, bundler, reorder=None):
         """Calculate a delta group, yielding a sequence of changegroup chunks
         (strings).
 
@@ -1049,45 +1094,33 @@
         guaranteed to have this parent as it has all history before
         these changesets. In the case firstparent is nullrev the
         changegroup starts with a full revision.
-        fullrev forces the insertion of the full revision, necessary
-        in the case of shallow clones where the first parent might
-        not exist at the reciever.
         """
 
-        revs = [self.rev(n) for n in nodelist]
+        # if we don't have any revisions touched by these changesets, bail
+        if len(nodelist) == 0:
+            yield bundler.close()
+            return
 
-        # if we don't have any revisions touched by these changesets, bail
-        if not revs:
-            yield changegroup.closechunk()
-            return
+        # for generaldelta revlogs, we linearize the revs; this will both be
+        # much quicker and generate a much smaller bundle
+        if (self._generaldelta and reorder is not False) or reorder:
+            dag = dagutil.revlogdag(self)
+            revs = set(self.rev(n) for n in nodelist)
+            revs = dag.linearize(revs)
+        else:
+            revs = sorted([self.rev(n) for n in nodelist])
 
         # add the parent of the first rev
         p = self.parentrevs(revs[0])[0]
         revs.insert(0, p)
-        if p == nullrev:
-            fullrev = True
 
         # build deltas
-        for d in xrange(len(revs) - 1):
-            a, b = revs[d], revs[d + 1]
-            nb = self.node(b)
-
-            if infocollect is not None:
-                infocollect(nb)
+        for r in xrange(len(revs) - 1):
+            prev, curr = revs[r], revs[r + 1]
+            for c in bundler.revchunk(self, curr, prev):
+                yield c
 
-            p = self.parents(nb)
-            meta = nb + p[0] + p[1] + lookup(nb)
-            if fullrev:
-                d = self.revision(nb)
-                meta += mdiff.trivialdiffheader(len(d))
-                fullrev = False
-            else:
-                d = self.revdiff(a, b)
-            yield changegroup.chunkheader(len(meta) + len(d))
-            yield meta
-            yield d
-
-        yield changegroup.closechunk()
+        yield bundler.close()
 
     def addgroup(self, bundle, linkmapper, transaction):
         """
@@ -1118,53 +1151,35 @@
         try:
             # loop through our set of deltas
             chain = None
-            while 1:
-                chunkdata = bundle.parsechunk()
+            while True:
+                chunkdata = bundle.deltachunk(chain)
                 if not chunkdata:
                     break
                 node = chunkdata['node']
                 p1 = chunkdata['p1']
                 p2 = chunkdata['p2']
                 cs = chunkdata['cs']
-                delta = chunkdata['data']
+                deltabase = chunkdata['deltabase']
+                delta = chunkdata['delta']
 
                 link = linkmapper(cs)
-                if (node in self.nodemap and
-                    (not self.flags(self.rev(node)) & REVIDX_PUNCHED_FLAG)):
+                if node in self.nodemap:
                     # this can happen if two branches make the same change
                     chain = node
                     continue
 
                 for p in (p1, p2):
                     if not p in self.nodemap:
-                        if self._shallow:
-                            # add null entries for missing parents
-                            # XXX FIXME
-                            #if base == nullrev:
-                            #    base = len(self)
-                            #e = (offset_type(end, REVIDX_PUNCHED_FLAG),
-                            #     0, 0, base, nullrev, nullrev, nullrev, p)
-                            #self.index.insert(-1, e)
-                            #self.nodemap[p] = r
-                            #entry = self._io.packentry(e, self.node,
-                            #                           self.version, r)
-                            #ifh.write(entry)
-                            #t, r = r, r + 1
-                            raise LookupError(p, self.indexfile,
-                                              _('unknown parent'))
-                        else:
-                            raise LookupError(p, self.indexfile,
-                                              _('unknown parent'))
+                        raise LookupError(p, self.indexfile,
+                                          _('unknown parent'))
 
-                if not chain:
-                    # retrieve the parent revision of the delta chain
-                    chain = p1
-                    if not chain in self.nodemap:
-                        raise LookupError(chain, self.indexfile, _('unknown base'))
+                if deltabase not in self.nodemap:
+                    raise LookupError(deltabase, self.indexfile,
+                                      _('unknown delta base'))
 
-                chainrev = self.rev(chain)
+                baserev = self.rev(deltabase)
                 chain = self._addrevision(node, None, transaction, link,
-                                          p1, p2, (chainrev, delta), ifh, dfh)
+                                          p1, p2, (baserev, delta), ifh, dfh)
                 if not dfh and not self._inline:
                     # addrevision switched from inline to conventional
                     # reopen the index
--- a/mercurial/revset.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/revset.py	Sat Jun 18 17:03:01 2011 -0500
@@ -6,13 +6,15 @@
 # GNU General Public License version 2 or any later version.
 
 import re
-import parser, util, error, discovery
+import parser, util, error, discovery, hbisect
 import bookmarks as bookmarksmod
 import match as matchmod
-from i18n import _, gettext
+from i18n import _
 
 elements = {
     "(": (20, ("group", 1, ")"), ("func", 1, ")")),
+    "~": (18, None, ("ancestor", 18)),
+    "^": (18, None, ("parent", 18), ("parentpost", 18)),
     "-": (5, ("negate", 19), ("minus", 5)),
     "::": (17, ("dagrangepre", 17), ("dagrange", 17),
            ("dagrangepost", 17)),
@@ -47,7 +49,7 @@
         elif c == '.' and program[pos:pos + 2] == '..': # look ahead carefully
             yield ('..', None, pos)
             pos += 1 # skip ahead
-        elif c in "():,-|&+!": # handle simple operators
+        elif c in "():,-|&+!~^": # handle simple operators
             yield (c, None, pos)
         elif (c in '"\'' or c == 'r' and
               program[pos:pos + 2] in ("r'", 'r"')): # handle quoted strings
@@ -123,7 +125,7 @@
     x = repo[x].rev()
     if x == -1 and len(subset) == len(repo):
         return [-1]
-    if x in subset:
+    if len(subset) == len(repo) or x in subset:
         return [x]
     return []
 
@@ -156,9 +158,10 @@
     return getset(repo, getset(repo, subset, x), y)
 
 def orset(repo, subset, x, y):
-    s = set(getset(repo, subset, x))
-    s |= set(getset(repo, [r for r in subset if r not in s], y))
-    return [r for r in subset if r in s]
+    xl = getset(repo, subset, x)
+    s = set(xl)
+    yl = getset(repo, [r for r in subset if r not in s], y)
+    return xl + yl
 
 def notset(repo, subset, x):
     s = set(getset(repo, subset, x))
@@ -174,6 +177,412 @@
 
 # functions
 
+def adds(repo, subset, x):
+    """``adds(pattern)``
+    Changesets that add a file matching pattern.
+    """
+    # i18n: "adds" is a keyword
+    pat = getstring(x, _("adds requires a pattern"))
+    return checkstatus(repo, subset, pat, 1)
+
+def ancestor(repo, subset, x):
+    """``ancestor(single, single)``
+    Greatest common ancestor of the two changesets.
+    """
+    # i18n: "ancestor" is a keyword
+    l = getargs(x, 2, 2, _("ancestor requires two arguments"))
+    r = range(len(repo))
+    a = getset(repo, r, l[0])
+    b = getset(repo, r, l[1])
+    if len(a) != 1 or len(b) != 1:
+        # i18n: "ancestor" is a keyword
+        raise error.ParseError(_("ancestor arguments must be single revisions"))
+    an = [repo[a[0]].ancestor(repo[b[0]]).rev()]
+
+    return [r for r in an if r in subset]
+
+def ancestors(repo, subset, x):
+    """``ancestors(set)``
+    Changesets that are ancestors of a changeset in set.
+    """
+    args = getset(repo, range(len(repo)), x)
+    if not args:
+        return []
+    s = set(repo.changelog.ancestors(*args)) | set(args)
+    return [r for r in subset if r in s]
+
+def ancestorspec(repo, subset, x, n):
+    """``set~n``
+    Changesets that are the Nth ancestor (first parents only) of a changeset in set.
+    """
+    try:
+        n = int(n[1])
+    except ValueError:
+        raise error.ParseError(_("~ expects a number"))
+    ps = set()
+    cl = repo.changelog
+    for r in getset(repo, subset, x):
+        for i in range(n):
+            r = cl.parentrevs(r)[0]
+        ps.add(r)
+    return [r for r in subset if r in ps]
+
+def author(repo, subset, x):
+    """``author(string)``
+    Alias for ``user(string)``.
+    """
+    # i18n: "author" is a keyword
+    n = getstring(x, _("author requires a string")).lower()
+    return [r for r in subset if n in repo[r].user().lower()]
+
+def bisected(repo, subset, x):
+    """``bisected(string)``
+    Changesets marked in the specified bisect state (good, bad, skip).
+    """
+    state = getstring(x, _("bisect requires a string")).lower()
+    if state not in ('good', 'bad', 'skip', 'unknown'):
+        raise error.ParseError(_('invalid bisect state'))
+    marked = set(repo.changelog.rev(n) for n in hbisect.load_state(repo)[state])
+    return [r for r in subset if r in marked]
+
+def bookmark(repo, subset, x):
+    """``bookmark([name])``
+    The named bookmark or all bookmarks.
+    """
+    # i18n: "bookmark" is a keyword
+    args = getargs(x, 0, 1, _('bookmark takes one or no arguments'))
+    if args:
+        bm = getstring(args[0],
+                       # i18n: "bookmark" is a keyword
+                       _('the argument to bookmark must be a string'))
+        bmrev = bookmarksmod.listbookmarks(repo).get(bm, None)
+        if not bmrev:
+            raise util.Abort(_("bookmark '%s' does not exist") % bm)
+        bmrev = repo[bmrev].rev()
+        return [r for r in subset if r == bmrev]
+    bms = set([repo[r].rev()
+               for r in bookmarksmod.listbookmarks(repo).values()])
+    return [r for r in subset if r in bms]
+
+def branch(repo, subset, x):
+    """``branch(string or set)``
+    All changesets belonging to the given branch or the branches of the given
+    changesets.
+    """
+    try:
+        b = getstring(x, '')
+        if b in repo.branchmap():
+            return [r for r in subset if repo[r].branch() == b]
+    except error.ParseError:
+        # not a string, but another revspec, e.g. tip()
+        pass
+
+    s = getset(repo, range(len(repo)), x)
+    b = set()
+    for r in s:
+        b.add(repo[r].branch())
+    s = set(s)
+    return [r for r in subset if r in s or repo[r].branch() in b]
+
+def checkstatus(repo, subset, pat, field):
+    m = matchmod.match(repo.root, repo.getcwd(), [pat])
+    s = []
+    fast = (m.files() == [pat])
+    for r in subset:
+        c = repo[r]
+        if fast:
+            if pat not in c.files():
+                continue
+        else:
+            for f in c.files():
+                if m(f):
+                    break
+            else:
+                continue
+        files = repo.status(c.p1().node(), c.node())[field]
+        if fast:
+            if pat in files:
+                s.append(r)
+        else:
+            for f in files:
+                if m(f):
+                    s.append(r)
+                    break
+    return s
+
+def children(repo, subset, x):
+    """``children(set)``
+    Child changesets of changesets in set.
+    """
+    cs = set()
+    cl = repo.changelog
+    s = set(getset(repo, range(len(repo)), x))
+    for r in xrange(0, len(repo)):
+        for p in cl.parentrevs(r):
+            if p in s:
+                cs.add(r)
+    return [r for r in subset if r in cs]
+
+def closed(repo, subset, x):
+    """``closed()``
+    Changeset is closed.
+    """
+    # i18n: "closed" is a keyword
+    getargs(x, 0, 0, _("closed takes no arguments"))
+    return [r for r in subset if repo[r].extra().get('close')]
+
+def contains(repo, subset, x):
+    """``contains(pattern)``
+    Revision contains a file matching pattern. See :hg:`help patterns`
+    for information about file patterns.
+    """
+    # i18n: "contains" is a keyword
+    pat = getstring(x, _("contains requires a pattern"))
+    m = matchmod.match(repo.root, repo.getcwd(), [pat])
+    s = []
+    if m.files() == [pat]:
+        for r in subset:
+            if pat in repo[r]:
+                s.append(r)
+    else:
+        for r in subset:
+            for f in repo[r].manifest():
+                if m(f):
+                    s.append(r)
+                    break
+    return s
+
+def date(repo, subset, x):
+    """``date(interval)``
+    Changesets within the interval, see :hg:`help dates`.
+    """
+    # i18n: "date" is a keyword
+    ds = getstring(x, _("date requires a string"))
+    dm = util.matchdate(ds)
+    return [r for r in subset if dm(repo[r].date()[0])]
+
+def desc(repo, subset, x):
+    """``desc(string)``
+    Search commit message for string. The match is case-insensitive.
+    """
+    # i18n: "desc" is a keyword
+    ds = getstring(x, _("desc requires a string")).lower()
+    l = []
+    for r in subset:
+        c = repo[r]
+        if ds in c.description().lower():
+            l.append(r)
+    return l
+
+def descendants(repo, subset, x):
+    """``descendants(set)``
+    Changesets which are descendants of changesets in set.
+    """
+    args = getset(repo, range(len(repo)), x)
+    if not args:
+        return []
+    s = set(repo.changelog.descendants(*args)) | set(args)
+    return [r for r in subset if r in s]
+
+def filelog(repo, subset, x):
+    """``filelog(pattern)``
+    Changesets connected to the specified filelog.
+    """
+
+    pat = getstring(x, _("filelog requires a pattern"))
+    m = matchmod.match(repo.root, repo.getcwd(), [pat], default='relpath')
+    s = set()
+
+    if not m.anypats():
+        for f in m.files():
+            fl = repo.file(f)
+            for fr in fl:
+                s.add(fl.linkrev(fr))
+    else:
+        for f in repo[None]:
+            if m(f):
+                fl = repo.file(f)
+                for fr in fl:
+                    s.add(fl.linkrev(fr))
+
+    return [r for r in subset if r in s]
+
+def follow(repo, subset, x):
+    """``follow([file])``
+    An alias for ``::.`` (ancestors of the working copy's first parent).
+    If a filename is specified, the history of the given file is followed,
+    including copies.
+    """
+    # i18n: "follow" is a keyword
+    l = getargs(x, 0, 1, _("follow takes no arguments or a filename"))
+    p = repo['.'].rev()
+    if l:
+        x = getstring(l[0], "follow expected a filename")
+        s = set(ctx.rev() for ctx in repo['.'][x].ancestors())
+    else:
+        s = set(repo.changelog.ancestors(p))
+
+    s |= set([p])
+    return [r for r in subset if r in s]
+
+def followfile(repo, subset, f):
+    """``follow()``
+    An alias for ``::.`` (ancestors of the working copy's first parent).
+    """
+    # i18n: "follow" is a keyword
+    getargs(x, 0, 0, _("follow takes no arguments"))
+    p = repo['.'].rev()
+    s = set(repo.changelog.ancestors(p)) | set([p])
+    return [r for r in subset if r in s]
+
+def getall(repo, subset, x):
+    """``all()``
+    All changesets, the same as ``0:tip``.
+    """
+    # i18n: "all" is a keyword
+    getargs(x, 0, 0, _("all takes no arguments"))
+    return subset
+
+def grep(repo, subset, x):
+    """``grep(regex)``
+    Like ``keyword(string)`` but accepts a regex. Use ``grep(r'...')``
+    to ensure special escape characters are handled correctly. Unlike
+    ``keyword(string)``, the match is case-sensitive.
+    """
+    try:
+        # i18n: "grep" is a keyword
+        gr = re.compile(getstring(x, _("grep requires a string")))
+    except re.error, e:
+        raise error.ParseError(_('invalid match pattern: %s') % e)
+    l = []
+    for r in subset:
+        c = repo[r]
+        for e in c.files() + [c.user(), c.description()]:
+            if gr.search(e):
+                l.append(r)
+                break
+    return l
+
+def hasfile(repo, subset, x):
+    """``file(pattern)``
+    Changesets affecting files matched by pattern.
+    """
+    # i18n: "file" is a keyword
+    pat = getstring(x, _("file requires a pattern"))
+    m = matchmod.match(repo.root, repo.getcwd(), [pat])
+    s = []
+    for r in subset:
+        for f in repo[r].files():
+            if m(f):
+                s.append(r)
+                break
+    return s
+
+def head(repo, subset, x):
+    """``head()``
+    Changeset is a named branch head.
+    """
+    # i18n: "head" is a keyword
+    getargs(x, 0, 0, _("head takes no arguments"))
+    hs = set()
+    for b, ls in repo.branchmap().iteritems():
+        hs.update(repo[h].rev() for h in ls)
+    return [r for r in subset if r in hs]
+
+def heads(repo, subset, x):
+    """``heads(set)``
+    Members of set with no children in set.
+    """
+    s = getset(repo, subset, x)
+    ps = set(parents(repo, subset, x))
+    return [r for r in s if r not in ps]
+
+def keyword(repo, subset, x):
+    """``keyword(string)``
+    Search commit message, user name, and names of changed files for
+    string. The match is case-insensitive.
+    """
+    # i18n: "keyword" is a keyword
+    kw = getstring(x, _("keyword requires a string")).lower()
+    l = []
+    for r in subset:
+        c = repo[r]
+        t = " ".join(c.files() + [c.user(), c.description()])
+        if kw in t.lower():
+            l.append(r)
+    return l
+
+def limit(repo, subset, x):
+    """``limit(set, n)``
+    First n members of set.
+    """
+    # i18n: "limit" is a keyword
+    l = getargs(x, 2, 2, _("limit requires two arguments"))
+    try:
+        # i18n: "limit" is a keyword
+        lim = int(getstring(l[1], _("limit requires a number")))
+    except ValueError:
+        # i18n: "limit" is a keyword
+        raise error.ParseError(_("limit expects a number"))
+    ss = set(subset)
+    os = getset(repo, range(len(repo)), l[0])[:lim]
+    return [r for r in os if r in ss]
+
+def last(repo, subset, x):
+    """``last(set, n)``
+    Last n members of set.
+    """
+    # i18n: "last" is a keyword
+    l = getargs(x, 2, 2, _("last requires two arguments"))
+    try:
+        # i18n: "last" is a keyword
+        lim = int(getstring(l[1], _("last requires a number")))
+    except ValueError:
+        # i18n: "last" is a keyword
+        raise error.ParseError(_("last expects a number"))
+    ss = set(subset)
+    os = getset(repo, range(len(repo)), l[0])[-lim:]
+    return [r for r in os if r in ss]
+
+def maxrev(repo, subset, x):
+    """``max(set)``
+    Changeset with highest revision number in set.
+    """
+    os = getset(repo, range(len(repo)), x)
+    if os:
+        m = max(os)
+        if m in subset:
+            return [m]
+    return []
+
+def merge(repo, subset, x):
+    """``merge()``
+    Changeset is a merge changeset.
+    """
+    # i18n: "merge" is a keyword
+    getargs(x, 0, 0, _("merge takes no arguments"))
+    cl = repo.changelog
+    return [r for r in subset if cl.parentrevs(r)[1] != -1]
+
+def minrev(repo, subset, x):
+    """``min(set)``
+    Changeset with lowest revision number in set.
+    """
+    os = getset(repo, range(len(repo)), x)
+    if os:
+        m = min(os)
+        if m in subset:
+            return [m]
+    return []
+
+def modifies(repo, subset, x):
+    """``modifies(pattern)``
+    Changesets modifying files matched by pattern.
+    """
+    # i18n: "modifies" is a keyword
+    pat = getstring(x, _("modifies requires a pattern"))
+    return checkstatus(repo, subset, pat, 0)
+
 def node(repo, subset, x):
     """``id(string)``
     Revision non-ambiguously specified by the given hex string prefix.
@@ -188,26 +597,35 @@
         rn = repo.changelog.rev(repo.changelog._partialmatch(n))
     return [r for r in subset if r == rn]
 
-def rev(repo, subset, x):
-    """``rev(number)``
-    Revision with the given numeric identifier.
+def outgoing(repo, subset, x):
+    """``outgoing([path])``
+    Changesets not found in the specified destination repository, or the
+    default push location.
     """
-    # i18n: "rev" is a keyword
-    l = getargs(x, 1, 1, _("rev requires one argument"))
-    try:
-        # i18n: "rev" is a keyword
-        l = int(getstring(l[0], _("rev requires a number")))
-    except ValueError:
-        # i18n: "rev" is a keyword
-        raise error.ParseError(_("rev expects a number"))
-    return [r for r in subset if r == l]
+    import hg # avoid start-up nasties
+    # i18n: "outgoing" is a keyword
+    l = getargs(x, 0, 1, _("outgoing requires a repository path"))
+    # i18n: "outgoing" is a keyword
+    dest = l and getstring(l[0], _("outgoing requires a repository path")) or ''
+    dest = repo.ui.expandpath(dest or 'default-push', dest or 'default')
+    dest, branches = hg.parseurl(dest)
+    revs, checkout = hg.addbranchrevs(repo, repo, branches, [])
+    if revs:
+        revs = [repo.lookup(rev) for rev in revs]
+    other = hg.peer(repo, {}, dest)
+    repo.ui.pushbuffer()
+    common, outheads = discovery.findcommonoutgoing(repo, other, onlyheads=revs)
+    repo.ui.popbuffer()
+    cl = repo.changelog
+    o = set([cl.rev(r) for r in repo.changelog.findmissing(common, outheads)])
+    return [r for r in subset if r in o]
 
 def p1(repo, subset, x):
     """``p1([set])``
     First parent of changesets in set, or the working directory.
     """
     if x is None:
-        p = repo[x].parents()[0].rev()
+        p = repo[x].p1().rev()
         return [r for r in subset if r == p]
 
     ps = set()
@@ -248,293 +666,30 @@
         ps.update(cl.parentrevs(r))
     return [r for r in subset if r in ps]
 
-def maxrev(repo, subset, x):
-    """``max(set)``
-    Changeset with highest revision number in set.
-    """
-    s = getset(repo, subset, x)
-    if s:
-        m = max(s)
-        if m in subset:
-            return [m]
-    return []
-
-def minrev(repo, subset, x):
-    """``min(set)``
-    Changeset with lowest revision number in set.
-    """
-    s = getset(repo, subset, x)
-    if s:
-        m = min(s)
-        if m in subset:
-            return [m]
-    return []
-
-def limit(repo, subset, x):
-    """``limit(set, n)``
-    First n members of set.
-    """
-    # i18n: "limit" is a keyword
-    l = getargs(x, 2, 2, _("limit requires two arguments"))
-    try:
-        # i18n: "limit" is a keyword
-        lim = int(getstring(l[1], _("limit requires a number")))
-    except ValueError:
-        # i18n: "limit" is a keyword
-        raise error.ParseError(_("limit expects a number"))
-    return getset(repo, subset, l[0])[:lim]
-
-def children(repo, subset, x):
-    """``children(set)``
-    Child changesets of changesets in set.
-    """
-    cs = set()
-    cl = repo.changelog
-    s = set(getset(repo, range(len(repo)), x))
-    for r in xrange(0, len(repo)):
-        for p in cl.parentrevs(r):
-            if p in s:
-                cs.add(r)
-    return [r for r in subset if r in cs]
-
-def branch(repo, subset, x):
-    """``branch(set)``
-    All changesets belonging to the branches of changesets in set.
-    """
-    s = getset(repo, range(len(repo)), x)
-    b = set()
-    for r in s:
-        b.add(repo[r].branch())
-    s = set(s)
-    return [r for r in subset if r in s or repo[r].branch() in b]
-
-def ancestor(repo, subset, x):
-    """``ancestor(single, single)``
-    Greatest common ancestor of the two changesets.
-    """
-    # i18n: "ancestor" is a keyword
-    l = getargs(x, 2, 2, _("ancestor requires two arguments"))
-    r = range(len(repo))
-    a = getset(repo, r, l[0])
-    b = getset(repo, r, l[1])
-    if len(a) != 1 or len(b) != 1:
-        # i18n: "ancestor" is a keyword
-        raise error.ParseError(_("ancestor arguments must be single revisions"))
-    an = [repo[a[0]].ancestor(repo[b[0]]).rev()]
-
-    return [r for r in an if r in subset]
-
-def ancestors(repo, subset, x):
-    """``ancestors(set)``
-    Changesets that are ancestors of a changeset in set.
-    """
-    args = getset(repo, range(len(repo)), x)
-    if not args:
-        return []
-    s = set(repo.changelog.ancestors(*args)) | set(args)
-    return [r for r in subset if r in s]
-
-def descendants(repo, subset, x):
-    """``descendants(set)``
-    Changesets which are descendants of changesets in set.
-    """
-    args = getset(repo, range(len(repo)), x)
-    if not args:
-        return []
-    s = set(repo.changelog.descendants(*args)) | set(args)
-    return [r for r in subset if r in s]
-
-def follow(repo, subset, x):
-    """``follow()``
-    An alias for ``::.`` (ancestors of the working copy's first parent).
-    """
-    # i18n: "follow" is a keyword
-    getargs(x, 0, 0, _("follow takes no arguments"))
-    p = repo['.'].rev()
-    s = set(repo.changelog.ancestors(p)) | set([p])
-    return [r for r in subset if r in s]
-
-def date(repo, subset, x):
-    """``date(interval)``
-    Changesets within the interval, see :hg:`help dates`.
-    """
-    # i18n: "date" is a keyword
-    ds = getstring(x, _("date requires a string"))
-    dm = util.matchdate(ds)
-    return [r for r in subset if dm(repo[r].date()[0])]
-
-def keyword(repo, subset, x):
-    """``keyword(string)``
-    Search commit message, user name, and names of changed files for
-    string. The match is case-insensitive.
-    """
-    # i18n: "keyword" is a keyword
-    kw = getstring(x, _("keyword requires a string")).lower()
-    l = []
-    for r in subset:
-        c = repo[r]
-        t = " ".join(c.files() + [c.user(), c.description()])
-        if kw in t.lower():
-            l.append(r)
-    return l
-
-def grep(repo, subset, x):
-    """``grep(regex)``
-    Like ``keyword(string)`` but accepts a regex. Use ``grep(r'...')``
-    to ensure special escape characters are handled correctly. Unlike
-    ``keyword(string)``, the match is case-sensitive.
+def parentspec(repo, subset, x, n):
+    """``set^0``
+    The set.
+    ``set^1`` (or ``set^``), ``set^2``
+    First or second parent, respectively, of all changesets in set.
     """
     try:
-        # i18n: "grep" is a keyword
-        gr = re.compile(getstring(x, _("grep requires a string")))
-    except re.error, e:
-        raise error.ParseError(_('invalid match pattern: %s') % e)
-    l = []
-    for r in subset:
-        c = repo[r]
-        for e in c.files() + [c.user(), c.description()]:
-            if gr.search(e):
-                l.append(r)
-                continue
-    return l
-
-def author(repo, subset, x):
-    """``author(string)``
-    Alias for ``user(string)``.
-    """
-    # i18n: "author" is a keyword
-    n = getstring(x, _("author requires a string")).lower()
-    return [r for r in subset if n in repo[r].user().lower()]
-
-def user(repo, subset, x):
-    """``user(string)``
-    User name contains string. The match is case-insensitive.
-    """
-    return author(repo, subset, x)
-
-def hasfile(repo, subset, x):
-    """``file(pattern)``
-    Changesets affecting files matched by pattern.
-    """
-    # i18n: "file" is a keyword
-    pat = getstring(x, _("file requires a pattern"))
-    m = matchmod.match(repo.root, repo.getcwd(), [pat])
-    s = []
-    for r in subset:
-        for f in repo[r].files():
-            if m(f):
-                s.append(r)
-                continue
-    return s
-
-def contains(repo, subset, x):
-    """``contains(pattern)``
-    Revision contains a file matching pattern. See :hg:`help patterns`
-    for information about file patterns.
-    """
-    # i18n: "contains" is a keyword
-    pat = getstring(x, _("contains requires a pattern"))
-    m = matchmod.match(repo.root, repo.getcwd(), [pat])
-    s = []
-    if m.files() == [pat]:
-        for r in subset:
-            if pat in repo[r]:
-                s.append(r)
-                continue
-    else:
-        for r in subset:
-            for f in repo[r].manifest():
-                if m(f):
-                    s.append(r)
-                    continue
-    return s
-
-def checkstatus(repo, subset, pat, field):
-    m = matchmod.match(repo.root, repo.getcwd(), [pat])
-    s = []
-    fast = (m.files() == [pat])
-    for r in subset:
-        c = repo[r]
-        if fast:
-            if pat not in c.files():
-                continue
-        else:
-            for f in c.files():
-                if m(f):
-                    break
-            else:
-                continue
-        files = repo.status(c.p1().node(), c.node())[field]
-        if fast:
-            if pat in files:
-                s.append(r)
-                continue
-        else:
-            for f in files:
-                if m(f):
-                    s.append(r)
-                    continue
-    return s
-
-def modifies(repo, subset, x):
-    """``modifies(pattern)``
-    Changesets modifying files matched by pattern.
-    """
-    # i18n: "modifies" is a keyword
-    pat = getstring(x, _("modifies requires a pattern"))
-    return checkstatus(repo, subset, pat, 0)
-
-def adds(repo, subset, x):
-    """``adds(pattern)``
-    Changesets that add a file matching pattern.
-    """
-    # i18n: "adds" is a keyword
-    pat = getstring(x, _("adds requires a pattern"))
-    return checkstatus(repo, subset, pat, 1)
-
-def removes(repo, subset, x):
-    """``removes(pattern)``
-    Changesets which remove files matching pattern.
-    """
-    # i18n: "removes" is a keyword
-    pat = getstring(x, _("removes requires a pattern"))
-    return checkstatus(repo, subset, pat, 2)
-
-def merge(repo, subset, x):
-    """``merge()``
-    Changeset is a merge changeset.
-    """
-    # i18n: "merge" is a keyword
-    getargs(x, 0, 0, _("merge takes no arguments"))
+        n = int(n[1])
+        if n not in (0, 1, 2):
+            raise ValueError
+    except ValueError:
+        raise error.ParseError(_("^ expects a number 0, 1, or 2"))
+    ps = set()
     cl = repo.changelog
-    return [r for r in subset if cl.parentrevs(r)[1] != -1]
-
-def closed(repo, subset, x):
-    """``closed()``
-    Changeset is closed.
-    """
-    # i18n: "closed" is a keyword
-    getargs(x, 0, 0, _("closed takes no arguments"))
-    return [r for r in subset if repo[r].extra().get('close')]
-
-def head(repo, subset, x):
-    """``head()``
-    Changeset is a named branch head.
-    """
-    # i18n: "head" is a keyword
-    getargs(x, 0, 0, _("head takes no arguments"))
-    hs = set()
-    for b, ls in repo.branchmap().iteritems():
-        hs.update(repo[h].rev() for h in ls)
-    return [r for r in subset if r in hs]
-
-def reverse(repo, subset, x):
-    """``reverse(set)``
-    Reverse order of set.
-    """
-    l = getset(repo, subset, x)
-    l.reverse()
-    return l
+    for r in getset(repo, subset, x):
+        if n == 0:
+            ps.add(r)
+        elif n == 1:
+            ps.add(cl.parentrevs(r)[0])
+        elif n == 2:
+            parents = cl.parentrevs(r)
+            if len(parents) > 1:
+                ps.add(parents[1])
+    return [r for r in subset if r in ps]
 
 def present(repo, subset, x):
     """``present(set)``
@@ -546,6 +701,44 @@
     except error.RepoLookupError:
         return []
 
+def removes(repo, subset, x):
+    """``removes(pattern)``
+    Changesets which remove files matching pattern.
+    """
+    # i18n: "removes" is a keyword
+    pat = getstring(x, _("removes requires a pattern"))
+    return checkstatus(repo, subset, pat, 2)
+
+def rev(repo, subset, x):
+    """``rev(number)``
+    Revision with the given numeric identifier.
+    """
+    # i18n: "rev" is a keyword
+    l = getargs(x, 1, 1, _("rev requires one argument"))
+    try:
+        # i18n: "rev" is a keyword
+        l = int(getstring(l[0], _("rev requires a number")))
+    except ValueError:
+        # i18n: "rev" is a keyword
+        raise error.ParseError(_("rev expects a number"))
+    return [r for r in subset if r == l]
+
+def reverse(repo, subset, x):
+    """``reverse(set)``
+    Reverse order of set.
+    """
+    l = getset(repo, subset, x)
+    l.reverse()
+    return l
+
+def roots(repo, subset, x):
+    """``roots(set)``
+    Changesets with no parent changeset in set.
+    """
+    s = getset(repo, subset, x)
+    cs = set(children(repo, subset, x))
+    return [r for r in s if r not in cs]
+
 def sort(repo, subset, x):
     """``sort(set[, [-]key...])``
     Sort set by keys. The default sort order is ascending, specify a key
@@ -601,53 +794,6 @@
     l.sort()
     return [e[-1] for e in l]
 
-def getall(repo, subset, x):
-    """``all()``
-    All changesets, the same as ``0:tip``.
-    """
-    # i18n: "all" is a keyword
-    getargs(x, 0, 0, _("all takes no arguments"))
-    return subset
-
-def heads(repo, subset, x):
-    """``heads(set)``
-    Members of set with no children in set.
-    """
-    s = getset(repo, subset, x)
-    ps = set(parents(repo, subset, x))
-    return [r for r in s if r not in ps]
-
-def roots(repo, subset, x):
-    """``roots(set)``
-    Changesets with no parent changeset in set.
-    """
-    s = getset(repo, subset, x)
-    cs = set(children(repo, subset, x))
-    return [r for r in s if r not in cs]
-
-def outgoing(repo, subset, x):
-    """``outgoing([path])``
-    Changesets not found in the specified destination repository, or the
-    default push location.
-    """
-    import hg # avoid start-up nasties
-    # i18n: "outgoing" is a keyword
-    l = getargs(x, 0, 1, _("outgoing requires a repository path"))
-    # i18n: "outgoing" is a keyword
-    dest = l and getstring(l[0], _("outgoing requires a repository path")) or ''
-    dest = repo.ui.expandpath(dest or 'default-push', dest or 'default')
-    dest, branches = hg.parseurl(dest)
-    revs, checkout = hg.addbranchrevs(repo, repo, branches, [])
-    if revs:
-        revs = [repo.lookup(rev) for rev in revs]
-    other = hg.repository(hg.remoteui(repo, {}), dest)
-    repo.ui.pushbuffer()
-    o = discovery.findoutgoing(repo, other)
-    repo.ui.popbuffer()
-    cl = repo.changelog
-    o = set([cl.rev(r) for r in repo.changelog.nodesbetween(o, revs)[0]])
-    return [r for r in subset if r in o]
-
 def tag(repo, subset, x):
     """``tag([name])``
     The specified tag by name, or all tagged revisions if no name is given.
@@ -659,6 +805,8 @@
         tn = getstring(args[0],
                        # i18n: "tag" is a keyword
                        _('the argument to tag must be a string'))
+        if not repo.tags().get(tn, None):
+            raise util.Abort(_("tag '%s' does not exist") % tn)
         s = set([cl.rev(n) for t, n in repo.tagslist() if t == tn])
     else:
         s = set([cl.rev(n) for t, n in repo.tagslist() if t != 'tip'])
@@ -667,23 +815,11 @@
 def tagged(repo, subset, x):
     return tag(repo, subset, x)
 
-def bookmark(repo, subset, x):
-    """``bookmark([name])``
-    The named bookmark or all bookmarks.
+def user(repo, subset, x):
+    """``user(string)``
+    User name contains string. The match is case-insensitive.
     """
-    # i18n: "bookmark" is a keyword
-    args = getargs(x, 0, 1, _('bookmark takes one or no arguments'))
-    if args:
-        bm = getstring(args[0],
-                       # i18n: "bookmark" is a keyword
-                       _('the argument to bookmark must be a string'))
-        bmrev = bookmarksmod.listbookmarks(repo).get(bm, None)
-        if bmrev:
-            bmrev = repo[bmrev].rev()
-        return [r for r in subset if r == bmrev]
-    bms = set([repo[r].rev()
-               for r in bookmarksmod.listbookmarks(repo).values()])
-    return [r for r in subset if r in bms]
+    return author(repo, subset, x)
 
 symbols = {
     "adds": adds,
@@ -691,33 +827,37 @@
     "ancestor": ancestor,
     "ancestors": ancestors,
     "author": author,
+    "bisected": bisected,
     "bookmark": bookmark,
     "branch": branch,
     "children": children,
     "closed": closed,
     "contains": contains,
     "date": date,
+    "desc": desc,
     "descendants": descendants,
     "file": hasfile,
+    "filelog": filelog,
     "follow": follow,
     "grep": grep,
     "head": head,
     "heads": heads,
+    "id": node,
     "keyword": keyword,
+    "last": last,
     "limit": limit,
     "max": maxrev,
+    "merge": merge,
     "min": minrev,
-    "merge": merge,
     "modifies": modifies,
-    "id": node,
     "outgoing": outgoing,
     "p1": p1,
     "p2": p2,
     "parents": parents,
     "present": present,
     "removes": removes,
+    "rev": rev,
     "reverse": reverse,
-    "rev": rev,
     "roots": roots,
     "sort": sort,
     "tag": tag,
@@ -734,6 +874,9 @@
     "not": notset,
     "list": listset,
     "func": func,
+    "ancestor": ancestorspec,
+    "parent": parentspec,
+    "parentpost": p1,
 }
 
 def optimize(x, small):
@@ -779,16 +922,20 @@
     elif op == 'not':
         o = optimize(x[1], not small)
         return o[0], (op, o[1])
+    elif op == 'parentpost':
+        o = optimize(x[1], small)
+        return o[0], (op, o[1])
     elif op == 'group':
         return optimize(x[1], small)
-    elif op in 'range list':
+    elif op in 'range list parent ancestorspec':
         wa, ta = optimize(x[1], small)
         wb, tb = optimize(x[2], small)
         return wa + wb, (op, ta, tb)
     elif op == 'func':
         f = getstring(x[1], _("not a symbol"))
         wa, ta = optimize(x[2], small)
-        if f in "grep date user author keyword branch file outgoing":
+        if f in ("author branch closed date desc file grep keyword "
+                 "outgoing user"):
             w = 10 # slow
         elif f in "modifies adds removes":
             w = 30 # slower
@@ -805,33 +952,93 @@
         return w + wa, (op, x[1], ta)
     return 1, x
 
+class revsetalias(object):
+    funcre = re.compile('^([^(]+)\(([^)]+)\)$')
+    args = ()
+
+    def __init__(self, token, value):
+        '''Aliases like:
+
+        h = heads(default)
+        b($1) = ancestors($1) - ancestors(default)
+        '''
+        if isinstance(token, tuple):
+            self.type, self.name = token
+        else:
+            m = self.funcre.search(token)
+            if m:
+                self.type = 'func'
+                self.name = m.group(1)
+                self.args = [x.strip() for x in m.group(2).split(',')]
+            else:
+                self.type = 'symbol'
+                self.name = token
+
+        if isinstance(value, str):
+            for arg in self.args:
+                value = value.replace(arg, repr(arg))
+            self.replacement, pos = parse(value)
+            if pos != len(value):
+                raise error.ParseError('invalid token', pos)
+        else:
+            self.replacement = value
+
+    def match(self, tree):
+        if not tree:
+            return False
+        if tree == (self.type, self.name):
+            return True
+        if tree[0] != self.type:
+            return False
+        if len(tree) > 1 and tree[1] != ('symbol', self.name):
+            return False
+        # 'func' + funcname + args
+        if ((self.args and len(tree) != 3) or
+            (len(self.args) == 1 and tree[2][0] == 'list') or
+            (len(self.args) > 1 and (tree[2][0] != 'list' or
+                                     len(tree[2]) - 1 != len(self.args)))):
+            raise error.ParseError('invalid amount of arguments', len(tree) - 2)
+        return True
+
+    def replace(self, tree):
+        if tree == (self.type, self.name):
+            return self.replacement
+        result = self.replacement
+        def getsubtree(i):
+            if tree[2][0] == 'list':
+                return tree[2][i + 1]
+            return tree[i + 2]
+        for i, v in enumerate(self.args):
+            valalias = revsetalias(('string', v), getsubtree(i))
+            result = valalias.process(result)
+        return result
+
+    def process(self, tree):
+        if self.match(tree):
+            return self.replace(tree)
+        if isinstance(tree, tuple):
+            return tuple(map(self.process, tree))
+        return tree
+
+def findaliases(ui, tree):
+    for k, v in ui.configitems('revsetalias'):
+        alias = revsetalias(k, v)
+        tree = alias.process(tree)
+    return tree
+
 parse = parser.parser(tokenize, elements).parse
 
-def match(spec):
+def match(ui, spec):
     if not spec:
         raise error.ParseError(_("empty query"))
     tree, pos = parse(spec)
     if (pos != len(spec)):
         raise error.ParseError("invalid token", pos)
+    tree = findaliases(ui, tree)
     weight, tree = optimize(tree, True)
     def mfunc(repo, subset):
         return getset(repo, subset, tree)
     return mfunc
 
-def makedoc(topic, doc):
-    """Generate and include predicates help in revsets topic."""
-    predicates = []
-    for name in sorted(symbols):
-        text = symbols[name].__doc__
-        if not text:
-            continue
-        text = gettext(text.rstrip())
-        lines = text.splitlines()
-        lines[1:] = [('  ' + l.strip()) for l in lines[1:]]
-        predicates.append('\n'.join(lines))
-    predicates = '\n\n'.join(predicates)
-    doc = doc.replace('.. predicatesmarker', predicates)
-    return doc
-
 # tell hggettext to extract docstrings from these functions:
 i18nfunctions = symbols.values()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mercurial/scmutil.py	Sat Jun 18 17:03:01 2011 -0500
@@ -0,0 +1,705 @@
+# scmutil.py - Mercurial core utility functions
+#
+#  Copyright Matt Mackall <mpm@selenic.com>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2 or any later version.
+
+from i18n import _
+import util, error, osutil, revset, similar
+import match as matchmod
+import os, errno, stat, sys, glob
+
+def checkfilename(f):
+    '''Check that the filename f is an acceptable filename for a tracked file'''
+    if '\r' in f or '\n' in f:
+        raise util.Abort(_("'\\n' and '\\r' disallowed in filenames: %r") % f)
+
+def checkportable(ui, f):
+    '''Check if filename f is portable and warn or abort depending on config'''
+    checkfilename(f)
+    abort, warn = checkportabilityalert(ui)
+    if abort or warn:
+        msg = util.checkwinfilename(f)
+        if msg:
+            msg = "%s: %r" % (msg, f)
+            if abort:
+                raise util.Abort(msg)
+            ui.warn(_("warning: %s\n") % msg)
+
+def checkportabilityalert(ui):
+    '''check if the user's config requests nothing, a warning, or abort for
+    non-portable filenames'''
+    val = ui.config('ui', 'portablefilenames', 'warn')
+    lval = val.lower()
+    bval = util.parsebool(val)
+    abort = os.name == 'nt' or lval == 'abort'
+    warn = bval or lval == 'warn'
+    if bval is None and not (warn or abort or lval == 'ignore'):
+        raise error.ConfigError(
+            _("ui.portablefilenames value is invalid ('%s')") % val)
+    return abort, warn
+
+class casecollisionauditor(object):
+    def __init__(self, ui, abort, existingiter):
+        self._ui = ui
+        self._abort = abort
+        self._map = {}
+        for f in existingiter:
+            self._map[f.lower()] = f
+
+    def __call__(self, f):
+        fl = f.lower()
+        map = self._map
+        if fl in map and map[fl] != f:
+            msg = _('possible case-folding collision for %s') % f
+            if self._abort:
+                raise util.Abort(msg)
+            self._ui.warn(_("warning: %s\n") % msg)
+        map[fl] = f
+
+class pathauditor(object):
+    '''ensure that a filesystem path contains no banned components.
+    the following properties of a path are checked:
+
+    - ends with a directory separator
+    - under top-level .hg
+    - starts at the root of a windows drive
+    - contains ".."
+    - traverses a symlink (e.g. a/symlink_here/b)
+    - inside a nested repository (a callback can be used to approve
+      some nested repositories, e.g., subrepositories)
+    '''
+
+    def __init__(self, root, callback=None):
+        self.audited = set()
+        self.auditeddir = set()
+        self.root = root
+        self.callback = callback
+
+    def __call__(self, path):
+        '''Check the relative path.
+        path may contain a pattern (e.g. foodir/**.txt)'''
+
+        if path in self.audited:
+            return
+        # AIX ignores "/" at end of path, others raise EISDIR.
+        if util.endswithsep(path):
+            raise util.Abort(_("path ends in directory separator: %s") % path)
+        normpath = os.path.normcase(path)
+        parts = util.splitpath(normpath)
+        if (os.path.splitdrive(path)[0]
+            or parts[0].lower() in ('.hg', '.hg.', '')
+            or os.pardir in parts):
+            raise util.Abort(_("path contains illegal component: %s") % path)
+        if '.hg' in path.lower():
+            lparts = [p.lower() for p in parts]
+            for p in '.hg', '.hg.':
+                if p in lparts[1:]:
+                    pos = lparts.index(p)
+                    base = os.path.join(*parts[:pos])
+                    raise util.Abort(_('path %r is inside nested repo %r')
+                                     % (path, base))
+
+        parts.pop()
+        prefixes = []
+        while parts:
+            prefix = os.sep.join(parts)
+            if prefix in self.auditeddir:
+                break
+            curpath = os.path.join(self.root, prefix)
+            try:
+                st = os.lstat(curpath)
+            except OSError, err:
+                # EINVAL can be raised as invalid path syntax under win32.
+                # They must be ignored for patterns can be checked too.
+                if err.errno not in (errno.ENOENT, errno.ENOTDIR, errno.EINVAL):
+                    raise
+            else:
+                if stat.S_ISLNK(st.st_mode):
+                    raise util.Abort(
+                        _('path %r traverses symbolic link %r')
+                        % (path, prefix))
+                elif (stat.S_ISDIR(st.st_mode) and
+                      os.path.isdir(os.path.join(curpath, '.hg'))):
+                    if not self.callback or not self.callback(curpath):
+                        raise util.Abort(_('path %r is inside nested repo %r') %
+                                         (path, prefix))
+            prefixes.append(prefix)
+            parts.pop()
+
+        self.audited.add(path)
+        # only add prefixes to the cache after checking everything: we don't
+        # want to add "foo/bar/baz" before checking if there's a "foo/.hg"
+        self.auditeddir.update(prefixes)
+
+class abstractopener(object):
+    """Abstract base class; cannot be instantiated"""
+
+    def __init__(self, *args, **kwargs):
+        '''Prevent instantiation; don't call this from subclasses.'''
+        raise NotImplementedError('attempted instantiating ' + str(type(self)))
+
+    def read(self, path):
+        fp = self(path, 'rb')
+        try:
+            return fp.read()
+        finally:
+            fp.close()
+
+    def write(self, path, data):
+        fp = self(path, 'wb')
+        try:
+            return fp.write(data)
+        finally:
+            fp.close()
+
+    def append(self, path, data):
+        fp = self(path, 'ab')
+        try:
+            return fp.write(data)
+        finally:
+            fp.close()
+
+class opener(abstractopener):
+    '''Open files relative to a base directory
+
+    This class is used to hide the details of COW semantics and
+    remote file access from higher level code.
+    '''
+    def __init__(self, base, audit=True):
+        self.base = base
+        if audit:
+            self.auditor = pathauditor(base)
+        else:
+            self.auditor = util.always
+        self.createmode = None
+        self._trustnlink = None
+
+    @util.propertycache
+    def _cansymlink(self):
+        return util.checklink(self.base)
+
+    def _fixfilemode(self, name):
+        if self.createmode is None:
+            return
+        os.chmod(name, self.createmode & 0666)
+
+    def __call__(self, path, mode="r", text=False, atomictemp=False):
+        r = util.checkosfilename(path)
+        if r:
+            raise util.Abort("%s: %r" % (r, path))
+        self.auditor(path)
+        f = os.path.join(self.base, path)
+
+        if not text and "b" not in mode:
+            mode += "b" # for that other OS
+
+        nlink = -1
+        dirname, basename = os.path.split(f)
+        # If basename is empty, then the path is malformed because it points
+        # to a directory. Let the posixfile() call below raise IOError.
+        if basename and mode not in ('r', 'rb'):
+            if atomictemp:
+                if not os.path.isdir(dirname):
+                    util.makedirs(dirname, self.createmode)
+                return util.atomictempfile(f, mode, self.createmode)
+            try:
+                if 'w' in mode:
+                    util.unlink(f)
+                    nlink = 0
+                else:
+                    # nlinks() may behave differently for files on Windows
+                    # shares if the file is open.
+                    fd = util.posixfile(f)
+                    nlink = util.nlinks(f)
+                    if nlink < 1:
+                        nlink = 2 # force mktempcopy (issue1922)
+                    fd.close()
+            except (OSError, IOError), e:
+                if e.errno != errno.ENOENT:
+                    raise
+                nlink = 0
+                if not os.path.isdir(dirname):
+                    util.makedirs(dirname, self.createmode)
+            if nlink > 0:
+                if self._trustnlink is None:
+                    self._trustnlink = nlink > 1 or util.checknlink(f)
+                if nlink > 1 or not self._trustnlink:
+                    util.rename(util.mktempcopy(f), f)
+        fp = util.posixfile(f, mode)
+        if nlink == 0:
+            self._fixfilemode(f)
+        return fp
+
+    def symlink(self, src, dst):
+        self.auditor(dst)
+        linkname = os.path.join(self.base, dst)
+        try:
+            os.unlink(linkname)
+        except OSError:
+            pass
+
+        dirname = os.path.dirname(linkname)
+        if not os.path.exists(dirname):
+            util.makedirs(dirname, self.createmode)
+
+        if self._cansymlink:
+            try:
+                os.symlink(src, linkname)
+            except OSError, err:
+                raise OSError(err.errno, _('could not symlink to %r: %s') %
+                              (src, err.strerror), linkname)
+        else:
+            f = self(dst, "w")
+            f.write(src)
+            f.close()
+            self._fixfilemode(dst)
+
+    def audit(self, path):
+        self.auditor(path)
+
+class filteropener(abstractopener):
+    '''Wrapper opener for filtering filenames with a function.'''
+
+    def __init__(self, opener, filter):
+        self._filter = filter
+        self._orig = opener
+
+    def __call__(self, path, *args, **kwargs):
+        return self._orig(self._filter(path), *args, **kwargs)
+
+def canonpath(root, cwd, myname, auditor=None):
+    '''return the canonical path of myname, given cwd and root'''
+    if util.endswithsep(root):
+        rootsep = root
+    else:
+        rootsep = root + os.sep
+    name = myname
+    if not os.path.isabs(name):
+        name = os.path.join(root, cwd, name)
+    name = os.path.normpath(name)
+    if auditor is None:
+        auditor = pathauditor(root)
+    if name != rootsep and name.startswith(rootsep):
+        name = name[len(rootsep):]
+        auditor(name)
+        return util.pconvert(name)
+    elif name == root:
+        return ''
+    else:
+        # Determine whether `name' is in the hierarchy at or beneath `root',
+        # by iterating name=dirname(name) until that causes no change (can't
+        # check name == '/', because that doesn't work on windows).  For each
+        # `name', compare dev/inode numbers.  If they match, the list `rel'
+        # holds the reversed list of components making up the relative file
+        # name we want.
+        root_st = os.stat(root)
+        rel = []
+        while True:
+            try:
+                name_st = os.stat(name)
+            except OSError:
+                break
+            if util.samestat(name_st, root_st):
+                if not rel:
+                    # name was actually the same as root (maybe a symlink)
+                    return ''
+                rel.reverse()
+                name = os.path.join(*rel)
+                auditor(name)
+                return util.pconvert(name)
+            dirname, basename = os.path.split(name)
+            rel.append(basename)
+            if dirname == name:
+                break
+            name = dirname
+
+        raise util.Abort('%s not under root' % myname)
+
+def walkrepos(path, followsym=False, seen_dirs=None, recurse=False):
+    '''yield every hg repository under path, recursively.'''
+    def errhandler(err):
+        if err.filename == path:
+            raise err
+    if followsym and hasattr(os.path, 'samestat'):
+        def adddir(dirlst, dirname):
+            match = False
+            samestat = os.path.samestat
+            dirstat = os.stat(dirname)
+            for lstdirstat in dirlst:
+                if samestat(dirstat, lstdirstat):
+                    match = True
+                    break
+            if not match:
+                dirlst.append(dirstat)
+            return not match
+    else:
+        followsym = False
+
+    if (seen_dirs is None) and followsym:
+        seen_dirs = []
+        adddir(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')
+            if os.path.isdir(os.path.join(qroot, '.hg')):
+                yield qroot # we have a patch queue repo here
+            if recurse:
+                # avoid recursing inside the .hg directory
+                dirs.remove('.hg')
+            else:
+                dirs[:] = [] # don't descend further
+        elif followsym:
+            newdirs = []
+            for d in dirs:
+                fname = os.path.join(root, d)
+                if adddir(seen_dirs, fname):
+                    if os.path.islink(fname):
+                        for hgname in walkrepos(fname, True, seen_dirs):
+                            yield hgname
+                    else:
+                        newdirs.append(d)
+            dirs[:] = newdirs
+
+def osrcpath():
+    '''return default os-specific hgrc search path'''
+    path = systemrcpath()
+    path.extend(userrcpath())
+    path = [os.path.normpath(f) for f in path]
+    return path
+
+_rcpath = None
+
+def rcpath():
+    '''return hgrc search path. if env var HGRCPATH is set, use it.
+    for each item in path, if directory, use files ending in .rc,
+    else use item.
+    make HGRCPATH empty to only look in .hg/hgrc of current repo.
+    if no HGRCPATH, use default os-specific path.'''
+    global _rcpath
+    if _rcpath is None:
+        if 'HGRCPATH' in os.environ:
+            _rcpath = []
+            for p in os.environ['HGRCPATH'].split(os.pathsep):
+                if not p:
+                    continue
+                p = util.expandpath(p)
+                if os.path.isdir(p):
+                    for f, kind in osutil.listdir(p):
+                        if f.endswith('.rc'):
+                            _rcpath.append(os.path.join(p, f))
+                else:
+                    _rcpath.append(p)
+        else:
+            _rcpath = osrcpath()
+    return _rcpath
+
+if os.name != 'nt':
+
+    def rcfiles(path):
+        rcs = [os.path.join(path, 'hgrc')]
+        rcdir = os.path.join(path, 'hgrc.d')
+        try:
+            rcs.extend([os.path.join(rcdir, f)
+                        for f, kind in osutil.listdir(rcdir)
+                        if f.endswith(".rc")])
+        except OSError:
+            pass
+        return rcs
+
+    def systemrcpath():
+        path = []
+        # old mod_python does not set sys.argv
+        if len(getattr(sys, 'argv', [])) > 0:
+            p = os.path.dirname(os.path.dirname(sys.argv[0]))
+            path.extend(rcfiles(os.path.join(p, 'etc/mercurial')))
+        path.extend(rcfiles('/etc/mercurial'))
+        return path
+
+    def userrcpath():
+        return [os.path.expanduser('~/.hgrc')]
+
+else:
+
+    _HKEY_LOCAL_MACHINE = 0x80000002L
+
+    def systemrcpath():
+        '''return default os-specific hgrc search path'''
+        rcpath = []
+        filename = util.executablepath()
+        # Use mercurial.ini found in directory with hg.exe
+        progrc = os.path.join(os.path.dirname(filename), 'mercurial.ini')
+        if os.path.isfile(progrc):
+            rcpath.append(progrc)
+            return rcpath
+        # Use hgrc.d found in directory with hg.exe
+        progrcd = os.path.join(os.path.dirname(filename), 'hgrc.d')
+        if os.path.isdir(progrcd):
+            for f, kind in osutil.listdir(progrcd):
+                if f.endswith('.rc'):
+                    rcpath.append(os.path.join(progrcd, f))
+            return rcpath
+        # else look for a system rcpath in the registry
+        value = util.lookupreg('SOFTWARE\\Mercurial', None,
+                               _HKEY_LOCAL_MACHINE)
+        if not isinstance(value, str) or not value:
+            return rcpath
+        value = value.replace('/', os.sep)
+        for p in value.split(os.pathsep):
+            if p.lower().endswith('mercurial.ini'):
+                rcpath.append(p)
+            elif os.path.isdir(p):
+                for f, kind in osutil.listdir(p):
+                    if f.endswith('.rc'):
+                        rcpath.append(os.path.join(p, f))
+        return rcpath
+
+    def userrcpath():
+        '''return os-specific hgrc search path to the user dir'''
+        home = os.path.expanduser('~')
+        path = [os.path.join(home, 'mercurial.ini'),
+                os.path.join(home, '.hgrc')]
+        userprofile = os.environ.get('USERPROFILE')
+        if userprofile:
+            path.append(os.path.join(userprofile, 'mercurial.ini'))
+            path.append(os.path.join(userprofile, '.hgrc'))
+        return path
+
+def revsingle(repo, revspec, default='.'):
+    if not revspec:
+        return repo[default]
+
+    l = revrange(repo, [revspec])
+    if len(l) < 1:
+        raise util.Abort(_('empty revision set'))
+    return repo[l[-1]]
+
+def revpair(repo, revs):
+    if not revs:
+        return repo.dirstate.p1(), None
+
+    l = revrange(repo, revs)
+
+    if len(l) == 0:
+        return repo.dirstate.p1(), None
+
+    if len(l) == 1:
+        return repo.lookup(l[0]), None
+
+    return repo.lookup(l[0]), repo.lookup(l[-1])
+
+_revrangesep = ':'
+
+def revrange(repo, revs):
+    """Yield revision as strings from a list of revision specifications."""
+
+    def revfix(repo, val, defval):
+        if not val and val != 0 and defval is not None:
+            return defval
+        return repo.changelog.rev(repo.lookup(val))
+
+    seen, l = set(), []
+    for spec in revs:
+        # attempt to parse old-style ranges first to deal with
+        # things like old-tag which contain query metacharacters
+        try:
+            if isinstance(spec, int):
+                seen.add(spec)
+                l.append(spec)
+                continue
+
+            if _revrangesep in spec:
+                start, end = spec.split(_revrangesep, 1)
+                start = revfix(repo, start, 0)
+                end = revfix(repo, end, len(repo) - 1)
+                step = start > end and -1 or 1
+                for rev in xrange(start, end + step, step):
+                    if rev in seen:
+                        continue
+                    seen.add(rev)
+                    l.append(rev)
+                continue
+            elif spec and spec in repo: # single unquoted rev
+                rev = revfix(repo, spec, None)
+                if rev in seen:
+                    continue
+                seen.add(rev)
+                l.append(rev)
+                continue
+        except error.RepoLookupError:
+            pass
+
+        # fall through to new-style queries if old-style fails
+        m = revset.match(repo.ui, spec)
+        for r in m(repo, range(len(repo))):
+            if r not in seen:
+                l.append(r)
+        seen.update(l)
+
+    return l
+
+def expandpats(pats):
+    if not util.expandglobs:
+        return list(pats)
+    ret = []
+    for p in pats:
+        kind, name = matchmod._patsplit(p, None)
+        if kind is None:
+            try:
+                globbed = glob.glob(name)
+            except re.error:
+                globbed = [name]
+            if globbed:
+                ret.extend(globbed)
+                continue
+        ret.append(p)
+    return ret
+
+def match(ctx, pats=[], opts={}, globbed=False, default='relpath'):
+    if pats == ("",):
+        pats = []
+    if not globbed and default == 'relpath':
+        pats = expandpats(pats or [])
+
+    m = ctx.match(pats, opts.get('include'), opts.get('exclude'),
+                         default)
+    def badfn(f, msg):
+        ctx._repo.ui.warn("%s: %s\n" % (m.rel(f), msg))
+    m.bad = badfn
+    return m
+
+def matchall(repo):
+    return matchmod.always(repo.root, repo.getcwd())
+
+def matchfiles(repo, files):
+    return matchmod.exact(repo.root, repo.getcwd(), files)
+
+def addremove(repo, pats=[], opts={}, dry_run=None, similarity=None):
+    if dry_run is None:
+        dry_run = opts.get('dry_run')
+    if similarity is None:
+        similarity = float(opts.get('similarity') or 0)
+    # we'd use status here, except handling of symlinks and ignore is tricky
+    added, unknown, deleted, removed = [], [], [], []
+    audit_path = pathauditor(repo.root)
+    m = match(repo[None], pats, opts)
+    for abs in repo.walk(m):
+        target = repo.wjoin(abs)
+        good = True
+        try:
+            audit_path(abs)
+        except (OSError, util.Abort):
+            good = False
+        rel = m.rel(abs)
+        exact = m.exact(abs)
+        if good and abs not in repo.dirstate:
+            unknown.append(abs)
+            if repo.ui.verbose or not exact:
+                repo.ui.status(_('adding %s\n') % ((pats and rel) or abs))
+        elif repo.dirstate[abs] != 'r' and (not good or not os.path.lexists(target)
+            or (os.path.isdir(target) and not os.path.islink(target))):
+            deleted.append(abs)
+            if repo.ui.verbose or not exact:
+                repo.ui.status(_('removing %s\n') % ((pats and rel) or abs))
+        # for finding renames
+        elif repo.dirstate[abs] == 'r':
+            removed.append(abs)
+        elif repo.dirstate[abs] == 'a':
+            added.append(abs)
+    copies = {}
+    if similarity > 0:
+        for old, new, score in similar.findrenames(repo,
+                added + unknown, removed + deleted, similarity):
+            if repo.ui.verbose or not m.exact(old) or not m.exact(new):
+                repo.ui.status(_('recording removal of %s as rename to %s '
+                                 '(%d%% similar)\n') %
+                               (m.rel(old), m.rel(new), score * 100))
+            copies[new] = old
+
+    if not dry_run:
+        wctx = repo[None]
+        wlock = repo.wlock()
+        try:
+            wctx.forget(deleted)
+            wctx.add(unknown)
+            for new, old in copies.iteritems():
+                wctx.copy(old, new)
+        finally:
+            wlock.release()
+
+def updatedir(ui, repo, patches, similarity=0):
+    '''Update dirstate after patch application according to metadata'''
+    if not patches:
+        return []
+    copies = []
+    removes = set()
+    cfiles = patches.keys()
+    cwd = repo.getcwd()
+    if cwd:
+        cfiles = [util.pathto(repo.root, cwd, f) for f in patches.keys()]
+    for f in patches:
+        gp = patches[f]
+        if not gp:
+            continue
+        if gp.op == 'RENAME':
+            copies.append((gp.oldpath, gp.path))
+            removes.add(gp.oldpath)
+        elif gp.op == 'COPY':
+            copies.append((gp.oldpath, gp.path))
+        elif gp.op == 'DELETE':
+            removes.add(gp.path)
+
+    wctx = repo[None]
+    for src, dst in copies:
+        dirstatecopy(ui, repo, wctx, src, dst, cwd=cwd)
+    if (not similarity) and removes:
+        wctx.remove(sorted(removes), True)
+
+    for f in patches:
+        gp = patches[f]
+        if gp and gp.mode:
+            islink, isexec = gp.mode
+            dst = repo.wjoin(gp.path)
+            # patch won't create empty files
+            if gp.op == 'ADD' and not os.path.lexists(dst):
+                flags = (isexec and 'x' or '') + (islink and 'l' or '')
+                repo.wwrite(gp.path, '', flags)
+            util.setflags(dst, islink, isexec)
+    addremove(repo, cfiles, similarity=similarity)
+    files = patches.keys()
+    files.extend([r for r in removes if r not in files])
+    return sorted(files)
+
+def dirstatecopy(ui, repo, wctx, src, dst, dryrun=False, cwd=None):
+    """Update the dirstate to reflect the intent of copying src to dst. For
+    different reasons it might not end with dst being marked as copied from src.
+    """
+    origsrc = repo.dirstate.copied(src) or src
+    if dst == origsrc: # copying back a copy?
+        if repo.dirstate[dst] not in 'mn' and not dryrun:
+            repo.dirstate.normallookup(dst)
+    else:
+        if repo.dirstate[origsrc] == 'a' and origsrc == src:
+            if not ui.quiet:
+                ui.warn(_("%s has not been committed yet, so no copy "
+                          "data will be stored for %s.\n")
+                        % (repo.pathto(origsrc, cwd), repo.pathto(dst, cwd)))
+            if repo.dirstate[dst] in '?r' and not dryrun:
+                wctx.add([dst])
+        elif not dryrun:
+            wctx.copy(origsrc, dst)
+
+def readrequires(opener, supported):
+    '''Reads and parses .hg/requires and checks if all entries found
+    are in the list of supported features.'''
+    requirements = set(opener.read("requires").splitlines())
+    for r in requirements:
+        if r not in supported:
+            if not r or not r[0].isalnum():
+                raise error.RequirementError(_(".hg/requires file is corrupt"))
+            raise error.RequirementError(_("unknown repository format: "
+                "requires feature '%s' (upgrade Mercurial)") % r)
+    return requirements
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mercurial/setdiscovery.py	Sat Jun 18 17:03:01 2011 -0500
@@ -0,0 +1,193 @@
+# setdiscovery.py - improved discovery of common nodeset for mercurial
+#
+# Copyright 2010 Benoit Boissinot <bboissin@gmail.com>
+# and Peter Arrenbrecht <peter@arrenbrecht.ch>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2 or any later version.
+
+from node import nullid
+from i18n import _
+import random, collections, util, dagutil
+
+def _updatesample(dag, nodes, sample, always, quicksamplesize=0):
+    # if nodes is empty we scan the entire graph
+    if nodes:
+        heads = dag.headsetofconnecteds(nodes)
+    else:
+        heads = dag.heads()
+    dist = {}
+    visit = collections.deque(heads)
+    seen = set()
+    factor = 1
+    while visit:
+        curr = visit.popleft()
+        if curr in seen:
+            continue
+        d = dist.setdefault(curr, 1)
+        if d > factor:
+            factor *= 2
+        if d == factor:
+            if curr not in always: # need this check for the early exit below
+                sample.add(curr)
+                if quicksamplesize and (len(sample) >= quicksamplesize):
+                    return
+        seen.add(curr)
+        for p in dag.parents(curr):
+            if not nodes or p in nodes:
+                dist.setdefault(p, d + 1)
+                visit.append(p)
+
+def _setupsample(dag, nodes, size):
+    if len(nodes) <= size:
+        return set(nodes), None, 0
+    always = set(dag.heads())
+    desiredlen = size - len(always)
+    if desiredlen <= 0:
+        # This could be bad if there are very many heads, all unknown to the
+        # server. We're counting on long request support here.
+        return always, None, desiredlen
+    return always, set(), desiredlen
+
+def _takequicksample(dag, nodes, size, initial):
+    always, sample, desiredlen = _setupsample(dag, nodes, size)
+    if sample is None:
+        return always
+    if initial:
+        fromset = None
+    else:
+        fromset = nodes
+    _updatesample(dag, fromset, sample, always, quicksamplesize=desiredlen)
+    sample.update(always)
+    return sample
+
+def _takefullsample(dag, nodes, size):
+    always, sample, desiredlen = _setupsample(dag, nodes, size)
+    if sample is None:
+        return always
+    # update from heads
+    _updatesample(dag, nodes, sample, always)
+    # update from roots
+    _updatesample(dag.inverse(), nodes, sample, always)
+    assert sample
+    if len(sample) > desiredlen:
+        sample = set(random.sample(sample, desiredlen))
+    elif len(sample) < desiredlen:
+        more = desiredlen - len(sample)
+        sample.update(random.sample(list(nodes - sample - always), more))
+    sample.update(always)
+    return sample
+
+def findcommonheads(ui, local, remote,
+                    initialsamplesize=100,
+                    fullsamplesize=200,
+                    abortwhenunrelated=True):
+    '''Return a tuple (common, anyincoming, remoteheads) used to identify
+    missing nodes from or in remote.
+
+    shortcutlocal determines whether we try use direct access to localrepo if
+    remote is actually local.
+    '''
+    roundtrips = 0
+    cl = local.changelog
+    dag = dagutil.revlogdag(cl)
+
+    # early exit if we know all the specified remote heads already
+    ui.debug("query 1; heads\n")
+    roundtrips += 1
+    ownheads = dag.heads()
+    sample = ownheads
+    if remote.local():
+        # stopgap until we have a proper localpeer that supports batch()
+        srvheadhashes = remote.heads()
+        yesno = remote.known(dag.externalizeall(sample))
+    elif remote.capable('batch'):
+        batch = remote.batch()
+        srvheadhashesref = batch.heads()
+        yesnoref = batch.known(dag.externalizeall(sample))
+        batch.submit()
+        srvheadhashes = srvheadhashesref.value
+        yesno = yesnoref.value
+    else:
+        # compatibitity with pre-batch, but post-known remotes during 1.9 devel
+        srvheadhashes = remote.heads()
+        sample = []
+
+    if cl.tip() == nullid:
+        if srvheadhashes != [nullid]:
+            return [nullid], True, srvheadhashes
+        return [nullid], False, []
+
+    # start actual discovery (we note this before the next "if" for
+    # compatibility reasons)
+    ui.status(_("searching for changes\n"))
+
+    srvheads = dag.internalizeall(srvheadhashes, filterunknown=True)
+    if len(srvheads) == len(srvheadhashes):
+        ui.note("all remote heads known locally\n")
+        return (srvheadhashes, False, srvheadhashes,)
+
+    if sample and util.all(yesno):
+        ui.note("all local heads known remotely\n")
+        ownheadhashes = dag.externalizeall(ownheads)
+        return (ownheadhashes, True, srvheadhashes,)
+
+    # full blown discovery
+    undecided = dag.nodeset() # own nodes where I don't know if remote knows them
+    common = set() # own nodes I know we both know
+    missing = set() # own nodes I know remote lacks
+
+    # treat remote heads (and maybe own heads) as a first implicit sample response
+    common.update(dag.ancestorset(srvheads))
+    undecided.difference_update(common)
+
+    full = False
+    while undecided:
+
+        if sample:
+            commoninsample = set(n for i, n in enumerate(sample) if yesno[i])
+            common.update(dag.ancestorset(commoninsample, common))
+
+            missinginsample = [n for i, n in enumerate(sample) if not yesno[i]]
+            missing.update(dag.descendantset(missinginsample, missing))
+
+            undecided.difference_update(missing)
+            undecided.difference_update(common)
+
+        if not undecided:
+            break
+
+        if full:
+            ui.note("sampling from both directions\n")
+            sample = _takefullsample(dag, undecided, size=fullsamplesize)
+        elif common:
+            # use cheapish initial sample
+            ui.debug("taking initial sample\n")
+            sample = _takefullsample(dag, undecided, size=fullsamplesize)
+        else:
+            # use even cheaper initial sample
+            ui.debug("taking quick initial sample\n")
+            sample = _takequicksample(dag, undecided, size=initialsamplesize,
+                                      initial=True)
+
+        roundtrips += 1
+        ui.progress(_('searching'), roundtrips, unit=_('queries'))
+        ui.debug("query %i; still undecided: %i, sample size is: %i\n"
+                 % (roundtrips, len(undecided), len(sample)))
+        # indices between sample and externalized version must match
+        sample = list(sample)
+        yesno = remote.known(dag.externalizeall(sample))
+        full = True
+
+    result = dag.headsetofconnecteds(common)
+    ui.progress(_('searching'), None)
+    ui.debug("%d total queries\n" % roundtrips)
+
+    if not result and srvheadhashes != [nullid]:
+        if abortwhenunrelated:
+            raise util.Abort(_("repository is unrelated"))
+        else:
+            ui.warn(_("warning: repository is unrelated\n"))
+        return (set([nullid]), True, srvheadhashes,)
+
+    return (dag.externalizeall(result), True, srvheadhashes,)
--- a/mercurial/simplemerge.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/simplemerge.py	Sat Jun 18 17:03:01 2011 -0500
@@ -18,7 +18,7 @@
 # s: "i hate that."
 
 from i18n import _
-import util, mdiff
+import scmutil, util, mdiff
 import sys, os
 
 class CantReprocessAndShowBase(Exception):
@@ -211,7 +211,7 @@
         Method is as follows:
 
         The two sequences align only on regions which match the base
-        and both descendents.  These are found by doing a two-way diff
+        and both descendants.  These are found by doing a two-way diff
         of each one against the base, and then finding the
         intersections between those regions.  These "sync regions"
         are by definition unchanged in both and easily dealt with.
@@ -315,7 +315,7 @@
     mismatch_region = staticmethod(mismatch_region)
 
     def find_sync_regions(self):
-        """Return a list of sync regions, where both descendents match the base.
+        """Return a list of sync regions, where both descendants match the base.
 
         Generates a list of (base1, base2, a1, a2, b1, b2).  There is
         always a zero-length sync region at the end of all the files.
@@ -432,7 +432,7 @@
 
     local = os.path.realpath(local)
     if not opts.get('print'):
-        opener = util.opener(os.path.dirname(local))
+        opener = scmutil.opener(os.path.dirname(local))
         out = opener(os.path.basename(local), "w", atomictemp=True)
     else:
         out = sys.stdout
--- a/mercurial/sshrepo.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/sshrepo.py	Sat Jun 18 17:03:01 2011 -0500
@@ -7,7 +7,6 @@
 
 from i18n import _
 import util, error, wireproto
-import re
 
 class remotelock(object):
     def __init__(self, repo):
@@ -20,20 +19,20 @@
             self.release()
 
 class sshrepository(wireproto.wirerepository):
-    def __init__(self, ui, path, create=0):
+    def __init__(self, ui, path, create=False):
         self._url = path
         self.ui = ui
 
-        m = re.match(r'^ssh://(([^@]+)@)?([^:/]+)(:(\d+))?(/(.*))?$', path)
-        if not m:
+        u = util.url(path, parsequery=False, parsefragment=False)
+        if u.scheme != 'ssh' or not u.host or u.path is None:
             self._abort(error.RepoError(_("couldn't parse location %s") % path))
 
-        self.user = m.group(2)
-        if self.user and ':' in self.user:
+        self.user = u.user
+        if u.passwd is not None:
             self._abort(error.RepoError(_("password in URL not supported")))
-        self.host = m.group(3)
-        self.port = m.group(5)
-        self.path = m.group(7) or "."
+        self.host = u.host
+        self.port = u.port
+        self.path = u.path or "."
 
         sshcmd = self.ui.config("ui", "ssh", "ssh")
         remotecmd = self.ui.config("ui", "remotecmd", "hg")
@@ -89,7 +88,7 @@
                 break
 
     def readerr(self):
-        while 1:
+        while True:
             size = util.fstat(self.pipee).st_size
             if size == 0:
                 break
@@ -119,9 +118,24 @@
     def _callstream(self, cmd, **args):
         self.ui.debug("sending %s command\n" % cmd)
         self.pipeo.write("%s\n" % cmd)
-        for k, v in sorted(args.iteritems()):
+        _func, names = wireproto.commands[cmd]
+        keys = names.split()
+        wireargs = {}
+        for k in keys:
+            if k == '*':
+                wireargs['*'] = args
+                break
+            else:
+                wireargs[k] = args[k]
+                del args[k]
+        for k, v in sorted(wireargs.iteritems()):
             self.pipeo.write("%s %d\n" % (k, len(v)))
-            self.pipeo.write(v)
+            if isinstance(v, dict):
+                for dk, dv in v.iteritems():
+                    self.pipeo.write("%s %d\n" % (dk, len(dv)))
+                    self.pipeo.write(dv)
+            else:
+                self.pipeo.write(v)
         self.pipeo.flush()
 
         return self.pipei
@@ -134,7 +148,7 @@
         r = self._call(cmd, **args)
         if r:
             return '', r
-        while 1:
+        while True:
             d = fp.read(4096)
             if not d:
                 break
@@ -153,7 +167,7 @@
         self.readerr()
         try:
             l = int(l)
-        except:
+        except ValueError:
             self._abort(error.ResponseError(_("unexpected response:"), l))
         return self.pipei.read(l)
 
@@ -172,14 +186,14 @@
     def unlock(self):
         self._call("unlock")
 
-    def addchangegroup(self, cg, source, url):
+    def addchangegroup(self, cg, source, url, lock=None):
         '''Send a changegroup to the remote server.  Return an integer
         similar to unbundle(). DEPRECATED, since it requires locking the
         remote.'''
         d = self._call("addchangegroup")
         if d:
             self._abort(error.RepoError(_("push refused: %s") % d))
-        while 1:
+        while True:
             d = cg.read(4096)
             if not d:
                 break
@@ -194,7 +208,7 @@
             return 1
         try:
             return int(r)
-        except:
+        except ValueError:
             self._abort(error.ResponseError(_("unexpected response:"), r))
 
 instance = sshrepository
--- a/mercurial/sshserver.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/sshserver.py	Sat Jun 18 17:03:01 2011 -0500
@@ -14,34 +14,34 @@
         self.ui = ui
         self.repo = repo
         self.lock = None
-        self.fin = sys.stdin
-        self.fout = sys.stdout
+        self.fin = ui.fin
+        self.fout = ui.fout
 
         hook.redirect(True)
-        sys.stdout = sys.stderr
+        ui.fout = repo.ui.fout = ui.ferr
 
         # Prevent insertion/deletion of CRs
-        util.set_binary(self.fin)
-        util.set_binary(self.fout)
+        util.setbinary(self.fin)
+        util.setbinary(self.fout)
 
     def getargs(self, args):
         data = {}
         keys = args.split()
-        count = len(keys)
         for n in xrange(len(keys)):
             argline = self.fin.readline()[:-1]
             arg, l = argline.split()
-            val = self.fin.read(int(l))
             if arg not in keys:
                 raise util.Abort("unexpected parameter %r" % arg)
             if arg == '*':
                 star = {}
-                for n in xrange(int(l)):
+                for k in xrange(int(l)):
+                    argline = self.fin.readline()[:-1]
                     arg, l = argline.split()
                     val = self.fin.read(int(l))
                     star[arg] = val
                 data['*'] = star
             else:
+                val = self.fin.read(int(l))
                 data[arg] = val
         return [data[k] for k in keys]
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mercurial/sslutil.py	Sat Jun 18 17:03:01 2011 -0500
@@ -0,0 +1,128 @@
+# sslutil.py - SSL handling for mercurial
+#
+# Copyright 2005, 2006, 2007, 2008 Matt Mackall <mpm@selenic.com>
+# Copyright 2006, 2007 Alexis S. L. Carvalho <alexis@cecm.usp.br>
+# Copyright 2006 Vadim Gelfer <vadim.gelfer@gmail.com>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2 or any later version.
+import os
+
+from mercurial import util
+from mercurial.i18n import _
+try:
+    # avoid using deprecated/broken FakeSocket in python 2.6
+    import ssl
+    ssl_wrap_socket = ssl.wrap_socket
+    CERT_REQUIRED = ssl.CERT_REQUIRED
+except ImportError:
+    CERT_REQUIRED = 2
+
+    import socket, httplib
+
+    def ssl_wrap_socket(sock, key_file, cert_file,
+                        cert_reqs=CERT_REQUIRED, ca_certs=None):
+        if ca_certs:
+            raise util.Abort(_(
+                'certificate checking requires Python 2.6'))
+
+        ssl = socket.ssl(sock, key_file, cert_file)
+        return httplib.FakeSocket(sock, ssl)
+
+def _verifycert(cert, hostname):
+    '''Verify that cert (in socket.getpeercert() format) matches hostname.
+    CRLs is not handled.
+
+    Returns error message if any problems are found and None on success.
+    '''
+    if not cert:
+        return _('no certificate received')
+    dnsname = hostname.lower()
+    def matchdnsname(certname):
+        return (certname == dnsname or
+                '.' in dnsname and certname == '*.' + dnsname.split('.', 1)[1])
+
+    san = cert.get('subjectAltName', [])
+    if san:
+        certnames = [value.lower() for key, value in san if key == 'DNS']
+        for name in certnames:
+            if matchdnsname(name):
+                return None
+        if certnames:
+            return _('certificate is for %s') % ', '.join(certnames)
+
+    # subject is only checked when subjectAltName is empty
+    for s in cert.get('subject', []):
+        key, value = s[0]
+        if key == 'commonName':
+            try:
+                # 'subject' entries are unicode
+                certname = value.lower().encode('ascii')
+            except UnicodeEncodeError:
+                return _('IDN in certificate not supported')
+            if matchdnsname(certname):
+                return None
+            return _('certificate is for %s') % certname
+    return _('no commonName or subjectAltName found in certificate')
+
+
+# CERT_REQUIRED means fetch the cert from the server all the time AND
+# validate it against the CA store provided in web.cacerts.
+#
+# We COMPLETELY ignore CERT_REQUIRED on Python <= 2.5, as it's totally
+# busted on those versions.
+
+def sslkwargs(ui, host):
+    cacerts = ui.config('web', 'cacerts')
+    hostfingerprint = ui.config('hostfingerprints', host)
+    if cacerts and not hostfingerprint:
+        cacerts = util.expandpath(cacerts)
+        if not os.path.exists(cacerts):
+            raise util.Abort(_('could not find web.cacerts: %s') % cacerts)
+        return {'ca_certs': cacerts,
+                'cert_reqs': CERT_REQUIRED,
+                }
+    return {}
+
+class validator(object):
+    def __init__(self, ui, host):
+        self.ui = ui
+        self.host = host
+
+    def __call__(self, sock):
+        host = self.host
+        cacerts = self.ui.config('web', 'cacerts')
+        hostfingerprint = self.ui.config('hostfingerprints', host)
+        if cacerts and not hostfingerprint:
+            msg = _verifycert(sock.getpeercert(), host)
+            if msg:
+                raise util.Abort(_('%s certificate error: %s '
+                                   '(use --insecure to connect '
+                                   'insecurely)') % (host, msg))
+            self.ui.debug('%s certificate successfully verified\n' % host)
+        else:
+            if getattr(sock, 'getpeercert', False):
+                peercert = sock.getpeercert(True)
+                peerfingerprint = util.sha1(peercert).hexdigest()
+                nicefingerprint = ":".join([peerfingerprint[x:x + 2]
+                    for x in xrange(0, len(peerfingerprint), 2)])
+                if hostfingerprint:
+                    if peerfingerprint.lower() != \
+                            hostfingerprint.replace(':', '').lower():
+                        raise util.Abort(_('invalid certificate for %s '
+                                           'with fingerprint %s') %
+                                         (host, nicefingerprint))
+                    self.ui.debug('%s certificate matched fingerprint %s\n' %
+                                  (host, nicefingerprint))
+                else:
+                    self.ui.warn(_('warning: %s certificate '
+                                   'with fingerprint %s not verified '
+                                   '(check hostfingerprints or web.cacerts '
+                                   'config setting)\n') %
+                                 (host, nicefingerprint))
+            else: # python 2.5 ?
+                if hostfingerprint:
+                    raise util.Abort(_("host fingerprint for %s can't be "
+                                       "verified (Python too old)") % host)
+                self.ui.warn(_("warning: certificate for %s can't be "
+                               "verified (Python too old)\n") % host)
--- a/mercurial/statichttprepo.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/statichttprepo.py	Sat Jun 18 17:03:01 2011 -0500
@@ -9,7 +9,7 @@
 
 from i18n import _
 import changelog, byterange, url, error
-import localrepo, manifest, util, store
+import localrepo, manifest, util, scmutil, store
 import urllib, urllib2, errno
 
 class httprangereader(object):
@@ -67,17 +67,17 @@
     urlopener = url.opener(ui, authinfo)
     urlopener.add_handler(byterange.HTTPRangeHandler())
 
-    def opener(base):
-        """return a function that opens files over http"""
-        p = base
-        def o(path, mode="r", atomictemp=None):
-            if 'a' in mode or 'w' in mode:
+    class statichttpopener(scmutil.abstractopener):
+        def __init__(self, base):
+            self.base = base
+
+        def __call__(self, path, mode="r", atomictemp=None):
+            if mode not in ('r', 'rb'):
                 raise IOError('Permission denied')
-            f = "/".join((p, urllib.quote(path)))
+            f = "/".join((self.base, urllib.quote(path)))
             return httprangereader(f, urlopener)
-        return o
 
-    return opener
+    return statichttpopener
 
 class statichttprepository(localrepo.localrepository):
     def __init__(self, ui, path):
@@ -85,17 +85,19 @@
         self.ui = ui
 
         self.root = path
-        self.path, authinfo = url.getauthinfo(path.rstrip('/') + "/.hg")
+        u = util.url(path.rstrip('/') + "/.hg")
+        self.path, authinfo = u.authinfo()
 
         opener = build_opener(ui, authinfo)
         self.opener = opener(self.path)
 
-        # find requirements
         try:
-            requirements = self.opener("requires").read().splitlines()
+            requirements = scmutil.readrequires(self.opener, self.supported)
         except IOError, inst:
             if inst.errno != errno.ENOENT:
                 raise
+            requirements = set()
+
             # check if it is a non-empty old-style repository
             try:
                 fp = self.opener("00changelog.i")
@@ -107,13 +109,6 @@
                 # we do not care about empty old-style repositories here
                 msg = _("'%s' does not appear to be an hg repository") % path
                 raise error.RepoError(msg)
-            requirements = []
-
-        # check them
-        for r in requirements:
-            if r not in self.supported:
-                raise error.RequirementError(
-                        _("requirement '%s' not supported") % r)
 
         # setup store
         self.store = store.store(requirements, self.path, opener)
@@ -129,7 +124,7 @@
         self._branchcachetip = None
         self.encodepats = None
         self.decodepats = None
-        self.capabilities = self.capabilities.difference(["pushkey"])
+        self.capabilities.difference_update(["pushkey"])
 
     def url(self):
         return self._url
--- a/mercurial/store.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/store.py	Sat Jun 18 17:03:01 2011 -0500
@@ -6,7 +6,7 @@
 # GNU General Public License version 2 or any later version.
 
 from i18n import _
-import osutil, util
+import osutil, scmutil, util
 import os, stat
 
 _sha = util.sha1
@@ -14,6 +14,14 @@
 # This avoids a collision between a file named foo and a dir named
 # foo.i or foo.d
 def encodedir(path):
+    '''
+    >>> encodedir('data/foo.i')
+    'data/foo.i'
+    >>> encodedir('data/foo.i/bla.i')
+    'data/foo.i.hg/bla.i'
+    >>> encodedir('data/foo.i.hg/bla.i')
+    'data/foo.i.hg.hg/bla.i'
+    '''
     if not path.startswith('data/'):
         return path
     return (path
@@ -22,6 +30,14 @@
             .replace(".d/", ".d.hg/"))
 
 def decodedir(path):
+    '''
+    >>> decodedir('data/foo.i')
+    'data/foo.i'
+    >>> decodedir('data/foo.i.hg/bla.i')
+    'data/foo.i/bla.i'
+    >>> decodedir('data/foo.i.hg.hg/bla.i')
+    'data/foo.i.hg/bla.i'
+    '''
     if not path.startswith('data/') or ".hg/" not in path:
         return path
     return (path
@@ -30,10 +46,33 @@
             .replace(".hg.hg/", ".hg/"))
 
 def _buildencodefun():
+    '''
+    >>> enc, dec = _buildencodefun()
+
+    >>> enc('nothing/special.txt')
+    'nothing/special.txt'
+    >>> dec('nothing/special.txt')
+    'nothing/special.txt'
+
+    >>> enc('HELLO')
+    '_h_e_l_l_o'
+    >>> dec('_h_e_l_l_o')
+    'HELLO'
+
+    >>> enc('hello:world?')
+    'hello~3aworld~3f'
+    >>> dec('hello~3aworld~3f')
+    'hello:world?'
+
+    >>> enc('the\x07quick\xADshot')
+    'the~07quick~adshot'
+    >>> dec('the~07quick~adshot')
+    'the\\x07quick\\xadshot'
+    '''
     e = '_'
-    win_reserved = [ord(x) for x in '\\:*?"<>|']
+    winreserved = [ord(x) for x in '\\:*?"<>|']
     cmap = dict([(chr(x), chr(x)) for x in xrange(127)])
-    for x in (range(32) + range(126, 256) + win_reserved):
+    for x in (range(32) + range(126, 256) + winreserved):
         cmap[chr(x)] = "~%02x" % x
     for x in range(ord("A"), ord("Z")+1) + [ord(e)]:
         cmap[chr(x)] = e + chr(x).lower()
@@ -57,26 +96,54 @@
 
 encodefilename, decodefilename = _buildencodefun()
 
-def _build_lower_encodefun():
-    win_reserved = [ord(x) for x in '\\:*?"<>|']
+def _buildlowerencodefun():
+    '''
+    >>> f = _buildlowerencodefun()
+    >>> f('nothing/special.txt')
+    'nothing/special.txt'
+    >>> f('HELLO')
+    'hello'
+    >>> f('hello:world?')
+    'hello~3aworld~3f'
+    >>> f('the\x07quick\xADshot')
+    'the~07quick~adshot'
+    '''
+    winreserved = [ord(x) for x in '\\:*?"<>|']
     cmap = dict([(chr(x), chr(x)) for x in xrange(127)])
-    for x in (range(32) + range(126, 256) + win_reserved):
+    for x in (range(32) + range(126, 256) + winreserved):
         cmap[chr(x)] = "~%02x" % x
     for x in range(ord("A"), ord("Z")+1):
         cmap[chr(x)] = chr(x).lower()
     return lambda s: "".join([cmap[c] for c in s])
 
-lowerencode = _build_lower_encodefun()
+lowerencode = _buildlowerencodefun()
 
-_windows_reserved_filenames = '''con prn aux nul
+_winreservednames = '''con prn aux nul
     com1 com2 com3 com4 com5 com6 com7 com8 com9
     lpt1 lpt2 lpt3 lpt4 lpt5 lpt6 lpt7 lpt8 lpt9'''.split()
 def _auxencode(path, dotencode):
+    '''
+    Encodes filenames containing names reserved by Windows or which end in
+    period or space. Does not touch other single reserved characters c.
+    Specifically, c in '\\:*?"<>|' or ord(c) <= 31 are *not* encoded here.
+    Additionally encodes space or period at the beginning, if dotencode is
+    True.
+    path is assumed to be all lowercase.
+
+    >>> _auxencode('.foo/aux.txt/txt.aux/con/prn/nul/foo.', True)
+    '~2efoo/au~78.txt/txt.aux/co~6e/pr~6e/nu~6c/foo~2e'
+    >>> _auxencode('.com1com2/lpt9.lpt4.lpt1/conprn/foo.', False)
+    '.com1com2/lp~749.lpt4.lpt1/conprn/foo~2e'
+    >>> _auxencode('foo. ', True)
+    'foo.~20'
+    >>> _auxencode(' .foo', True)
+    '~20.foo'
+    '''
     res = []
     for n in path.split('/'):
         if n:
             base = n.split('.')[0]
-            if base and (base in _windows_reserved_filenames):
+            if base and (base in _winreservednames):
                 # encode third letter ('aux' -> 'au~78')
                 ec = "~%02x" % ord(n[2])
                 n = n[0:2] + ec + n[3:]
@@ -88,9 +155,9 @@
         res.append(n)
     return '/'.join(res)
 
-MAX_PATH_LEN_IN_HGSTORE = 120
-DIR_PREFIX_LEN = 8
-_MAX_SHORTENED_DIRS_LEN = 8 * (DIR_PREFIX_LEN + 1) - 4
+_maxstorepathlen = 120
+_dirprefixlen = 8
+_maxshortdirslen = 8 * (_dirprefixlen + 1) - 4
 def _hybridencode(path, auxencode):
     '''encodes path with a length limit
 
@@ -106,17 +173,17 @@
 
     Hashed encoding (not reversible):
 
-    If the default-encoded path is longer than MAX_PATH_LEN_IN_HGSTORE, a
+    If the default-encoded path is longer than _maxstorepathlen, a
     non-reversible hybrid hashing of the path is done instead.
-    This encoding uses up to DIR_PREFIX_LEN characters of all directory
+    This encoding uses up to _dirprefixlen characters of all directory
     levels of the lowerencoded path, but not more levels than can fit into
-    _MAX_SHORTENED_DIRS_LEN.
+    _maxshortdirslen.
     Then follows the filler followed by the sha digest of the full path.
     The filler is the beginning of the basename of the lowerencoded path
     (the basename is everything after the last path separator). The filler
     is as long as possible, filling in characters from the basename until
-    the encoded path has MAX_PATH_LEN_IN_HGSTORE characters (or all chars
-    of the basename have been taken).
+    the encoded path has _maxstorepathlen characters (or all chars of the
+    basename have been taken).
     The extension (e.g. '.i' or '.d') is preserved.
 
     The string 'data/' at the beginning is replaced with 'dh/', if the hashed
@@ -128,7 +195,7 @@
     path = encodedir(path)
     ndpath = path[len('data/'):]
     res = 'data/' + auxencode(encodefilename(ndpath))
-    if len(res) > MAX_PATH_LEN_IN_HGSTORE:
+    if len(res) > _maxstorepathlen:
         digest = _sha(path).hexdigest()
         aep = auxencode(lowerencode(ndpath))
         _root, ext = os.path.splitext(aep)
@@ -136,21 +203,21 @@
         basename = parts[-1]
         sdirs = []
         for p in parts[:-1]:
-            d = p[:DIR_PREFIX_LEN]
+            d = p[:_dirprefixlen]
             if d[-1] in '. ':
                 # Windows can't access dirs ending in period or space
                 d = d[:-1] + '_'
             t = '/'.join(sdirs) + '/' + d
-            if len(t) > _MAX_SHORTENED_DIRS_LEN:
+            if len(t) > _maxshortdirslen:
                 break
             sdirs.append(d)
         dirs = '/'.join(sdirs)
         if len(dirs) > 0:
             dirs += '/'
         res = 'dh/' + dirs + digest + ext
-        space_left = MAX_PATH_LEN_IN_HGSTORE - len(res)
-        if space_left > 0:
-            filler = basename[:space_left]
+        spaceleft = _maxstorepathlen - len(res)
+        if spaceleft > 0:
+            filler = basename[:spaceleft]
             res = 'dh/' + dirs + filler + digest + ext
     return res
 
@@ -169,12 +236,12 @@
 
 class basicstore(object):
     '''base class for local repository stores'''
-    def __init__(self, path, opener):
+    def __init__(self, path, openertype):
         self.path = path
         self.createmode = _calcmode(path)
-        op = opener(self.path)
+        op = openertype(self.path)
         op.createmode = self.createmode
-        self.opener = lambda f, *args, **kw: op(encodedir(f), *args, **kw)
+        self.opener = scmutil.filteropener(op, encodedir)
 
     def join(self, f):
         return self.path + '/' + encodedir(f)
@@ -218,12 +285,12 @@
         pass
 
 class encodedstore(basicstore):
-    def __init__(self, path, opener):
+    def __init__(self, path, openertype):
         self.path = path + '/store'
         self.createmode = _calcmode(self.path)
-        op = opener(self.path)
+        op = openertype(self.path)
         op.createmode = self.createmode
-        self.opener = lambda f, *args, **kw: op(encodefilename(f), *args, **kw)
+        self.opener = scmutil.filteropener(op, encodefilename)
 
     def datafiles(self):
         for a, b, size in self._walk('data', True):
@@ -298,21 +365,27 @@
             self._load()
         return iter(self.entries)
 
+class _fncacheopener(scmutil.abstractopener):
+    def __init__(self, op, fnc, encode):
+        self.opener = op
+        self.fncache = fnc
+        self.encode = encode
+
+    def __call__(self, path, mode='r', *args, **kw):
+        if mode not in ('r', 'rb') and path.startswith('data/'):
+            self.fncache.add(path)
+        return self.opener(self.encode(path), mode, *args, **kw)
+
 class fncachestore(basicstore):
-    def __init__(self, path, opener, encode):
+    def __init__(self, path, openertype, encode):
         self.encode = encode
         self.path = path + '/store'
         self.createmode = _calcmode(self.path)
-        op = opener(self.path)
+        op = openertype(self.path)
         op.createmode = self.createmode
         fnc = fncache(op)
         self.fncache = fnc
-
-        def fncacheopener(path, mode='r', *args, **kw):
-            if mode not in ('r', 'rb') and path.startswith('data/'):
-                fnc.add(path)
-            return op(self.encode(path), mode, *args, **kw)
-        self.opener = fncacheopener
+        self.opener = _fncacheopener(op, fnc, encode)
 
     def join(self, f):
         return self.path + '/' + self.encode(f)
@@ -344,11 +417,11 @@
     def write(self):
         self.fncache.write()
 
-def store(requirements, path, opener):
+def store(requirements, path, openertype):
     if 'store' in requirements:
         if 'fncache' in requirements:
             auxencode = lambda f: _auxencode(f, 'dotencode' in requirements)
             encode = lambda f: _hybridencode(f, auxencode)
-            return fncachestore(path, opener, encode)
-        return encodedstore(path, opener)
-    return basicstore(path, opener)
+            return fncachestore(path, openertype, encode)
+        return encodedstore(path, openertype)
+    return basicstore(path, openertype)
--- a/mercurial/subrepo.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/subrepo.py	Sat Jun 18 17:03:01 2011 -0500
@@ -5,10 +5,10 @@
 # This software may be used and distributed according to the terms of the
 # GNU General Public License version 2 or any later version.
 
-import errno, os, re, xml.dom.minidom, shutil, urlparse, posixpath
+import errno, os, re, xml.dom.minidom, shutil, posixpath
 import stat, subprocess, tarfile
 from i18n import _
-import config, util, node, error, cmdutil
+import config, scmutil, util, node, error, cmdutil, bookmarks
 hg = None
 propertycache = util.propertycache
 
@@ -79,9 +79,8 @@
 
 def writestate(repo, state):
     """rewrite .hgsubstate in (outer) repo with these subrepo states"""
-    repo.wwrite('.hgsubstate',
-                ''.join(['%s %s\n' % (state[s][1], s)
-                         for s in sorted(state)]), '')
+    lines = ['%s %s\n' % (state[s][1], s) for s in sorted(state)]
+    repo.wwrite('.hgsubstate', ''.join(lines), '')
 
 def submerge(repo, wctx, mctx, actx, overwrite):
     """delegated from merge.applyupdates: merging of .hgsubstate file
@@ -137,6 +136,10 @@
         elif ld == a: # remote removed, local unchanged
             debug(s, "remote removed, remove")
             wctx.sub(s).remove()
+        elif a == nullstate: # not present in remote or ancestor
+            debug(s, "local added, keep")
+            sm[s] = l
+            continue
         else:
             if repo.ui.promptchoice(
                 _(' local changed subrepository %s which remote removed\n'
@@ -145,7 +148,7 @@
                 debug(s, "prompt remove")
                 wctx.sub(s).remove()
 
-    for s, r in s2.items():
+    for s, r in sorted(s2.items()):
         if s in s1:
             continue
         elif s not in sa:
@@ -194,26 +197,16 @@
     """return pull/push path of repo - either based on parent repo .hgsub info
     or on the top repo config. Abort or return None if no source found."""
     if hasattr(repo, '_subparent'):
-        source = repo._subsource
-        if source.startswith('/') or '://' in source:
-            return source
+        source = util.url(repo._subsource)
+        source.path = posixpath.normpath(source.path)
+        if posixpath.isabs(source.path) or source.scheme:
+            return str(source)
         parent = _abssource(repo._subparent, push, abort=False)
         if parent:
-            if '://' in parent:
-                if parent[-1] == '/':
-                    parent = parent[:-1]
-                r = urlparse.urlparse(parent + '/' + source)
-                if parent.startswith('ssh://') and not r[1]:
-                    # Python before 2.6 parses ssh:// URLs wrong
-                    host, path = r[2][2:].split('/', 1)
-                    r2 = '//%s/%s' % (host, posixpath.normpath(path))
-                else:
-                    r2 = posixpath.normpath(r[2])
-                r = urlparse.urlunparse((r[0], r[1], r2,
-                                         r[3], r[4], r[5]))
-                return r
-            else: # plain file system path
-                return posixpath.normpath(os.path.join(parent, repo._subsource))
+            parent = util.url(parent)
+            parent.path = posixpath.join(parent.path, source.path)
+            parent.path = posixpath.normpath(parent.path)
+            return str(parent)
     else: # recursion reached top repo
         if hasattr(repo, '_subtoppath'):
             return repo._subtoppath
@@ -245,7 +238,7 @@
     import hg as h
     hg = h
 
-    util.path_auditor(ctx._repo.root)(path)
+    scmutil.pathauditor(ctx._repo.root)(path)
     state = ctx.substate.get(path, nullstate)
     if state[2] not in types:
         raise util.Abort(_('unknown subrepo type %s') % state[2])
@@ -352,8 +345,11 @@
             create = True
             util.makedirs(root)
         self._repo = hg.repository(r.ui, root, create=create)
-        self._repo._subparent = r
-        self._repo._subsource = state[0]
+        self._initrepo(r, state[0], create)
+
+    def _initrepo(self, parentrepo, source, create):
+        self._repo._subparent = parentrepo
+        self._repo._subsource = source
 
         if create:
             fp = self._repo.opener("hgrc", "w", text=True)
@@ -415,7 +411,7 @@
         if r == '' and not ignoreupdate: # no state recorded
             return True
         w = self._repo[None]
-        if w.p1() != self._repo[r] and not ignoreupdate:
+        if r != w.p1().hex() and not ignoreupdate:
             # different version checked out
             return True
         return w.dirty() # working directory changed
@@ -438,15 +434,23 @@
 
     def _get(self, state):
         source, revision, kind = state
-        try:
-            self._repo.lookup(revision)
-        except error.RepoError:
+        if revision not in self._repo:
             self._repo._subsource = source
             srcurl = _abssource(self._repo)
-            self._repo.ui.status(_('pulling subrepo %s from %s\n')
-                                 % (subrelpath(self), srcurl))
-            other = hg.repository(self._repo.ui, srcurl)
-            self._repo.pull(other)
+            other = hg.peer(self._repo.ui, {}, srcurl)
+            if len(self._repo) == 0:
+                self._repo.ui.status(_('cloning subrepo %s from %s\n')
+                                     % (subrelpath(self), srcurl))
+                parentrepo = self._repo._subparent
+                shutil.rmtree(self._repo.root)
+                other, self._repo = hg.clone(self._repo._subparent.ui, {}, other,
+                                         self._repo.root, update=False)
+                self._initrepo(parentrepo, source, create=True)
+            else:
+                self._repo.ui.status(_('pulling subrepo %s from %s\n')
+                                     % (subrelpath(self), srcurl))
+                self._repo.pull(other)
+            bookmarks.updatefromremote(self._repo.ui, self._repo, other)
 
     def get(self, state, overwrite=False):
         self._get(state)
@@ -491,7 +495,7 @@
         dsturl = _abssource(self._repo, True)
         self._repo.ui.status(_('pushing subrepo %s to %s\n') %
             (subrelpath(self), dsturl))
-        other = hg.repository(self._repo.ui, dsturl)
+        other = hg.peer(self._repo.ui, {}, dsturl)
         return self._repo.push(other, force)
 
     def outgoing(self, ui, dest, opts):
@@ -522,7 +526,7 @@
         self._ctx = ctx
         self._ui = ctx._repo.ui
 
-    def _svncommand(self, commands, filename=''):
+    def _svncommand(self, commands, filename='', failok=False):
         cmd = ['svn']
         extrakw = {}
         if not self._ui.interactive():
@@ -547,15 +551,16 @@
                               universal_newlines=True, env=env, **extrakw)
         stdout, stderr = p.communicate()
         stderr = stderr.strip()
-        if p.returncode:
-            raise util.Abort(stderr or 'exited with code %d' % p.returncode)
-        if stderr:
-            self._ui.warn(stderr + '\n')
-        return stdout
+        if not failok:
+            if p.returncode:
+                raise util.Abort(stderr or 'exited with code %d' % p.returncode)
+            if stderr:
+                self._ui.warn(stderr + '\n')
+        return stdout, stderr
 
     @propertycache
     def _svnversion(self):
-        output = self._svncommand(['--version'], filename=None)
+        output, err = self._svncommand(['--version'], filename=None)
         m = re.search(r'^svn,\s+version\s+(\d+)\.(\d+)', output)
         if not m:
             raise util.Abort(_('cannot retrieve svn tool version'))
@@ -565,7 +570,7 @@
         # Get the working directory revision as well as the last
         # commit revision so we can compare the subrepo state with
         # both. We used to store the working directory one.
-        output = self._svncommand(['info', '--xml'])
+        output, err = self._svncommand(['info', '--xml'])
         doc = xml.dom.minidom.parseString(output)
         entries = doc.getElementsByTagName('entry')
         lastrev, rev = '0', '0'
@@ -584,7 +589,7 @@
         if the working directory was changed, and extchanges is
         True if any of these changes concern an external entry.
         """
-        output = self._svncommand(['status', '--xml'])
+        output, err = self._svncommand(['status', '--xml'])
         externals, changes = [], []
         doc = xml.dom.minidom.parseString(output)
         for e in doc.getElementsByTagName('entry'):
@@ -619,13 +624,13 @@
         if extchanged:
             # Do not try to commit externals
             raise util.Abort(_('cannot commit svn externals'))
-        commitinfo = self._svncommand(['commit', '-m', text])
+        commitinfo, err = self._svncommand(['commit', '-m', text])
         self._ui.status(commitinfo)
         newrev = re.search('Committed revision ([0-9]+).', commitinfo)
         if not newrev:
             raise util.Abort(commitinfo.splitlines()[-1])
         newrev = newrev.groups()[0]
-        self._ui.status(self._svncommand(['update', '-r', newrev]))
+        self._ui.status(self._svncommand(['update', '-r', newrev])[0])
         return newrev
 
     def remove(self):
@@ -659,9 +664,15 @@
         if self._svnversion >= (1, 5):
             args.append('--force')
         args.extend([state[0], '--revision', state[1]])
-        status = self._svncommand(args)
+        status, err = self._svncommand(args, failok=True)
         if not re.search('Checked out revision [0-9]+.', status):
-            raise util.Abort(status.splitlines()[-1])
+            if ('is already a working copy for a different URL' in err
+                and (self._wcchanged() == (False, False))):
+                # obstructed but clean working copy, so just blow it away.
+                self.remove()
+                self.get(state, overwrite=False)
+                return
+            raise util.Abort((status or err).splitlines()[-1])
         self._ui.status(status)
 
     def merge(self, state):
@@ -748,6 +759,12 @@
             current = None
         return current
 
+    def _gitremote(self, remote):
+        out = self._gitcommand(['remote', 'show', '-n', remote])
+        line = out.split('\n')[1]
+        i = line.index('URL: ') + len('URL: ')
+        return line[i:]
+
     def _githavelocally(self, revision):
         out, code = self._gitdir(['cat-file', '-e', revision])
         return code == 0
@@ -756,6 +773,9 @@
         base = self._gitcommand(['merge-base', r1, r2])
         return base == r1
 
+    def _gitisbare(self):
+        return self._gitcommand(['config', '--bool', 'core.bare']) == 'true'
+
     def _gitbranchmap(self):
         '''returns 2 things:
         a map from git branch to revision
@@ -801,11 +821,14 @@
 
     def _fetch(self, source, revision):
         if self._gitmissing():
-            self._ui.status(_('cloning subrepo %s\n') % self._relpath)
-            self._gitnodir(['clone', self._abssource(source), self._abspath])
+            source = self._abssource(source)
+            self._ui.status(_('cloning subrepo %s from %s\n') %
+                            (self._relpath, source))
+            self._gitnodir(['clone', source, self._abspath])
         if self._githavelocally(revision):
             return
-        self._ui.status(_('pulling subrepo %s\n') % self._relpath)
+        self._ui.status(_('pulling subrepo %s from %s\n') %
+                        (self._relpath, self._gitremote('origin')))
         # try only origin: the originally cloned repo
         self._gitcommand(['fetch'])
         if not self._githavelocally(revision):
@@ -815,6 +838,8 @@
     def dirty(self, ignoreupdate=False):
         if self._gitmissing():
             return self._state[1] != ''
+        if self._gitisbare():
+            return True
         if not ignoreupdate and self._state[1] != self._gitstate():
             # different version checked out
             return True
@@ -829,14 +854,14 @@
             return
         self._fetch(source, revision)
         # if the repo was set to be bare, unbare it
-        if self._gitcommand(['config', '--bool', 'core.bare']) == 'true':
+        if self._gitisbare():
             self._gitcommand(['config', 'core.bare', 'false'])
             if self._gitstate() == revision:
                 self._gitcommand(['reset', '--hard', 'HEAD'])
                 return
         elif self._gitstate() == revision:
             if overwrite:
-                # first reset the index to unmark new files for commit, because 
+                # first reset the index to unmark new files for commit, because
                 # reset --hard will otherwise throw away files added for commit,
                 # not just unmark them.
                 self._gitcommand(['reset', 'HEAD'])
--- a/mercurial/tags.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/tags.py	Sat Jun 18 17:03:01 2011 -0500
@@ -12,9 +12,9 @@
 
 from node import nullid, bin, hex, short
 from i18n import _
-import os.path
 import encoding
 import error
+import errno
 
 def findglobaltags(ui, repo, alltags, tagtypes):
     '''Find global tags in repo by reading .hgtags from every head that
@@ -60,15 +60,18 @@
 def readlocaltags(ui, repo, alltags, tagtypes):
     '''Read local tags in repo.  Update alltags and tagtypes.'''
     try:
-        # localtags is in the local encoding; re-encode to UTF-8 on
-        # input for consistency with the rest of this module.
-        data = repo.opener("localtags").read()
-        filetags = _readtags(
-            ui, repo, data.splitlines(), "localtags",
-            recode=encoding.fromlocal)
-        _updatetags(filetags, "local", alltags, tagtypes)
-    except IOError:
-        pass
+        data = repo.opener.read("localtags")
+    except IOError, inst:
+        if inst.errno != errno.ENOENT:
+            raise
+        return
+
+    # localtags is in the local encoding; re-encode to UTF-8 on
+    # input for consistency with the rest of this module.
+    filetags = _readtags(
+        ui, repo, data.splitlines(), "localtags",
+        recode=encoding.fromlocal)
+    _updatetags(filetags, "local", alltags, tagtypes)
 
 def _readtags(ui, repo, lines, fn, recode=None):
     '''Read tag definitions from a file (or any source of lines).
@@ -283,4 +286,7 @@
     for (name, (node, hist)) in cachetags.iteritems():
         cachefile.write("%s %s\n" % (hex(node), name))
 
-    cachefile.rename()
+    try:
+        cachefile.rename()
+    except (OSError, IOError):
+        pass
--- a/mercurial/templatefilters.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/templatefilters.py	Sat Jun 18 17:03:01 2011 -0500
@@ -8,11 +8,11 @@
 import cgi, re, os, time, urllib
 import encoding, node, util
 
-def stringify(thing):
-    '''turn nested template iterator into string.'''
-    if hasattr(thing, '__iter__') and not isinstance(thing, str):
-        return "".join([stringify(t) for t in thing if t is not None])
-    return str(thing)
+def addbreaks(text):
+    """:addbreaks: Any text. Add an XHTML "<br />" tag before the end of
+    every line except the last.
+    """
+    return text.replace('\n', '<br/>\n')
 
 agescales = [("year", 3600 * 24 * 365),
              ("month", 3600 * 24 * 30),
@@ -23,7 +23,9 @@
              ("second", 1)]
 
 def age(date):
-    '''turn a (timestamp, tzoff) tuple into an age string.'''
+    """:age: Date. Returns a human-readable date/time difference between the
+    given date/time and the current date/time.
+    """
 
     def plural(t, c):
         if c == 1:
@@ -34,18 +36,65 @@
 
     now = time.time()
     then = date[0]
+    future = False
     if then > now:
-        return 'in the future'
-
-    delta = max(1, int(now - then))
-    if delta > agescales[0][1] * 2:
-        return util.shortdate(date)
+        future = True
+        delta = max(1, int(then - now))
+        if delta > agescales[0][1] * 30:
+            return 'in the distant future'
+    else:
+        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:
+            if future:
+                return '%s from now' % fmt(t, n)
             return '%s ago' % fmt(t, n)
 
+def basename(path):
+    """:basename: Any text. Treats the text as a path, and returns the last
+    component of the path after splitting by the path separator
+    (ignoring trailing separators). For example, "foo/bar/baz" becomes
+    "baz" and "foo/bar//" becomes "bar".
+    """
+    return os.path.basename(path)
+
+def datefilter(text):
+    """:date: Date. Returns a date in a Unix date format, including the
+    timezone: "Mon Sep 04 15:13:13 2006 0700".
+    """
+    return util.datestr(text)
+
+def domain(author):
+    """: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``.
+    """
+    f = author.find('@')
+    if f == -1:
+        return ''
+    author = author[f + 1:]
+    f = author.find('>')
+    if f >= 0:
+        author = author[:f]
+    return author
+
+def email(text):
+    """:email: Any text. Extracts the first string that looks like an email
+    address. Example: ``User <user@example.com>`` becomes
+    ``user@example.com``.
+    """
+    return util.email(text)
+
+def escape(text):
+    """:escape: Any text. Replaces the special XML/XHTML characters "&", "<"
+    and ">" with XML entities.
+    """
+    return cgi.escape(text, True)
+
 para_re = None
 space_re = None
 
@@ -74,40 +123,45 @@
     return "".join([space_re.sub(' ', util.wrap(para, width=width)) + rest
                     for para, rest in findparas()])
 
+def fill68(text):
+    """:fill68: Any text. Wraps the text to fit in 68 columns."""
+    return fill(text, 68)
+
+def fill76(text):
+    """:fill76: Any text. Wraps the text to fit in 76 columns."""
+    return fill(text, 76)
+
 def firstline(text):
-    '''return the first line of text'''
+    """:firstline: Any text. Returns the first line of text."""
     try:
         return text.splitlines(True)[0].rstrip('\r\n')
     except IndexError:
         return ''
 
-def nl2br(text):
-    '''replace raw newlines with xhtml line breaks.'''
-    return text.replace('\n', '<br/>\n')
+def hexfilter(text):
+    """:hex: Any text. Convert a binary Mercurial node identifier into
+    its long hexadecimal representation.
+    """
+    return node.hex(text)
 
-def obfuscate(text):
-    text = unicode(text, encoding.encoding, 'replace')
-    return ''.join(['&#%d;' % ord(c) for c in text])
+def hgdate(text):
+    """:hgdate: Date. Returns the date as a pair of numbers: "1157407993
+    25200" (Unix timestamp, timezone offset).
+    """
+    return "%d %d" % text
 
-def domain(author):
-    '''get domain of author, or empty string if none.'''
-    f = author.find('@')
-    if f == -1:
-        return ''
-    author = author[f + 1:]
-    f = author.find('>')
-    if f >= 0:
-        author = author[:f]
-    return author
+def isodate(text):
+    """:isodate: Date. Returns the date in ISO 8601 format: "2009-08-18 13:00
+    +0200".
+    """
+    return util.datestr(text, '%Y-%m-%d %H:%M %1%2')
 
-def person(author):
-    '''get name of author, or else username.'''
-    if not '@' in author:
-        return author
-    f = author.find('<')
-    if f == -1:
-        return util.shortuser(author)
-    return author[:f].rstrip()
+def isodatesec(text):
+    """:isodatesec: Date. Returns the date in ISO 8601 format, including
+    seconds: "2009-08-18 13:00:13 +0200". See also the rfc3339date
+    filter.
+    """
+    return util.datestr(text, '%Y-%m-%d %H:%M:%S %1%2')
 
 def indent(text, prefix):
     '''indent each non-empty line of text after first with prefix.'''
@@ -124,38 +178,6 @@
                 yield '\n'
     return "".join(indenter())
 
-def permissions(flags):
-    if "l" in flags:
-        return "lrwxrwxrwx"
-    if "x" in flags:
-        return "-rwxr-xr-x"
-    return "-rw-r--r--"
-
-def xmlescape(text):
-    text = (text
-            .replace('&', '&amp;')
-            .replace('<', '&lt;')
-            .replace('>', '&gt;')
-            .replace('"', '&quot;')
-            .replace("'", '&#39;')) # &apos; invalid in HTML
-    return re.sub('[\x00-\x08\x0B\x0C\x0E-\x1F]', ' ', text)
-
-def uescape(c):
-    if ord(c) < 0x80:
-        return c
-    else:
-        return '\\u%04x' % ord(c)
-
-_escapes = [
-    ('\\', '\\\\'), ('"', '\\"'), ('\t', '\\t'), ('\n', '\\n'),
-    ('\r', '\\r'), ('\f', '\\f'), ('\b', '\\b'),
-]
-
-def jsonescape(s):
-    for k, v in _escapes:
-        s = s.replace(k, v)
-    return ''.join(uescape(c) for c in s)
-
 def json(obj):
     if obj is None or obj is False or obj is True:
         return {None: 'null', False: 'false', True: 'true'}[obj]
@@ -180,49 +202,161 @@
     else:
         raise TypeError('cannot encode type %s' % obj.__class__.__name__)
 
+def _uescape(c):
+    if ord(c) < 0x80:
+        return c
+    else:
+        return '\\u%04x' % ord(c)
+
+_escapes = [
+    ('\\', '\\\\'), ('"', '\\"'), ('\t', '\\t'), ('\n', '\\n'),
+    ('\r', '\\r'), ('\f', '\\f'), ('\b', '\\b'),
+]
+
+def jsonescape(s):
+    for k, v in _escapes:
+        s = s.replace(k, v)
+    return ''.join(_uescape(c) for c in s)
+
+def localdate(text):
+    """:localdate: Date. Converts a date to local date."""
+    return (text[0], util.makedate()[1])
+
+def nonempty(str):
+    """:nonempty: Any text. Returns '(none)' if the string is empty."""
+    return str or "(none)"
+
+def obfuscate(text):
+    """:obfuscate: Any text. Returns the input text rendered as a sequence of
+    XML entities.
+    """
+    text = unicode(text, encoding.encoding, 'replace')
+    return ''.join(['&#%d;' % ord(c) for c in text])
+
+def permissions(flags):
+    if "l" in flags:
+        return "lrwxrwxrwx"
+    if "x" in flags:
+        return "-rwxr-xr-x"
+    return "-rw-r--r--"
+
+def person(author):
+    """:person: Any text. Returns the text before an email address."""
+    if not '@' in author:
+        return author
+    f = author.find('<')
+    if f != -1:
+        return author[:f].rstrip()
+    f = author.find('@')
+    return author[:f].replace('.', ' ')
+
+def rfc3339date(text):
+    """:rfc3339date: Date. Returns a date using the Internet date format
+    specified in RFC 3339: "2009-08-18T13:00:13+02:00".
+    """
+    return util.datestr(text, "%Y-%m-%dT%H:%M:%S%1:%2")
+
+def rfc822date(text):
+    """:rfc822date: Date. Returns a date using the same format used in email
+    headers: "Tue, 18 Aug 2009 13:00:13 +0200".
+    """
+    return util.datestr(text, "%a, %d %b %Y %H:%M:%S %1%2")
+
+def short(text):
+    """:short: Changeset hash. Returns the short form of a changeset hash,
+    i.e. a 12 hexadecimal digit string.
+    """
+    return text[:12]
+
+def shortdate(text):
+    """:shortdate: Date. Returns a date like "2006-09-18"."""
+    return util.shortdate(text)
+
+def stringescape(text):
+    return text.encode('string_escape')
+
+def stringify(thing):
+    """:stringify: Any type. Turns the value into text by converting values into
+    text and concatenating them.
+    """
+    if hasattr(thing, '__iter__') and not isinstance(thing, str):
+        return "".join([stringify(t) for t in thing if t is not None])
+    return str(thing)
+
+def strip(text):
+    """:strip: Any text. Strips all leading and trailing whitespace."""
+    return text.strip()
+
 def stripdir(text):
-    '''Treat the text as path and strip a directory level, if possible.'''
+    """:stripdir: Treat the text as path and strip a directory level, if
+    possible. For example, "foo" and "foo/bar" becomes "foo".
+    """
     dir = os.path.dirname(text)
     if dir == "":
         return os.path.basename(text)
     else:
         return dir
 
-def nonempty(str):
-    return str or "(none)"
+def tabindent(text):
+    """:tabindent: Any text. Returns the text, with every line except the
+    first starting with a tab character.
+    """
+    return indent(text, '\t')
+
+def urlescape(text):
+    """:urlescape: Any text. Escapes all "special" characters. For example,
+    "foo bar" becomes "foo%20bar".
+    """
+    return urllib.quote(text)
+
+def userfilter(text):
+    """:user: Any text. Returns the user portion of an email address."""
+    return util.shortuser(text)
+
+def xmlescape(text):
+    text = (text
+            .replace('&', '&amp;')
+            .replace('<', '&lt;')
+            .replace('>', '&gt;')
+            .replace('"', '&quot;')
+            .replace("'", '&#39;')) # &apos; invalid in HTML
+    return re.sub('[\x00-\x08\x0B\x0C\x0E-\x1F]', ' ', text)
 
 filters = {
-    "addbreaks": nl2br,
-    "basename": os.path.basename,
-    "stripdir": stripdir,
+    "addbreaks": addbreaks,
     "age": age,
-    "date": lambda x: util.datestr(x),
+    "basename": basename,
+    "date": datefilter,
     "domain": domain,
-    "email": util.email,
-    "escape": lambda x: cgi.escape(x, True),
-    "fill68": lambda x: fill(x, width=68),
-    "fill76": lambda x: fill(x, width=76),
+    "email": email,
+    "escape": escape,
+    "fill68": fill68,
+    "fill76": fill76,
     "firstline": firstline,
-    "tabindent": lambda x: indent(x, '\t'),
-    "hgdate": lambda x: "%d %d" % x,
-    "isodate": lambda x: util.datestr(x, '%Y-%m-%d %H:%M %1%2'),
-    "isodatesec": lambda x: util.datestr(x, '%Y-%m-%d %H:%M:%S %1%2'),
+    "hex": hexfilter,
+    "hgdate": hgdate,
+    "isodate": isodate,
+    "isodatesec": isodatesec,
     "json": json,
     "jsonescape": jsonescape,
-    "localdate": lambda x: (x[0], util.makedate()[1]),
+    "localdate": localdate,
     "nonempty": nonempty,
     "obfuscate": obfuscate,
     "permissions": permissions,
     "person": person,
-    "rfc822date": lambda x: util.datestr(x, "%a, %d %b %Y %H:%M:%S %1%2"),
-    "rfc3339date": lambda x: util.datestr(x, "%Y-%m-%dT%H:%M:%S%1:%2"),
-    "hex": node.hex,
-    "short": lambda x: x[:12],
-    "shortdate": util.shortdate,
+    "rfc3339date": rfc3339date,
+    "rfc822date": rfc822date,
+    "short": short,
+    "shortdate": shortdate,
+    "stringescape": stringescape,
     "stringify": stringify,
-    "strip": lambda x: x.strip(),
-    "urlescape": lambda x: urllib.quote(x),
-    "user": lambda x: util.shortuser(x),
-    "stringescape": lambda x: x.encode('string_escape'),
+    "strip": strip,
+    "stripdir": stripdir,
+    "tabindent": tabindent,
+    "urlescape": urlescape,
+    "user": userfilter,
     "xmlescape": xmlescape,
 }
+
+# tell hggettext to extract docstrings from these functions:
+i18nfunctions = filters.values()
--- a/mercurial/templatekw.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/templatekw.py	Sat Jun 18 17:03:01 2011 -0500
@@ -6,7 +6,7 @@
 # GNU General Public License version 2 or any later version.
 
 from node import hex
-import encoding, patch, util, error
+import patch, util, error
 
 def showlist(name, values, plural=None, **args):
     '''expand set of values.
@@ -73,8 +73,7 @@
 
 def getfiles(repo, ctx, revcache):
     if 'files' not in revcache:
-        revcache['files'] = repo.status(ctx.parents()[0].node(),
-                                        ctx.node())[:3]
+        revcache['files'] = repo.status(ctx.p1().node(), ctx.node())[:3]
     return revcache['files']
 
 def getlatesttags(repo, ctx, cache):
@@ -143,38 +142,52 @@
 
 
 def showauthor(repo, ctx, templ, **args):
+    """:author: String. The unmodified author of the changeset."""
     return ctx.user()
 
 def showbranch(**args):
+    """:branch: String. The name of the branch on which the changeset was
+    committed.
+    """
     return args['ctx'].branch()
 
 def showbranches(**args):
+    """:branches: List of strings. The name of the branch on which the
+    changeset was committed. Will be empty if the branch name was
+    default.
+    """
     branch = args['ctx'].branch()
     if branch != 'default':
         return showlist('branch', [branch], plural='branches', **args)
 
 def showbookmarks(**args):
+    """:bookmarks: List of strings. Any bookmarks associated with the
+    changeset.
+    """
     bookmarks = args['ctx'].bookmarks()
     return showlist('bookmark', bookmarks, **args)
 
 def showchildren(**args):
+    """:children: List of strings. The children of the changeset."""
     ctx = args['ctx']
     childrevs = ['%d:%s' % (cctx, cctx) for cctx in ctx.children()]
     return showlist('children', childrevs, **args)
 
 def showdate(repo, ctx, templ, **args):
+    """:date: Date information. The date when the changeset was committed."""
     return ctx.date()
 
 def showdescription(repo, ctx, templ, **args):
+    """:desc: String. The text of the changeset description."""
     return ctx.description().strip()
 
 def showdiffstat(repo, ctx, templ, **args):
-    files, adds, removes = 0, 0, 0
-    for i in patch.diffstatdata(util.iterlines(ctx.diff())):
-        files += 1
-        adds += i[1]
-        removes += i[2]
-    return '%s: +%s/-%s' % (files, adds, removes)
+    """:diffstat: String. Statistics of changes with the following format:
+    "modified files: +added/-removed lines"
+    """
+    stats = patch.diffstatdata(util.iterlines(ctx.diff()))
+    maxname, maxtotal, adds, removes, binary = patch.diffstatsum(stats)
+    return '%s: +%s/-%s' % (len(stats), adds, removes)
 
 def showextras(**args):
     templ = args['templ']
@@ -184,10 +197,14 @@
         yield templ('extra', **args)
 
 def showfileadds(**args):
+    """:file_adds: List of strings. Files added by this changeset."""
     repo, ctx, revcache = args['repo'], args['ctx'], args['revcache']
     return showlist('file_add', getfiles(repo, ctx, revcache)[1], **args)
 
 def showfilecopies(**args):
+    """:file_copies: List of strings. Files copied in this changeset with
+    their sources.
+    """
     cache, ctx = args['cache'], args['ctx']
     copies = args['revcache'].get('copies')
     if copies is None:
@@ -207,25 +224,37 @@
 # provided before calling the templater, usually with a --copies
 # command line switch.
 def showfilecopiesswitch(**args):
+    """:file_copies_switch: List of strings. Like "file_copies" but displayed
+    only if the --copied switch is set.
+    """
     copies = args['revcache'].get('copies') or []
     c = [{'name': x[0], 'source': x[1]} for x in copies]
     return showlist('file_copy', c, plural='file_copies', **args)
 
 def showfiledels(**args):
+    """:file_dels: List of strings. Files removed by this changeset."""
     repo, ctx, revcache = args['repo'], args['ctx'], args['revcache']
     return showlist('file_del', getfiles(repo, ctx, revcache)[2], **args)
 
 def showfilemods(**args):
+    """:file_mods: List of strings. Files modified by this changeset."""
     repo, ctx, revcache = args['repo'], args['ctx'], args['revcache']
     return showlist('file_mod', getfiles(repo, ctx, revcache)[0], **args)
 
 def showfiles(**args):
+    """:files: List of strings. All files modified, added, or removed by this
+    changeset.
+    """
     return showlist('file', args['ctx'].files(), **args)
 
 def showlatesttag(repo, ctx, templ, cache, **args):
+    """:latesttag: String. Most recent global tag in the ancestors of this
+    changeset.
+    """
     return getlatesttags(repo, ctx, cache)[2]
 
 def showlatesttagdistance(repo, ctx, templ, cache, **args):
+    """:latesttagdistance: Integer. Longest path to the latest tag."""
     return getlatesttags(repo, ctx, cache)[1]
 
 def showmanifest(**args):
@@ -236,12 +265,17 @@
     return templ('manifest', **args)
 
 def shownode(repo, ctx, templ, **args):
+    """:node: String. The changeset identification hash, as a 40 hexadecimal
+    digit string.
+    """
     return ctx.hex()
 
 def showrev(repo, ctx, templ, **args):
+    """:rev: Integer. The repository-local changeset revision number."""
     return ctx.rev()
 
 def showtags(**args):
+    """:tags: List of strings. Any tags associated with the changeset."""
     return showlist('tag', args['ctx'].tags(), **args)
 
 # keywords are callables like:
@@ -276,3 +310,5 @@
     'tags': showtags,
 }
 
+# tell hggettext to extract docstrings from these functions:
+i18nfunctions = keywords.values()
--- a/mercurial/templater.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/templater.py	Sat Jun 18 17:03:01 2011 -0500
@@ -311,7 +311,7 @@
         '''Get the template for the given template name. Use a local cache.'''
         if not t in self.cache:
             try:
-                self.cache[t] = open(self.map[t][1]).read()
+                self.cache[t] = util.readfile(self.map[t][1])
             except KeyError, inst:
                 raise util.Abort(_('"%s" not in template map') % inst.args[0])
             except IOError, inst:
--- a/mercurial/templates/coal/header.tmpl	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/templates/coal/header.tmpl	Sat Jun 18 17:03:01 2011 -0500
@@ -4,3 +4,4 @@
 <link rel="icon" href="{staticurl}hgicon.png" type="image/png" />
 <meta name="robots" content="index, nofollow" />
 <link rel="stylesheet" href="{staticurl}style-coal.css" type="text/css" />
+<script type="text/javascript" src="{staticurl}mercurial.js"></script>
--- a/mercurial/templates/coal/map	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/templates/coal/map	Sat Jun 18 17:03:01 2011 -0500
@@ -23,6 +23,8 @@
 filenodelink = '<a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{file|escape}</a> '
 filenolink = '{file|escape} '
 fileellipses = '...'
+diffstatlink = ../paper/diffstat.tmpl
+diffstatnolink = ../paper/diffstat.tmpl
 changelogentry = ../paper/shortlogentry.tmpl
 searchentry = ../paper/shortlogentry.tmpl
 changeset = ../paper/changeset.tmpl
@@ -94,14 +96,12 @@
 
 filerename = '{file|escape}@'
 filelogrename = '
-  <tr>
-    <th>base:</th>
-    <td>
-      <a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">
-        {file|escape}@{node|short}
-      </a>
-    </td>
-  </tr>'
+  <span class="base">
+    base
+    <a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">
+      {file|escape}@{node|short}
+    </a>
+  </span>'
 fileannotateparent = '
   <tr>
     <td class="metatag">parent:</td>
@@ -199,7 +199,7 @@
     <td><a href="{url}{sessionvars%urlparameter}">{name|escape}</a></td>
     <td>{description}</td>
     <td>{contact|obfuscate}</td>
-    <td class="age">{lastchange|age}</td>
+    <td class="age">{lastchange|date}</td>
     <td class="indexlinks">{archives%indexarchiveentry}</td>
   </tr>\n'
 indexarchiveentry = '<a href="{url}archive/{node|short}{extension|urlescape}">&nbsp;&darr;{type|escape}</a>'
--- a/mercurial/templates/gitweb/bookmarks.tmpl	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/templates/gitweb/bookmarks.tmpl	Sat Jun 18 17:03:01 2011 -0500
@@ -8,7 +8,7 @@
 <body>
 
 <div class="page_header">
-<a href="http://mercurial.selenic.com/" title="Mercurial" style="float: right;">Mercurial</a><a href="{url}summary{sessionvars%urlparameter}">{repo|escape}</a> / bookmarks
+<a href="{logourl}" title="Mercurial" style="float: right;">Mercurial</a><a href="{url}summary{sessionvars%urlparameter}">{repo|escape}</a> / bookmarks
 </div>
 
 <div class="page_nav">
--- a/mercurial/templates/gitweb/branches.tmpl	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/templates/gitweb/branches.tmpl	Sat Jun 18 17:03:01 2011 -0500
@@ -8,7 +8,7 @@
 <body>
 
 <div class="page_header">
-<a href="http://mercurial.selenic.com/" title="Mercurial" style="float: right;">Mercurial</a><a href="{url}summary{sessionvars%urlparameter}">{repo|escape}</a> / branches
+<a href="{logourl}" title="Mercurial" style="float: right;">Mercurial</a><a href="{url}summary{sessionvars%urlparameter}">{repo|escape}</a> / branches
 </div>
 
 <div class="page_nav">
--- a/mercurial/templates/gitweb/changelog.tmpl	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/templates/gitweb/changelog.tmpl	Sat Jun 18 17:03:01 2011 -0500
@@ -8,7 +8,7 @@
 <body>
 
 <div class="page_header">
-<a href="http://mercurial.selenic.com/" title="Mercurial" style="float: right;">Mercurial</a><a href="{url}summary{sessionvars%urlparameter}">{repo|escape}</a> / changelog
+<a href="{logourl}" title="Mercurial" style="float: right;">Mercurial</a><a href="{url}summary{sessionvars%urlparameter}">{repo|escape}</a> / changelog
 </div>
 
 <form action="{url}log">
--- a/mercurial/templates/gitweb/changelogentry.tmpl	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/templates/gitweb/changelogentry.tmpl	Sat Jun 18 17:03:01 2011 -0500
@@ -1,5 +1,5 @@
 <div>
-<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}{bookmarks%bookmarktag}</span></a>
+<a class="title" href="{url}rev/{node|short}{sessionvars%urlparameter}"><span class="age">{date|date}</span>{desc|strip|firstline|escape|nonempty}<span class="logtags"> {inbranch%inbranchtag}{branches%branchtag}{tags%tagtag}{bookmarks%bookmarktag}</span></a>
 </div>
 <div class="title_text">
 <div class="log_link">
--- a/mercurial/templates/gitweb/changeset.tmpl	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/templates/gitweb/changeset.tmpl	Sat Jun 18 17:03:01 2011 -0500
@@ -8,7 +8,7 @@
 <body>
 
 <div class="page_header">
-<a href="http://mercurial.selenic.com/" title="Mercurial" style="float: right;">Mercurial</a><a href="{url}summary{sessionvars%urlparameter}">{repo|escape}</a> / changeset
+<a href="{logourl}" title="Mercurial" style="float: right;">Mercurial</a><a href="{url}summary{sessionvars%urlparameter}">{repo|escape}</a> / changeset
 </div>
 
 <div class="page_nav">
@@ -32,7 +32,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})</td></tr>
+<tr><td></td><td class="date age">{date|date}</td></tr>
 {branch%changesetbranch}
 <tr><td>changeset {rev}</td><td style="font-family:monospace">{node|short}</td></tr>
 {parent%changesetparent}
--- a/mercurial/templates/gitweb/error.tmpl	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/templates/gitweb/error.tmpl	Sat Jun 18 17:03:01 2011 -0500
@@ -8,7 +8,7 @@
 <body>
 
 <div class="page_header">
-<a href="http://mercurial.selenic.com/" title="Mercurial" style="float: right;">Mercurial</a><a href="{url}summary{sessionvars%urlparameter}">{repo|escape}</a> / error
+<a href="{logourl}" title="Mercurial" style="float: right;">Mercurial</a><a href="{url}summary{sessionvars%urlparameter}">{repo|escape}</a> / error
 </div>
 
 <div class="page_nav">
--- a/mercurial/templates/gitweb/fileannotate.tmpl	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/templates/gitweb/fileannotate.tmpl	Sat Jun 18 17:03:01 2011 -0500
@@ -8,7 +8,7 @@
 <body>
 
 <div class="page_header">
-<a href="http://mercurial.selenic.com/" title="Mercurial" style="float: right;">Mercurial</a><a href="{url}summary{sessionvars%urlparameter}">{repo|escape}</a> / annotate
+<a href="{logourl}" title="Mercurial" style="float: right;">Mercurial</a><a href="{url}summary{sessionvars%urlparameter}">{repo|escape}</a> / annotate
 </div>
 
 <div class="page_nav">
@@ -40,7 +40,7 @@
  <td>{author|obfuscate}</td></tr>
 <tr>
  <td></td>
- <td>{date|date} ({date|age})</td></tr>
+ <td class="date age">{date|date}</td></tr>
 {branch%filerevbranch}
 <tr>
  <td>changeset {rev}</td>
--- a/mercurial/templates/gitweb/filediff.tmpl	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/templates/gitweb/filediff.tmpl	Sat Jun 18 17:03:01 2011 -0500
@@ -8,7 +8,7 @@
 <body>
 
 <div class="page_header">
-<a href="http://mercurial.selenic.com/" title="Mercurial" style="float: right;">Mercurial</a><a href="{url}summary{sessionvars%urlparameter}">{repo|escape}</a> / diff
+<a href="{logourl}" title="Mercurial" style="float: right;">Mercurial</a><a href="{url}summary{sessionvars%urlparameter}">{repo|escape}</a> / diff
 </div>
 
 <div class="page_nav">
--- a/mercurial/templates/gitweb/filelog.tmpl	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/templates/gitweb/filelog.tmpl	Sat Jun 18 17:03:01 2011 -0500
@@ -8,7 +8,7 @@
 <body>
 
 <div class="page_header">
-<a href="http://mercurial.selenic.com/" title="Mercurial" style="float: right;">Mercurial</a><a href="{url}summary{sessionvars%urlparameter}">{repo|escape}</a> / file revisions
+<a href="{logourl}" title="Mercurial" style="float: right;">Mercurial</a><a href="{url}summary{sessionvars%urlparameter}">{repo|escape}</a> / file revisions
 </div>
 
 <div class="page_nav">
--- a/mercurial/templates/gitweb/filerevision.tmpl	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/templates/gitweb/filerevision.tmpl	Sat Jun 18 17:03:01 2011 -0500
@@ -8,7 +8,7 @@
 <body>
 
 <div class="page_header">
-<a href="http://mercurial.selenic.com/" title="Mercurial" style="float: right;">Mercurial</a><a href="{url}summary{sessionvars%urlparameter}">{repo|escape}</a> / file revision
+<a href="{logourl}" title="Mercurial" style="float: right;">Mercurial</a><a href="{url}summary{sessionvars%urlparameter}">{repo|escape}</a> / file revision
 </div>
 
 <div class="page_nav">
@@ -40,7 +40,7 @@
  <td>{author|obfuscate}</td></tr>
 <tr>
  <td></td>
- <td>{date|date} ({date|age})</td></tr>
+ <td class="date age">{date|date}</td></tr>
 {branch%filerevbranch}
 <tr>
  <td>changeset {rev}</td>
--- a/mercurial/templates/gitweb/footer.tmpl	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/templates/gitweb/footer.tmpl	Sat Jun 18 17:03:01 2011 -0500
@@ -1,3 +1,4 @@
+<script type="text/javascript">process_dates()</script>
 <div class="page_footer">
 <div class="page_footer_text">{repo|escape}</div>
 <div class="rss_logo">
--- a/mercurial/templates/gitweb/graph.tmpl	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/templates/gitweb/graph.tmpl	Sat Jun 18 17:03:01 2011 -0500
@@ -9,7 +9,7 @@
 <body>
 
 <div class="page_header">
-<a href="http://mercurial.selenic.com/" title="Mercurial" style="float: right;">Mercurial</a><a href="{url}summary{sessionvars%urlparameter}">{repo|escape}</a> / graph
+<a href="{logourl}" title="Mercurial" style="float: right;">Mercurial</a><a href="{url}summary{sessionvars%urlparameter}">{repo|escape}</a> / graph
 </div>
 
 <form action="{url}log">
@@ -44,7 +44,6 @@
 <ul id="graphnodes"></ul>
 </div>
 
-<script type="text/javascript" src="{staticurl}graph.js"></script>
 <script>
 <!-- hide script content
 
--- a/mercurial/templates/gitweb/header.tmpl	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/templates/gitweb/header.tmpl	Sat Jun 18 17:03:01 2011 -0500
@@ -5,4 +5,4 @@
 <link rel="icon" href="{staticurl}hgicon.png" type="image/png" />
 <meta name="robots" content="index, nofollow"/>
 <link rel="stylesheet" href="{staticurl}style-gitweb.css" type="text/css" />
-
+<script type="text/javascript" src="{staticurl}mercurial.js"></script>
--- a/mercurial/templates/gitweb/help.tmpl	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/templates/gitweb/help.tmpl	Sat Jun 18 17:03:01 2011 -0500
@@ -8,7 +8,7 @@
 <body>
 
 <div class="page_header">
-<a href="http://mercurial.selenic.com/" title="Mercurial" style="float: right;">Mercurial</a><a href="{url}summary{sessionvars%urlparameter}">{repo|escape}</a> / help
+<a href="{logourl}" title="Mercurial" style="float: right;">Mercurial</a><a href="{url}summary{sessionvars%urlparameter}">{repo|escape}</a> / help
 </div>
 
 <div class="page_nav">
--- a/mercurial/templates/gitweb/helptopics.tmpl	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/templates/gitweb/helptopics.tmpl	Sat Jun 18 17:03:01 2011 -0500
@@ -8,7 +8,7 @@
 <body>
 
 <div class="page_header">
-<a href="http://mercurial.selenic.com/" title="Mercurial" style="float: right;">Mercurial</a><a href="{url}summary{sessionvars%urlparameter}">{repo|escape}</a> / help
+<a href="{logourl}" title="Mercurial" style="float: right;">Mercurial</a><a href="{url}summary{sessionvars%urlparameter}">{repo|escape}</a> / help
 </div>
 
 <div class="page_nav">
--- a/mercurial/templates/gitweb/index.tmpl	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/templates/gitweb/index.tmpl	Sat Jun 18 17:03:01 2011 -0500
@@ -4,7 +4,7 @@
 <body>
 
 <div class="page_header">
-    <a href="http://mercurial.selenic.com/" title="Mercurial" style="float: right;">Mercurial</a>
+    <a href="{logourl}" title="Mercurial" style="float: right;">Mercurial</a>
     Repositories list
 </div>
 
--- a/mercurial/templates/gitweb/manifest.tmpl	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/templates/gitweb/manifest.tmpl	Sat Jun 18 17:03:01 2011 -0500
@@ -8,7 +8,7 @@
 <body>
 
 <div class="page_header">
-<a href="http://mercurial.selenic.com/" title="Mercurial" style="float: right;">Mercurial</a><a href="{url}summary{sessionvars%urlparameter}">{repo|escape}</a> / files
+<a href="{logourl}" title="Mercurial" style="float: right;">Mercurial</a><a href="{url}summary{sessionvars%urlparameter}">{repo|escape}</a> / files
 </div>
 
 <div class="page_nav">
--- a/mercurial/templates/gitweb/map	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/templates/gitweb/map	Sat Jun 18 17:03:01 2011 -0500
@@ -162,7 +162,7 @@
 tags = tags.tmpl
 tagentry = '
   <tr class="parity{parity}">
-    <td class="age"><i>{date|age}</i></td>
+    <td class="age"><i class="age">{date|date}</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> |
@@ -173,7 +173,7 @@
 bookmarks = bookmarks.tmpl
 bookmarkentry = '
   <tr class="parity{parity}">
-    <td class="age"><i>{date|age}</i></td>
+    <td class="age"><i class="age">{date|date}</i></td>
     <td><a class="list" href="{url}rev/{node|short}{sessionvars%urlparameter}"><b>{bookmark|escape}</b></a></td>
     <td class="link">
       <a href="{url}rev/{node|short}{sessionvars%urlparameter}">changeset</a> |
@@ -184,7 +184,7 @@
 branches = branches.tmpl
 branchentry = '
   <tr class="parity{parity}">
-    <td class="age"><i>{date|age}</i></td>
+    <td class="age"><i class="age">{date|date}</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">
@@ -228,7 +228,7 @@
 bookmarktag = '<span class="bookmarktag" title="{name}">{name}</span> '
 shortlogentry = '
   <tr class="parity{parity}">
-    <td class="age"><i>{date|age}</i></td>
+    <td class="age"><i class="age">{date|date}</i></td>
     <td><i>{author|person}</i></td>
     <td>
       <a class="list" href="{url}rev/{node|short}{sessionvars%urlparameter}">
@@ -243,7 +243,7 @@
   </tr>'
 filelogentry = '
   <tr class="parity{parity}">
-    <td class="age"><i>{date|age}</i></td>
+    <td class="age"><i class="age">{date|date}</i></td>
     <td>
       <a class="list" href="{url}rev/{node|short}{sessionvars%urlparameter}">
         <b>{desc|strip|firstline|escape|nonempty}</b>
@@ -262,7 +262,7 @@
     </td>
     <td>{description}</td>
     <td>{contact|obfuscate}</td>
-    <td class="age">{lastchange|age}</td>
+    <td class="age">{lastchange|date}</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/mercurial/templates/gitweb/notfound.tmpl	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/templates/gitweb/notfound.tmpl	Sat Jun 18 17:03:01 2011 -0500
@@ -5,7 +5,7 @@
 <body>
 
 <div class="page_header">
-<a href="http://mercurial.selenic.com/" title="Mercurial" style="float: right;">Mercurial</a> Not found: {repo|escape}
+<a href="{logourl}" title="Mercurial" style="float: right;">Mercurial</a> Not found: {repo|escape}
 </div>
 
 <div class="page_body">
--- a/mercurial/templates/gitweb/search.tmpl	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/templates/gitweb/search.tmpl	Sat Jun 18 17:03:01 2011 -0500
@@ -8,7 +8,7 @@
 <body>
 
 <div class="page_header">
-<a href="http://mercurial.selenic.com/" title="Mercurial" style="float: right;">Mercurial</a><a href="{url}summary{sessionvars%urlparameter}">{repo|escape}</a> / search
+<a href="{logourl}" title="Mercurial" style="float: right;">Mercurial</a><a href="{url}summary{sessionvars%urlparameter}">{repo|escape}</a> / search
 
 <form action="{url}log">
 {sessionvars%hiddenformentry}
--- a/mercurial/templates/gitweb/shortlog.tmpl	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/templates/gitweb/shortlog.tmpl	Sat Jun 18 17:03:01 2011 -0500
@@ -8,7 +8,7 @@
 <body>
 
 <div class="page_header">
-<a href="http://mercurial.selenic.com/" title="Mercurial" style="float: right;">Mercurial</a><a href="{url}summary{sessionvars%urlparameter}">{repo|escape}</a> / shortlog
+<a href="{logourl}" title="Mercurial" style="float: right;">Mercurial</a><a href="{url}summary{sessionvars%urlparameter}">{repo|escape}</a> / shortlog
 </div>
 
 <form action="{url}log">
--- a/mercurial/templates/gitweb/summary.tmpl	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/templates/gitweb/summary.tmpl	Sat Jun 18 17:03:01 2011 -0500
@@ -8,7 +8,7 @@
 <body>
 
 <div class="page_header">
-<a href="http://mercurial.selenic.com/" title="Mercurial" style="float: right;">Mercurial</a><a href="{url}summary{sessionvars%urlparameter}">{repo|escape}</a> / summary
+<a href="{logourl}" title="Mercurial" style="float: right;">Mercurial</a><a href="{url}summary{sessionvars%urlparameter}">{repo|escape}</a> / summary
 
 <form action="{url}log">
 {sessionvars%hiddenformentry}
@@ -50,6 +50,12 @@
 <tr class="light"><td colspan="3"><a class="list" href="{url}tags{sessionvars%urlparameter}">...</a></td></tr>
 </table>
 
+<div><a class="title" href="{url}bookmarks{sessionvars%urlparameter}">bookmarks</a></div>
+<table cellspacing="0">
+{bookmarks%bookmarkentry}
+<tr class="light"><td colspan="3"><a class="list" href="{url}bookmarks{sessionvars%urlparameter}">...</a></td></tr>
+</table>
+
 <div><a class="title" href="#">branches</a></div>
 <table cellspacing="0">
 {branches%branchentry}
--- a/mercurial/templates/gitweb/tags.tmpl	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/templates/gitweb/tags.tmpl	Sat Jun 18 17:03:01 2011 -0500
@@ -8,7 +8,7 @@
 <body>
 
 <div class="page_header">
-<a href="http://mercurial.selenic.com/" title="Mercurial" style="float: right;">Mercurial</a><a href="{url}summary{sessionvars%urlparameter}">{repo|escape}</a> / tags
+<a href="{logourl}" title="Mercurial" style="float: right;">Mercurial</a><a href="{url}summary{sessionvars%urlparameter}">{repo|escape}</a> / tags
 </div>
 
 <div class="page_nav">
--- a/mercurial/templates/map-cmdline.compact	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/templates/map-cmdline.compact	Sat Jun 18 17:03:01 2011 -0500
@@ -1,4 +1,4 @@
-changeset = '{rev}{tags}{parents}   {node|short}   {date|isodate}   {author|user}\n  {desc|firstline|strip}\n\n'
+changeset = '{rev}{tags}{bookmarks}{parents}   {node|short}   {date|isodate}   {author|user}\n  {desc|firstline|strip}\n\n'
 changeset_quiet = '{rev}:{node|short}\n'
 changeset_verbose = '{rev}{tags}{parents}   {node|short}   {date|isodate}   {author}\n  {desc|strip}\n\n'
 start_tags = '['
@@ -7,3 +7,6 @@
 start_parents = ':'
 parent = '{rev},'
 last_parent = '{rev}'
+start_bookmarks = '['
+bookmark = '{bookmark},'
+last_bookmark = '{bookmark}]'
--- a/mercurial/templates/monoblue/changelogentry.tmpl	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/templates/monoblue/changelogentry.tmpl	Sat Jun 18 17:03:01 2011 -0500
@@ -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}{bookmarks%bookmarktag}</span></a></h3>
 <ul class="changelog-entry">
-    <li class="age">{date|age}</li>
+    <li class="age">{date|date}</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/mercurial/templates/monoblue/changeset.tmpl	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/templates/monoblue/changeset.tmpl	Sat Jun 18 17:03:01 2011 -0500
@@ -38,7 +38,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}{bookmarks%bookmarktag}</span></a></h3>
-    <p class="changeset-age"><span>{date|age}</span></p>
+    <p class="changeset-age age">{date|date}</p>
 
     <dl class="overview">
         <dt>author</dt>
--- a/mercurial/templates/monoblue/fileannotate.tmpl	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/templates/monoblue/fileannotate.tmpl	Sat Jun 18 17:03:01 2011 -0500
@@ -40,7 +40,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}</span></p>
+    <p class="changeset-age age">{date|date}</p>
 
     <dl class="overview">
         <dt>author</dt>
--- a/mercurial/templates/monoblue/filerevision.tmpl	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/templates/monoblue/filerevision.tmpl	Sat Jun 18 17:03:01 2011 -0500
@@ -40,7 +40,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}</span></p>
+    <p class="changeset-age age">{date|date}</p>
 
     <dl class="overview">
         <dt>author</dt>
--- a/mercurial/templates/monoblue/footer.tmpl	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/templates/monoblue/footer.tmpl	Sat Jun 18 17:03:01 2011 -0500
@@ -1,3 +1,4 @@
+    <script type="text/javascript">process_dates()</script>
     <div class="page-footer">
         <p>Mercurial Repository: {repo|escape}</p>
         <ul class="rss-logo">
@@ -8,7 +9,7 @@
     </div>
 
     <div id="powered-by">
-        <p><a href="http://mercurial.selenic.com/" title="Mercurial"><img src="{staticurl}hglogo.png" width=75 height=90 border=0 alt="mercurial"></a></p>
+        <p><a href="{logourl}" title="Mercurial"><img src="{staticurl}hglogo.png" width=75 height=90 border=0 alt="mercurial"></a></p>
     </div>
 
     <div id="corner-top-left"></div>
--- a/mercurial/templates/monoblue/graph.tmpl	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/templates/monoblue/graph.tmpl	Sat Jun 18 17:03:01 2011 -0500
@@ -40,7 +40,6 @@
         <ul id="graphnodes"></ul>
     </div>
 
-    <script type="text/javascript" src="{staticurl}graph.js"></script>
     <script>
     <!-- hide script content
 
--- a/mercurial/templates/monoblue/header.tmpl	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/templates/monoblue/header.tmpl	Sat Jun 18 17:03:01 2011 -0500
@@ -4,3 +4,4 @@
     <link rel="icon" href="{staticurl}hgicon.png" type="image/png" />
     <meta name="robots" content="index, nofollow"/>
     <link rel="stylesheet" href="{staticurl}style-monoblue.css" type="text/css" />
+    <script type="text/javascript" src="{staticurl}mercurial.js"></script>
--- a/mercurial/templates/monoblue/index.tmpl	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/templates/monoblue/index.tmpl	Sat Jun 18 17:03:01 2011 -0500
@@ -26,7 +26,7 @@
     </div>
 
     <div id="powered-by">
-        <p><a href="http://mercurial.selenic.com/" title="Mercurial"><img src="{staticurl}hglogo.png" width=75 height=90 border=0 alt="mercurial"></a></p>
+        <p><a href="{logourl}" title="Mercurial"><img src="{staticurl}hglogo.png" width=75 height=90 border=0 alt="mercurial"></a></p>
     </div>
 
     <div id="corner-top-left"></div>
--- a/mercurial/templates/monoblue/map	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/templates/monoblue/map	Sat Jun 18 17:03:01 2011 -0500
@@ -31,8 +31,10 @@
   </tr>'
 filenolink = '
   <tr class="parity{parity}">
+    <td><a href="{url}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{file|escape}</a></td>
+    <td></td>
     <td>
-      <a href="{url}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{file|escape}</a></td><td></td><td>file |
+      file |
       annotate |
       <a href="{url}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">diff</a> |
       <a href="{url}log/{node|short}/{file|urlescape}{sessionvars%urlparameter}">revisions</a>
@@ -139,7 +141,7 @@
 tags = tags.tmpl
 tagentry = '
   <tr class="parity{parity}">
-    <td class="nowrap">{date|age}</td>
+    <td class="nowrap age">{date|date}</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> |
@@ -150,7 +152,7 @@
 bookmarks = bookmarks.tmpl
 bookmarkentry = '
   <tr class="parity{parity}">
-    <td class="nowrap">{date|age}</td>
+    <td class="nowrap date">{date|date}</td>
     <td><a href="{url}rev/{node|short}{sessionvars%urlparameter}">{bookmark|escape}</a></td>
     <td class="nowrap">
       <a href="{url}rev/{node|short}{sessionvars%urlparameter}">changeset</a> |
@@ -161,7 +163,7 @@
 branches = branches.tmpl
 branchentry = '
   <tr class="parity{parity}">
-    <td class="nowrap">{date|age}</td>
+    <td class="nowrap age">{date|date}</td>
     <td><a href="{url}shortlog/{node|short}{sessionvars%urlparameter}">{node|short}</a></td>
     <td class="{status}">{branch|escape}</td>
     <td class="nowrap">
@@ -194,7 +196,7 @@
 bookmarktag = '<span class="bookmarktag" title="{name}">{name}</span> '
 shortlogentry = '
   <tr class="parity{parity}">
-    <td class="nowrap">{date|age}</td>
+    <td class="nowrap age">{date|date}</td>
     <td>{author|person}</td>
     <td>
       <a href="{url}rev/{node|short}{sessionvars%urlparameter}">
@@ -209,7 +211,7 @@
   </tr>'
 filelogentry = '
   <tr class="parity{parity}">
-    <td class="nowrap">{date|age}</td>
+    <td class="nowrap age">{date|date}</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>
@@ -222,7 +224,7 @@
     <td><a href="{url}{sessionvars%urlparameter}">{name|escape}</a></td>
     <td>{description}</td>
     <td>{contact|obfuscate}</td>
-    <td>{lastchange|age}</td>
+    <td class="age">{lastchange|date}</td>
     <td class="indexlinks">{archives%indexarchiveentry}</td>
     <td>
       <div class="rss_logo">
--- a/mercurial/templates/monoblue/summary.tmpl	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/templates/monoblue/summary.tmpl	Sat Jun 18 17:03:01 2011 -0500
@@ -58,6 +58,14 @@
         </tr>
     </table>
 
+    <h2><a href="{url}bookmarks{sessionvars%urlparameter}">Bookmarks</a></h2>
+    <table>
+    {bookmarks%bookmarkentry}
+        <tr class="light">
+            <td colspan="3"><a class="list" href="{url}bookmarks{sessionvars%urlparameter}">...</a></td>
+        </tr>
+    </table>
+
     <h2 class="no-link">Branches</h2>
     <table>
     {branches%branchentry}
--- a/mercurial/templates/paper/bookmarks.tmpl	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/templates/paper/bookmarks.tmpl	Sat Jun 18 17:03:01 2011 -0500
@@ -10,7 +10,7 @@
 <div class="container">
 <div class="menu">
 <div class="logo">
-<a href="http://mercurial.selenic.com/">
+<a href="{logourl}">
 <img src="{staticurl}hglogo.png" alt="mercurial" /></a>
 </div>
 <ul>
--- a/mercurial/templates/paper/branches.tmpl	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/templates/paper/branches.tmpl	Sat Jun 18 17:03:01 2011 -0500
@@ -10,7 +10,7 @@
 <div class="container">
 <div class="menu">
 <div class="logo">
-<a href="http://mercurial.selenic.com/">
+<a href="{logourl}">
 <img src="{staticurl}hglogo.png" alt="mercurial" /></a>
 </div>
 <ul>
--- a/mercurial/templates/paper/changeset.tmpl	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/templates/paper/changeset.tmpl	Sat Jun 18 17:03:01 2011 -0500
@@ -5,7 +5,7 @@
 <div class="container">
 <div class="menu">
 <div class="logo">
-<a href="http://mercurial.selenic.com/">
+<a href="{logourl}">
 <img src="{staticurl}hglogo.png" alt="mercurial" /></a>
 </div>
 <ul>
@@ -40,7 +40,7 @@
 files, or words in the commit message</div>
 </form>
 
-<div class="description">{desc|strip|escape|addbreaks|nonempty}</div>
+<div class="description">{desc|strip|escape|nonempty}</div>
 
 <table id="changesetEntry">
 <tr>
@@ -49,7 +49,7 @@
 </tr>
 <tr>
  <th class="date">date</th>
- <td class="date">{date|date} ({date|age})</td></tr>
+ <td class="date age">{date|date}</td></tr>
 <tr>
  <th class="author">parents</th>
  <td class="author">{parent%changesetparent}</td>
@@ -62,6 +62,18 @@
  <th class="files">files</th>
  <td class="files">{files}</td>
 </tr>
+<tr>
+  <th class="diffstat">diffstat</th>
+  <td class="diffstat">
+    {diffsummary}
+    <a id="diffstatexpand" href="javascript:showDiffstat()"/>[<tt>+</tt>]</a>
+    <div id="diffstatdetails" style="display:none;">
+      <a href="javascript:hideDiffstat()"/>[<tt>-</tt>]</a>
+      <p>
+      <table>{diffstat}</table>
+    </div>
+  </td>
+</tr>
 </table>
 
 <div class="overflow">
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mercurial/templates/paper/diffstat.tmpl	Sat Jun 18 17:03:01 2011 -0500
@@ -0,0 +1,8 @@
+  <tr class="parity{parity}">
+    <td class="diffstat-file"><a href="#l{fileno}.1">{file|escape}</a></td>
+    <td class="diffstat-total" align="right">{total}</td>
+    <td class="diffstat-graph">
+      <span class="diffstat-add" style="width:{addpct}%;">&nbsp;</span>
+      <span class="diffstat-remove" style="width:{removepct}%;">&nbsp;</span>
+    </td>
+  </tr>
--- a/mercurial/templates/paper/error.tmpl	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/templates/paper/error.tmpl	Sat Jun 18 17:03:01 2011 -0500
@@ -6,7 +6,7 @@
 <div class="container">
 <div class="menu">
 <div class="logo">
-<a href="http://mercurial.selenic.com/">
+<a href="{logourl}">
 <img src="{staticurl}hglogo.png" width=75 height=90 border=0 alt="mercurial" /></a>
 </div>
 <ul>
--- a/mercurial/templates/paper/fileannotate.tmpl	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/templates/paper/fileannotate.tmpl	Sat Jun 18 17:03:01 2011 -0500
@@ -6,7 +6,7 @@
 <div class="container">
 <div class="menu">
 <div class="logo">
-<a href="http://mercurial.selenic.com/">
+<a href="{logourl}">
 <img src="{staticurl}hglogo.png" alt="mercurial" /></a>
 </div>
 <ul>
@@ -45,7 +45,7 @@
 files, or words in the commit message</div>
 </form>
 
-<div class="description">{desc|strip|escape|addbreaks|nonempty}</div>
+<div class="description">{desc|strip|escape|nonempty}</div>
 
 <table id="changesetEntry">
 <tr>
@@ -54,7 +54,7 @@
 </tr>
 <tr>
  <th class="date">date</th>
- <td class="date">{date|date} ({date|age})</td>
+ <td class="date age">{date|date}</td>
 </tr>
 <tr>
  <th class="author">parents</th>
--- a/mercurial/templates/paper/filediff.tmpl	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/templates/paper/filediff.tmpl	Sat Jun 18 17:03:01 2011 -0500
@@ -6,7 +6,7 @@
 <div class="container">
 <div class="menu">
 <div class="logo">
-<a href="http://mercurial.selenic.com/">
+<a href="{logourl}">
 <img src="{staticurl}hglogo.png" alt="mercurial" /></a>
 </div>
 <ul>
@@ -44,7 +44,7 @@
 files, or words in the commit message</div>
 </form>
 
-<div class="description">{desc|strip|escape|addbreaks|nonempty}</div>
+<div class="description">{desc|strip|escape|nonempty}</div>
 
 <table id="changesetEntry">
 <tr>
@@ -53,7 +53,7 @@
 </tr>
 <tr>
  <th>date</th>
- <td>{date|date} ({date|age})</td>
+ <td class="date age">{date|date}</td>
 </tr>
 <tr>
  <th>parents</th>
--- a/mercurial/templates/paper/filelog.tmpl	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/templates/paper/filelog.tmpl	Sat Jun 18 17:03:01 2011 -0500
@@ -10,7 +10,7 @@
 <div class="container">
 <div class="menu">
 <div class="logo">
-<a href="http://mercurial.selenic.com/">
+<a href="{logourl}">
 <img src="{staticurl}hglogo.png" alt="mercurial" /></a>
 </div>
 <ul>
--- a/mercurial/templates/paper/filelogentry.tmpl	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/templates/paper/filelogentry.tmpl	Sat Jun 18 17:03:01 2011 -0500
@@ -1,5 +1,5 @@
  <tr class="parity{parity}">
-  <td class="age">{date|age}</td>
+  <td class="age">{date|date}</td>
   <td class="author">{author|person}</td>
-  <td class="description"><a href="{url}rev/{node|short}{sessionvars%urlparameter}">{desc|strip|firstline|escape|nonempty}</a>{inbranch%changelogbranchname}{branches%changelogbranchhead}{tags%changelogtag}</td>
+  <td class="description"><a href="{url}rev/{node|short}{sessionvars%urlparameter}">{desc|strip|firstline|escape|nonempty}</a>{inbranch%changelogbranchname}{branches%changelogbranchhead}{tags%changelogtag}{rename%filelogrename}</td>
  </tr>
--- a/mercurial/templates/paper/filerevision.tmpl	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/templates/paper/filerevision.tmpl	Sat Jun 18 17:03:01 2011 -0500
@@ -6,7 +6,7 @@
 <div class="container">
 <div class="menu">
 <div class="logo">
-<a href="http://mercurial.selenic.com/">
+<a href="{logourl}">
 <img src="{staticurl}hglogo.png" alt="mercurial" /></a>
 </div>
 <ul>
@@ -43,7 +43,7 @@
 files, or words in the commit message</div>
 </form>
 
-<div class="description">{desc|strip|escape|addbreaks|nonempty}</div>
+<div class="description">{desc|strip|escape|nonempty}</div>
 
 <table id="changesetEntry">
 <tr>
@@ -52,7 +52,7 @@
 </tr>
 <tr>
  <th class="date">date</th>
- <td class="date">{date|date} ({date|age})</td>
+ <td class="date age">{date|date}</td>
 </tr>
 <tr>
  <th class="author">parents</th>
--- a/mercurial/templates/paper/footer.tmpl	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/templates/paper/footer.tmpl	Sat Jun 18 17:03:01 2011 -0500
@@ -1,3 +1,4 @@
+<script type="text/javascript">process_dates()</script>
 {motd}
 
 </body>
--- a/mercurial/templates/paper/graph.tmpl	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/templates/paper/graph.tmpl	Sat Jun 18 17:03:01 2011 -0500
@@ -11,7 +11,7 @@
 <div class="container">
 <div class="menu">
 <div class="logo">
-<a href="http://mercurial.selenic.com/">
+<a href="{logourl}">
 <img src="{staticurl}hglogo.png" alt="mercurial" /></a>
 </div>
 <ul>
@@ -55,7 +55,6 @@
 <ul id="graphnodes"></ul>
 </div>
 
-<script type="text/javascript" src="{staticurl}graph.js"></script>
 <script type="text/javascript">
 <!-- hide script content
 
--- a/mercurial/templates/paper/header.tmpl	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/templates/paper/header.tmpl	Sat Jun 18 17:03:01 2011 -0500
@@ -4,3 +4,4 @@
 <link rel="icon" href="{staticurl}hgicon.png" type="image/png" />
 <meta name="robots" content="index, nofollow" />
 <link rel="stylesheet" href="{staticurl}style-paper.css" type="text/css" />
+<script type="text/javascript" src="{staticurl}mercurial.js"></script>
--- a/mercurial/templates/paper/help.tmpl	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/templates/paper/help.tmpl	Sat Jun 18 17:03:01 2011 -0500
@@ -10,7 +10,7 @@
 <div class="container">
 <div class="menu">
 <div class="logo">
-<a href="http://mercurial.selenic.com/">
+<a href="{logourl}">
 <img src="{staticurl}hglogo.png" alt="mercurial" /></a>
 </div>
 <ul>
--- a/mercurial/templates/paper/helptopics.tmpl	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/templates/paper/helptopics.tmpl	Sat Jun 18 17:03:01 2011 -0500
@@ -10,7 +10,7 @@
 <div class="container">
 <div class="menu">
 <div class="logo">
-<a href="http://mercurial.selenic.com/">
+<a href="{logourl}">
 <img src="{staticurl}hglogo.png" alt="mercurial" /></a>
 </div>
 <ul>
--- a/mercurial/templates/paper/index.tmpl	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/templates/paper/index.tmpl	Sat Jun 18 17:03:01 2011 -0500
@@ -5,7 +5,7 @@
 
 <div class="container">
 <div class="menu">
-<a href="http://mercurial.selenic.com/">
+<a href="{logourl}">
 <img src="{staticurl}hglogo.png" width=75 height=90 border=0 alt="mercurial" /></a>
 </div>
 <div class="main">
--- a/mercurial/templates/paper/manifest.tmpl	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/templates/paper/manifest.tmpl	Sat Jun 18 17:03:01 2011 -0500
@@ -6,7 +6,7 @@
 <div class="container">
 <div class="menu">
 <div class="logo">
-<a href="http://mercurial.selenic.com/">
+<a href="{logourl}">
 <img src="{staticurl}hglogo.png" alt="mercurial" /></a>
 </div>
 <ul>
--- a/mercurial/templates/paper/map	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/templates/paper/map	Sat Jun 18 17:03:01 2011 -0500
@@ -22,6 +22,8 @@
 filenodelink = '<a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{file|escape}</a> '
 filenolink = '{file|escape} '
 fileellipses = '...'
+diffstatlink = diffstat.tmpl
+diffstatnolink = diffstat.tmpl
 changelogentry = shortlogentry.tmpl
 searchentry = shortlogentry.tmpl
 changeset = changeset.tmpl
@@ -93,14 +95,12 @@
 
 filerename = '{file|escape}@'
 filelogrename = '
-  <tr>
-    <th>base:</th>
-    <td>
-      <a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">
-        {file|escape}@{node|short}
-      </a>
-    </td>
-  </tr>'
+  <span class="base">
+    base
+    <a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">
+      {file|escape}@{node|short}
+    </a>
+  </span>'
 fileannotateparent = '
   <tr>
     <td class="metatag">parent:</td>
@@ -198,7 +198,7 @@
     <td><a href="{url}{sessionvars%urlparameter}">{name|escape}</a></td>
     <td>{description}</td>
     <td>{contact|obfuscate}</td>
-    <td class="age">{lastchange|age}</td>
+    <td class="age">{lastchange|date}</td>
     <td class="indexlinks">{archives%indexarchiveentry}</td>
   </tr>\n'
 indexarchiveentry = '<a href="{url}archive/{node|short}{extension|urlescape}">&nbsp;&darr;{type|escape}</a>'
--- a/mercurial/templates/paper/search.tmpl	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/templates/paper/search.tmpl	Sat Jun 18 17:03:01 2011 -0500
@@ -6,7 +6,7 @@
 <div class="container">
 <div class="menu">
 <div class="logo">
-<a href="http://mercurial.selenic.com/">
+<a href="{logourl}">
 <img src="{staticurl}hglogo.png" width=75 height=90 border=0 alt="mercurial"></a>
 </div>
 <ul>
--- a/mercurial/templates/paper/shortlog.tmpl	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/templates/paper/shortlog.tmpl	Sat Jun 18 17:03:01 2011 -0500
@@ -10,7 +10,7 @@
 <div class="container">
 <div class="menu">
 <div class="logo">
-<a href="http://mercurial.selenic.com/">
+<a href="{logourl}">
 <img src="{staticurl}hglogo.png" alt="mercurial" /></a>
 </div>
 <ul>
--- a/mercurial/templates/paper/shortlogentry.tmpl	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/templates/paper/shortlogentry.tmpl	Sat Jun 18 17:03:01 2011 -0500
@@ -1,5 +1,5 @@
  <tr class="parity{parity}">
-  <td class="age">{age(date)}</td>
+  <td class="age">{date|date}</td>
   <td class="author">{author|person}</td>
   <td class="description"><a href="{url}rev/{node|short}{sessionvars%urlparameter}">{desc|strip|firstline|escape|nonempty}</a>{inbranch%changelogbranchname}{branches%changelogbranchhead}{tags % '<span class="tag">{name|escape}</span> '}{bookmarks % '<span class="tag">{name|escape}</span> '}</td>
  </tr>
--- a/mercurial/templates/paper/tags.tmpl	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/templates/paper/tags.tmpl	Sat Jun 18 17:03:01 2011 -0500
@@ -10,7 +10,7 @@
 <div class="container">
 <div class="menu">
 <div class="logo">
-<a href="http://mercurial.selenic.com/">
+<a href="{logourl}">
 <img src="{staticurl}hglogo.png" alt="mercurial" /></a>
 </div>
 <ul>
--- a/mercurial/templates/raw/map	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/templates/raw/map	Sat Jun 18 17:03:01 2011 -0500
@@ -24,5 +24,7 @@
 indexentry = '{url}\n'
 tags = '{entries%tagentry}'
 tagentry = '{tag}	{node}\n'
+bookmarks = '{entries%bookmarkentry}'
+bookmarkentry = '{bookmark}	{node}\n'
 branches = '{entries%branchentry}'
 branchentry = '{branch}	{node}	{status}\n'
--- a/mercurial/templates/spartan/changelogentry.tmpl	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/templates/spartan/changelogentry.tmpl	Sat Jun 18 17:03:01 2011 -0500
@@ -1,6 +1,6 @@
 <table class="logEntry parity{parity}">
  <tr>
-  <th class="age">{date|age}:</th>
+  <th><span class="age">{date|date}</span>:</th>
   <th class="firstline">{desc|strip|firstline|escape|nonempty}</th>
  </tr>
  <tr>
--- a/mercurial/templates/spartan/changeset.tmpl	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/templates/spartan/changeset.tmpl	Sat Jun 18 17:03:01 2011 -0500
@@ -31,7 +31,7 @@
 </tr>
 <tr>
  <th class="date">date:</th>
- <td class="date">{date|date} ({date|age})</td>
+ <td class="date age">{date|date}</td>
 </tr>
 <tr>
  <th class="files">files:</th>
--- a/mercurial/templates/spartan/fileannotate.tmpl	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/templates/spartan/fileannotate.tmpl	Sat Jun 18 17:03:01 2011 -0500
@@ -30,7 +30,7 @@
  <td>{author|obfuscate}</td></tr>
 <tr>
  <td class="metatag">date:</td>
- <td>{date|date} ({date|age})</td>
+ <td class="date age">{date|date}</td>
 </tr>
 <tr>
  <td class="metatag">permissions:</td>
--- a/mercurial/templates/spartan/filelogentry.tmpl	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/templates/spartan/filelogentry.tmpl	Sat Jun 18 17:03:01 2011 -0500
@@ -1,6 +1,6 @@
 <table class="logEntry parity{parity}">
  <tr>
-  <th class="age">{date|age}:</th>
+  <th><span class="age">{date|date}</span>:</th>
   <th class="firstline"><a href="{url}rev/{node|short}{sessionvars%urlparameter}">{desc|strip|firstline|escape|nonempty}</a></th>
  </tr>
  <tr>
--- a/mercurial/templates/spartan/filerevision.tmpl	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/templates/spartan/filerevision.tmpl	Sat Jun 18 17:03:01 2011 -0500
@@ -30,7 +30,7 @@
  <td>{author|obfuscate}</td></tr>
 <tr>
  <td class="metatag">date:</td>
- <td>{date|date} ({date|age})</td></tr>
+ <td class="date age">{date|date}</td></tr>
 <tr>
  <td class="metatag">permissions:</td>
  <td>{permissions|permissions}</td></tr>
--- a/mercurial/templates/spartan/footer.tmpl	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/templates/spartan/footer.tmpl	Sat Jun 18 17:03:01 2011 -0500
@@ -1,6 +1,7 @@
+<script type="text/javascript">process_dates()</script>
 {motd}
 <div class="logo">
-<a href="http://mercurial.selenic.com/">
+<a href="{logourl}">
 <img src="{staticurl}hglogo.png" width=75 height=90 border=0 alt="mercurial"></a>
 </div>
 
--- a/mercurial/templates/spartan/graph.tmpl	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/templates/spartan/graph.tmpl	Sat Jun 18 17:03:01 2011 -0500
@@ -36,7 +36,6 @@
 <ul id="graphnodes"></ul>
 </div>
 
-<script type="text/javascript" src="{staticurl}graph.js"></script>
 <script type="text/javascript">
 <!-- hide script content
 
--- a/mercurial/templates/spartan/header.tmpl	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/templates/spartan/header.tmpl	Sat Jun 18 17:03:01 2011 -0500
@@ -4,3 +4,4 @@
 <link rel="icon" href="{staticurl}hgicon.png" type="image/png">
 <meta name="robots" content="index, nofollow" />
 <link rel="stylesheet" href="{staticurl}style.css" type="text/css" />
+<script type="text/javascript" src="{staticurl}mercurial.js"></script>
--- a/mercurial/templates/spartan/map	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/templates/spartan/map	Sat Jun 18 17:03:01 2011 -0500
@@ -168,7 +168,7 @@
     <td><a href="{url}{sessionvars%urlparameter}">{name|escape}</a></td>
     <td>{description}</td>
     <td>{contact|obfuscate}</td>
-    <td class="age">{lastchange|age}</td>
+    <td class="age">{lastchange|date}</td>
     <td class="indexlinks">
       <a href="{url}rss-log">RSS</a>
       <a href="{url}atom-log">Atom</a>
--- a/mercurial/templates/spartan/shortlogentry.tmpl	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/templates/spartan/shortlogentry.tmpl	Sat Jun 18 17:03:01 2011 -0500
@@ -1,6 +1,6 @@
 <table class="slogEntry parity{parity}">
  <tr>
-  <td class="age">{date|age}</td>
+  <td class="age">{date|date}</td>
   <td class="author">{author|person}</td>
   <td class="node"><a href="{url}rev/{node|short}{sessionvars%urlparameter}">{desc|strip|firstline|escape|nonempty}</a></td>
  </tr>
--- a/mercurial/templates/static/graph.js	Wed Jun 01 16:32:48 2011 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,137 +0,0 @@
-// branch_renderer.js - Rendering of branch DAGs on the client side
-//
-// Copyright 2008 Dirkjan Ochtman <dirkjan AT ochtman DOT nl>
-// Copyright 2006 Alexander Schremmer <alex AT alexanderweb DOT de>
-//
-// derived from code written by Scott James Remnant <scott@ubuntu.com>
-// Copyright 2005 Canonical Ltd.
-//
-// This software may be used and distributed according to the terms
-// of the GNU General Public License, incorporated herein by reference.
-
-var colors = [
-	[ 1.0, 0.0, 0.0 ],
-	[ 1.0, 1.0, 0.0 ],
-	[ 0.0, 1.0, 0.0 ],
-	[ 0.0, 1.0, 1.0 ],
-	[ 0.0, 0.0, 1.0 ],
-	[ 1.0, 0.0, 1.0 ]
-];
-
-function Graph() {
-	
-	this.canvas = document.getElementById('graph');
-	if (navigator.userAgent.indexOf('MSIE') >= 0) this.canvas = window.G_vmlCanvasManager.initElement(this.canvas);
-	this.ctx = this.canvas.getContext('2d');
-	this.ctx.strokeStyle = 'rgb(0, 0, 0)';
-	this.ctx.fillStyle = 'rgb(0, 0, 0)';
-	this.cur = [0, 0];
-	this.line_width = 3;
-	this.bg = [0, 4];
-	this.cell = [2, 0];
-	this.columns = 0;
-	this.revlink = '';
-	
-	this.scale = function(height) {
-		this.bg_height = height;
-		this.box_size = Math.floor(this.bg_height / 1.2);
-		this.cell_height = this.box_size;
-	}
-	
-	function colorPart(num) {
-		num *= 255
-		num = num < 0 ? 0 : num;
-		num = num > 255 ? 255 : num;
-		var digits = Math.round(num).toString(16);
-		if (num < 16) {
-			return '0' + digits;
-		} else {
-			return digits;
-		}
-	}
-
-	this.setColor = function(color, bg, fg) {
-		
-		// Set the colour.
-		//
-		// Picks a distinct colour based on an internal wheel; the bg
-		// parameter provides the value that should be assigned to the 'zero'
-		// colours and the fg parameter provides the multiplier that should be
-		// applied to the foreground colours.
-		
-		color %= colors.length;
-		var red = (colors[color][0] * fg) || bg;
-		var green = (colors[color][1] * fg) || bg;
-		var blue = (colors[color][2] * fg) || bg;
-		red = Math.round(red * 255);
-		green = Math.round(green * 255);
-		blue = Math.round(blue * 255);
-		var s = 'rgb(' + red + ', ' + green + ', ' + blue + ')';
-		this.ctx.strokeStyle = s;
-		this.ctx.fillStyle = s;
-		return s;
-		
-	}
-
-	this.render = function(data) {
-		
-		var backgrounds = '';
-		var nodedata = '';
-		
-		for (var i in data) {
-			
-			var parity = i % 2;
-			this.cell[1] += this.bg_height;
-			this.bg[1] += this.bg_height;
-			
-			var cur = data[i];
-			var node = cur[1];
-			var edges = cur[2];
-			var fold = false;
-			
-			for (var j in edges) {
-				
-				line = edges[j];
-				start = line[0];
-				end = line[1];
-				color = line[2];
-
-				if (end > this.columns || start > this.columns) {
-					this.columns += 1;
-				}
-				
-				if (start == this.columns && start > end) {
-					var fold = true;
-				}
-				
-				x0 = this.cell[0] + this.box_size * start + this.box_size / 2;
-				y0 = this.bg[1] - this.bg_height / 2;
-				x1 = this.cell[0] + this.box_size * end + this.box_size / 2;
-				y1 = this.bg[1] + this.bg_height / 2;
-				
-				this.edge(x0, y0, x1, y1, color);
-				
-			}
-			
-			// Draw the revision node in the right column
-			
-			column = node[0]
-			color = node[1]
-			
-			radius = this.box_size / 8;
-			x = this.cell[0] + this.box_size * column + this.box_size / 2;
-			y = this.bg[1] - this.bg_height / 2;
-			var add = this.vertex(x, y, color, parity, cur);
-			backgrounds += add[0];
-			nodedata += add[1];
-			
-			if (fold) this.columns -= 1;
-			
-		}
-		
-		document.getElementById('nodebgs').innerHTML += backgrounds;
-		document.getElementById('graphnodes').innerHTML += nodedata;
-		
-	}
-
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mercurial/templates/static/mercurial.js	Sat Jun 18 17:03:01 2011 -0500
@@ -0,0 +1,231 @@
+// mercurial.js - JavaScript utility functions
+//
+// Rendering of branch DAGs on the client side
+// Display of elapsed time
+// Show or hide diffstat
+//
+// Copyright 2008 Dirkjan Ochtman <dirkjan AT ochtman DOT nl>
+// Copyright 2006 Alexander Schremmer <alex AT alexanderweb DOT de>
+//
+// derived from code written by Scott James Remnant <scott@ubuntu.com>
+// Copyright 2005 Canonical Ltd.
+//
+// This software may be used and distributed according to the terms
+// of the GNU General Public License, incorporated herein by reference.
+
+var colors = [
+	[ 1.0, 0.0, 0.0 ],
+	[ 1.0, 1.0, 0.0 ],
+	[ 0.0, 1.0, 0.0 ],
+	[ 0.0, 1.0, 1.0 ],
+	[ 0.0, 0.0, 1.0 ],
+	[ 1.0, 0.0, 1.0 ]
+];
+
+function Graph() {
+	
+	this.canvas = document.getElementById('graph');
+	if (navigator.userAgent.indexOf('MSIE') >= 0) this.canvas = window.G_vmlCanvasManager.initElement(this.canvas);
+	this.ctx = this.canvas.getContext('2d');
+	this.ctx.strokeStyle = 'rgb(0, 0, 0)';
+	this.ctx.fillStyle = 'rgb(0, 0, 0)';
+	this.cur = [0, 0];
+	this.line_width = 3;
+	this.bg = [0, 4];
+	this.cell = [2, 0];
+	this.columns = 0;
+	this.revlink = '';
+	
+	this.scale = function(height) {
+		this.bg_height = height;
+		this.box_size = Math.floor(this.bg_height / 1.2);
+		this.cell_height = this.box_size;
+	}
+	
+	function colorPart(num) {
+		num *= 255
+		num = num < 0 ? 0 : num;
+		num = num > 255 ? 255 : num;
+		var digits = Math.round(num).toString(16);
+		if (num < 16) {
+			return '0' + digits;
+		} else {
+			return digits;
+		}
+	}
+
+	this.setColor = function(color, bg, fg) {
+		
+		// Set the colour.
+		//
+		// Picks a distinct colour based on an internal wheel; the bg
+		// parameter provides the value that should be assigned to the 'zero'
+		// colours and the fg parameter provides the multiplier that should be
+		// applied to the foreground colours.
+		
+		color %= colors.length;
+		var red = (colors[color][0] * fg) || bg;
+		var green = (colors[color][1] * fg) || bg;
+		var blue = (colors[color][2] * fg) || bg;
+		red = Math.round(red * 255);
+		green = Math.round(green * 255);
+		blue = Math.round(blue * 255);
+		var s = 'rgb(' + red + ', ' + green + ', ' + blue + ')';
+		this.ctx.strokeStyle = s;
+		this.ctx.fillStyle = s;
+		return s;
+		
+	}
+
+	this.render = function(data) {
+		
+		var backgrounds = '';
+		var nodedata = '';
+		
+		for (var i in data) {
+			
+			var parity = i % 2;
+			this.cell[1] += this.bg_height;
+			this.bg[1] += this.bg_height;
+			
+			var cur = data[i];
+			var node = cur[1];
+			var edges = cur[2];
+			var fold = false;
+			
+			for (var j in edges) {
+				
+				line = edges[j];
+				start = line[0];
+				end = line[1];
+				color = line[2];
+
+				if (end > this.columns || start > this.columns) {
+					this.columns += 1;
+				}
+				
+				if (start == this.columns && start > end) {
+					var fold = true;
+				}
+				
+				x0 = this.cell[0] + this.box_size * start + this.box_size / 2;
+				y0 = this.bg[1] - this.bg_height / 2;
+				x1 = this.cell[0] + this.box_size * end + this.box_size / 2;
+				y1 = this.bg[1] + this.bg_height / 2;
+				
+				this.edge(x0, y0, x1, y1, color);
+				
+			}
+			
+			// Draw the revision node in the right column
+			
+			column = node[0]
+			color = node[1]
+			
+			radius = this.box_size / 8;
+			x = this.cell[0] + this.box_size * column + this.box_size / 2;
+			y = this.bg[1] - this.bg_height / 2;
+			var add = this.vertex(x, y, color, parity, cur);
+			backgrounds += add[0];
+			nodedata += add[1];
+			
+			if (fold) this.columns -= 1;
+			
+		}
+		
+		document.getElementById('nodebgs').innerHTML += backgrounds;
+		document.getElementById('graphnodes').innerHTML += nodedata;
+		
+	}
+
+}
+
+
+process_dates = (function(document, RegExp, Math, isNaN, Date, _false, _true){
+
+	// derived from code from mercurial/templatefilter.py
+
+	var scales = {
+		'year':  365 * 24 * 60 * 60,
+		'month':  30 * 24 * 60 * 60,
+		'week':    7 * 24 * 60 * 60,
+		'day':    24 * 60 * 60,
+		'hour':   60 * 60,
+		'minute': 60,
+		'second': 1
+	};
+
+	function format(count, string){
+		var ret = count + ' ' + string;
+		if (count > 1){
+			ret = ret + 's';
+		}
+		return ret;
+	}
+
+	function age(datestr){
+		var now = new Date();
+		var once = new Date(datestr);
+
+		if (isNaN(once.getTime())){
+			// parsing error
+			return datestr;
+		}
+
+		var delta = Math.floor((now.getTime() - once.getTime()) / 1000);
+
+		var future = _false;
+		if (delta < 0){
+			future = _true;
+			delta = -delta;
+			if (delta > (30 * scales.year)){
+				return "in the distant future";
+			}
+		}
+
+		if (delta > (2 * scales.year)){
+			return once.getFullYear() + '-' + once.getMonth() + '-' + once.getDate();
+		}
+
+		for (unit in scales){
+			var s = scales[unit];
+			var n = Math.floor(delta / s);
+			if ((n >= 2) || (s == 1)){
+				if (future){
+					return format(n, unit) + ' from now';
+				} else {
+					return format(n, unit) + ' ago';
+				}
+			}
+		}
+	}
+
+	return function(){
+		var nodes = document.getElementsByTagName('*');
+		var ageclass = new RegExp('\\bage\\b');
+		var dateclass = new RegExp('\\bdate\\b');
+		for (var i=0; i<nodes.length; ++i){
+			var node = nodes[i];
+			var classes = node.className;
+			if (ageclass.test(classes)){
+				var agevalue = age(node.textContent);
+				if (dateclass.test(classes)){
+					// We want both: date + (age)
+					node.textContent += ' ('+agevalue+')';
+				} else {
+					node.textContent = agevalue;
+				}
+			}
+		}
+	}
+})(document, RegExp, Math, isNaN, Date, false, true)
+
+function showDiffstat() {
+	document.getElementById('diffstatdetails').style.display = 'inline';
+	document.getElementById('diffstatexpand').style.display = 'none';
+}
+
+function hideDiffstat() {
+	document.getElementById('diffstatdetails').style.display = 'none';
+	document.getElementById('diffstatexpand').style.display = 'inline';
+}
--- a/mercurial/templates/static/style-coal.css	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/templates/static/style-coal.css	Sat Jun 18 17:03:01 2011 -0500
@@ -103,6 +103,26 @@
 .minusline { color: #dc143c; } /* crimson */
 .atline { color: purple; }
 
+.diffstat-file {
+  white-space: nowrap;
+  font-size: 90%;
+}
+.diffstat-total {
+  white-space: nowrap;
+  font-size: 90%;
+}
+.diffstat-graph {
+  width: 100%;
+}
+.diffstat-add {
+  background-color: green;
+  float: left;
+}
+.diffstat-remove {
+  background-color: red;
+  float: left;
+}
+
 .navigate {
   text-align: right;
   font-size: 60%;
@@ -173,6 +193,7 @@
 .bigtable .age { width: 6em; }
 .bigtable .author { width: 12em; }
 .bigtable .description { }
+.bigtable .description .base { font-size: 70%; float: right; line-height: 1.66; }
 .bigtable .node { width: 5em; font-family: monospace;}
 .bigtable .lineno { width: 2em; text-align: right;}
 .bigtable .lineno a { color: #999; font-size: smaller; font-family: monospace;}
@@ -220,6 +241,8 @@
   border-left: 3px solid #999;
   margin: 1em 0 1em 0;
   padding: .3em;
+  white-space: pre;
+  font-family: monospace;
 }
 
 /* Graph */
--- a/mercurial/templates/static/style-paper.css	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/templates/static/style-paper.css	Sat Jun 18 17:03:01 2011 -0500
@@ -94,6 +94,26 @@
 .minusline { color: #dc143c; } /* crimson */
 .atline { color: purple; }
 
+.diffstat-file {
+  white-space: nowrap;
+  font-size: 90%;
+}
+.diffstat-total {
+  white-space: nowrap;
+  font-size: 90%;
+}
+.diffstat-graph {
+  width: 100%;
+}
+.diffstat-add {
+  background-color: green;
+  float: left;
+}
+.diffstat-remove {
+  background-color: red;
+  float: left;
+}
+
 .navigate {
   text-align: right;
   font-size: 60%;
@@ -164,6 +184,7 @@
 .bigtable .age { width: 7em; }
 .bigtable .author { width: 12em; }
 .bigtable .description { }
+.bigtable .description .base { font-size: 70%; float: right; line-height: 1.66; }
 .bigtable .node { width: 5em; font-family: monospace;}
 .bigtable .permissions { width: 8em; text-align: left;}
 .bigtable .size { width: 5em; text-align: right; }
@@ -209,6 +230,8 @@
   border-left: 2px solid #999;
   margin: 1em 0 1em 0;
   padding: .3em;
+  white-space: pre;
+  font-family: monospace;
 }
 
 /* Graph */
--- a/mercurial/templates/template-vars.txt	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/templates/template-vars.txt	Sat Jun 18 17:03:01 2011 -0500
@@ -29,6 +29,7 @@
 entries       the entries relevant to the page
 
 url           base url of hgweb interface
+logourl       base url of logo
 staticurl     base url for static resources
 
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mercurial/treediscovery.py	Sat Jun 18 17:03:01 2011 -0500
@@ -0,0 +1,151 @@
+# discovery.py - protocol changeset discovery functions
+#
+# Copyright 2010 Matt Mackall <mpm@selenic.com>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2 or any later version.
+
+from node import nullid, short
+from i18n import _
+import util, error
+
+def findcommonincoming(repo, remote, heads=None, force=False):
+    """Return a tuple (common, fetch, heads) used to identify the common
+    subset of nodes between repo and remote.
+
+    "common" is a list of (at least) the heads of the common subset.
+    "fetch" is a list of roots of the nodes that would be incoming, to be
+      supplied to changegroupsubset.
+    "heads" is either the supplied heads, or else the remote's heads.
+    """
+
+    m = repo.changelog.nodemap
+    search = []
+    fetch = set()
+    seen = set()
+    seenbranch = set()
+    base = set()
+
+    if not heads:
+        heads = remote.heads()
+
+    if repo.changelog.tip() == nullid:
+        base.add(nullid)
+        if heads != [nullid]:
+            return [nullid], [nullid], list(heads)
+        return [nullid], [], heads
+
+    # assume we're closer to the tip than the root
+    # and start by examining the heads
+    repo.ui.status(_("searching for changes\n"))
+
+    unknown = []
+    for h in heads:
+        if h not in m:
+            unknown.append(h)
+        else:
+            base.add(h)
+
+    if not unknown:
+        return list(base), [], list(heads)
+
+    heads = unknown
+    req = set(unknown)
+    reqcnt = 0
+
+    # search through remote branches
+    # a 'branch' here is a linear segment of history, with four parts:
+    # head, root, first parent, second parent
+    # (a branch always has two parents (or none) by definition)
+    unknown = remote.branches(unknown)
+    while unknown:
+        r = []
+        while unknown:
+            n = unknown.pop(0)
+            if n[0] in seen:
+                continue
+
+            repo.ui.debug("examining %s:%s\n"
+                          % (short(n[0]), short(n[1])))
+            if n[0] == nullid: # found the end of the branch
+                pass
+            elif n in seenbranch:
+                repo.ui.debug("branch already found\n")
+                continue
+            elif n[1] and n[1] in m: # do we know the base?
+                repo.ui.debug("found incomplete branch %s:%s\n"
+                              % (short(n[0]), short(n[1])))
+                search.append(n[0:2]) # schedule branch range for scanning
+                seenbranch.add(n)
+            else:
+                if n[1] not in seen and n[1] not in fetch:
+                    if n[2] in m and n[3] in m:
+                        repo.ui.debug("found new changeset %s\n" %
+                                      short(n[1]))
+                        fetch.add(n[1]) # earliest unknown
+                    for p in n[2:4]:
+                        if p in m:
+                            base.add(p) # latest known
+
+                for p in n[2:4]:
+                    if p not in req and p not in m:
+                        r.append(p)
+                        req.add(p)
+            seen.add(n[0])
+
+        if r:
+            reqcnt += 1
+            repo.ui.progress(_('searching'), reqcnt, unit=_('queries'))
+            repo.ui.debug("request %d: %s\n" %
+                        (reqcnt, " ".join(map(short, r))))
+            for p in xrange(0, len(r), 10):
+                for b in remote.branches(r[p:p + 10]):
+                    repo.ui.debug("received %s:%s\n" %
+                                  (short(b[0]), short(b[1])))
+                    unknown.append(b)
+
+    # do binary search on the branches we found
+    while search:
+        newsearch = []
+        reqcnt += 1
+        repo.ui.progress(_('searching'), reqcnt, unit=_('queries'))
+        for n, l in zip(search, remote.between(search)):
+            l.append(n[1])
+            p = n[0]
+            f = 1
+            for i in l:
+                repo.ui.debug("narrowing %d:%d %s\n" % (f, len(l), short(i)))
+                if i in m:
+                    if f <= 2:
+                        repo.ui.debug("found new branch changeset %s\n" %
+                                          short(p))
+                        fetch.add(p)
+                        base.add(i)
+                    else:
+                        repo.ui.debug("narrowed branch search to %s:%s\n"
+                                      % (short(p), short(i)))
+                        newsearch.append((p, i))
+                    break
+                p, f = i, f * 2
+            search = newsearch
+
+    # sanity check our fetch list
+    for f in fetch:
+        if f in m:
+            raise error.RepoError(_("already have changeset ")
+                                  + short(f[:4]))
+
+    base = list(base)
+    if base == [nullid]:
+        if force:
+            repo.ui.warn(_("warning: repository is unrelated\n"))
+        else:
+            raise util.Abort(_("repository is unrelated"))
+
+    repo.ui.debug("found new changesets starting at " +
+                 " ".join([short(f) for f in fetch]) + "\n")
+
+    repo.ui.progress(_('searching'), None)
+    repo.ui.debug("%d total queries\n" % reqcnt)
+
+    return base, list(fetch), heads
--- a/mercurial/ui.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/ui.py	Sat Jun 18 17:03:01 2011 -0500
@@ -7,7 +7,7 @@
 
 from i18n import _
 import errno, getpass, os, socket, sys, tempfile, traceback
-import config, util, error
+import config, scmutil, util, error
 
 class ui(object):
     def __init__(self, src=None):
@@ -21,6 +21,10 @@
         self._trustgroups = set()
 
         if src:
+            self.fout = src.fout
+            self.ferr = src.ferr
+            self.fin = src.fin
+
             self._tcfg = src._tcfg.copy()
             self._ucfg = src._ucfg.copy()
             self._ocfg = src._ocfg.copy()
@@ -29,10 +33,14 @@
             self.environ = src.environ
             self.fixconfig()
         else:
+            self.fout = sys.stdout
+            self.ferr = sys.stderr
+            self.fin = sys.stdin
+
             # shared read-only environment
             self.environ = os.environ
             # we always trust global config files
-            for f in util.rcpath():
+            for f in scmutil.rcpath():
                 self.readconfig(f, trust=True)
 
     def copy(self):
@@ -82,10 +90,12 @@
                       'traceback', 'verbose'):
                 if k in cfg['ui']:
                     del cfg['ui'][k]
+            for k, v in cfg.items('defaults'):
+                del cfg['defaults'][k]
+        # Don't remove aliases from the configuration if in the exceptionlist
+        if self.plain('alias'):
             for k, v in cfg.items('alias'):
                 del cfg['alias'][k]
-            for k, v in cfg.items('defaults'):
-                del cfg['defaults'][k]
 
         if trusted:
             self._tcfg.update(cfg)
@@ -111,7 +121,7 @@
                                   % (n, p, self.configsource('paths', n)))
                         p = p.replace('%%', '%')
                     p = util.expandpath(p)
-                    if '://' not in p and not os.path.isabs(p):
+                    if not util.hasscheme(p) and not os.path.isabs(p):
                         p = os.path.normpath(os.path.join(root, p))
                     c.set("paths", n, p)
 
@@ -164,6 +174,26 @@
         return v
 
     def configbool(self, section, name, default=False, untrusted=False):
+        """parse a configuration element as a boolean
+
+        >>> u = ui(); s = 'foo'
+        >>> u.setconfig(s, 'true', 'yes')
+        >>> u.configbool(s, 'true')
+        True
+        >>> u.setconfig(s, 'false', 'no')
+        >>> u.configbool(s, 'false')
+        False
+        >>> u.configbool(s, 'unknown')
+        False
+        >>> u.configbool(s, 'unknown', True)
+        True
+        >>> u.setconfig(s, 'invalid', 'somevalue')
+        >>> u.configbool(s, 'invalid')
+        Traceback (most recent call last):
+            ...
+        ConfigError: foo.invalid is not a boolean ('somevalue')
+        """
+
         v = self.config(section, name, None, untrusted)
         if v is None:
             return default
@@ -171,12 +201,47 @@
             return v
         b = util.parsebool(v)
         if b is None:
-            raise error.ConfigError(_("%s.%s not a boolean ('%s')")
+            raise error.ConfigError(_("%s.%s is not a boolean ('%s')")
                                     % (section, name, v))
         return b
 
+    def configint(self, section, name, default=None, untrusted=False):
+        """parse a configuration element as an integer
+
+        >>> u = ui(); s = 'foo'
+        >>> u.setconfig(s, 'int1', '42')
+        >>> u.configint(s, 'int1')
+        42
+        >>> u.setconfig(s, 'int2', '-42')
+        >>> u.configint(s, 'int2')
+        -42
+        >>> u.configint(s, 'unknown', 7)
+        7
+        >>> u.setconfig(s, 'invalid', 'somevalue')
+        >>> u.configint(s, 'invalid')
+        Traceback (most recent call last):
+            ...
+        ConfigError: foo.invalid is not an integer ('somevalue')
+        """
+
+        v = self.config(section, name, None, untrusted)
+        if v is None:
+            return default
+        try:
+            return int(v)
+        except ValueError:
+            raise error.ConfigError(_("%s.%s is not an integer ('%s')")
+                                    % (section, name, v))
+
     def configlist(self, section, name, default=None, untrusted=False):
-        """Return a list of comma/space separated strings"""
+        """parse a configuration element as a list of comma/space separated
+        strings
+
+        >>> u = ui(); s = 'foo'
+        >>> u.setconfig(s, 'list1', 'this,is "a small" ,test')
+        >>> u.configlist(s, 'list1')
+        ['this', 'is', 'a small', 'test']
+        """
 
         def _parse_plain(parts, s, offset):
             whitespace = False
@@ -273,20 +338,29 @@
         cfg = self._data(untrusted)
         for section in cfg.sections():
             for name, value in self.configitems(section, untrusted):
-                yield section, name, str(value).replace('\n', '\\n')
+                yield section, name, value
 
-    def plain(self):
+    def plain(self, feature=None):
         '''is plain mode active?
 
-        Plain mode means that all configuration variables which affect the
-        behavior and output of Mercurial should be ignored. Additionally, the
-        output should be stable, reproducible and suitable for use in scripts or
-        applications.
+        Plain mode means that all configuration variables which affect
+        the behavior and output of Mercurial should be
+        ignored. Additionally, the output should be stable,
+        reproducible and suitable for use in scripts or applications.
+
+        The only way to trigger plain mode is by setting either the
+        `HGPLAIN' or `HGPLAINEXCEPT' environment variables.
 
-        The only way to trigger plain mode is by setting the `HGPLAIN'
-        environment variable.
+        The return value can either be
+        - False if HGPLAIN is not set, or feature is in HGPLAINEXCEPT
+        - True otherwise
         '''
-        return 'HGPLAIN' in os.environ
+        if 'HGPLAIN' not in os.environ and 'HGPLAINEXCEPT' not in os.environ:
+            return False
+        exceptions = os.environ.get('HGPLAINEXCEPT', '').strip().split(',')
+        if feature and exceptions:
+            return feature not in exceptions
+        return True
 
     def username(self):
         """Return default username to be used in commits.
@@ -325,7 +399,7 @@
 
     def expandpath(self, loc, default=None):
         """Return repository location relative to cwd or from [paths]"""
-        if "://" in loc or os.path.isdir(os.path.join(loc, '.hg')):
+        if util.hasscheme(loc) or os.path.isdir(os.path.join(loc, '.hg')):
             return loc
 
         path = self.config('paths', loc)
@@ -369,26 +443,26 @@
             self._buffers[-1].extend([str(a) for a in args])
         else:
             for a in args:
-                sys.stdout.write(str(a))
+                self.fout.write(str(a))
 
     def write_err(self, *args, **opts):
         try:
-            if not getattr(sys.stdout, 'closed', False):
-                sys.stdout.flush()
+            if not getattr(self.fout, 'closed', False):
+                self.fout.flush()
             for a in args:
-                sys.stderr.write(str(a))
+                self.ferr.write(str(a))
             # stderr may be buffered under win32 when redirected to files,
             # including stdout.
-            if not getattr(sys.stderr, 'closed', False):
-                sys.stderr.flush()
+            if not getattr(self.ferr, 'closed', False):
+                self.ferr.flush()
         except IOError, inst:
             if inst.errno not in (errno.EPIPE, errno.EIO):
                 raise
 
     def flush(self):
-        try: sys.stdout.flush()
+        try: self.fout.flush()
         except: pass
-        try: sys.stderr.flush()
+        try: self.ferr.flush()
         except: pass
 
     def interactive(self):
@@ -407,12 +481,9 @@
         '''
         i = self.configbool("ui", "interactive", None)
         if i is None:
-            try:
-                return sys.stdin.isatty()
-            except AttributeError:
-                # some environments replace stdin without implementing isatty
-                # usually those are non-interactive
-                return False
+            # some environments replace stdin without implementing isatty
+            # usually those are non-interactive
+            return util.isatty(self.fin)
 
         return i
 
@@ -448,17 +519,14 @@
 
         i = self.configbool("ui", "formatted", None)
         if i is None:
-            try:
-                return sys.stdout.isatty()
-            except AttributeError:
-                # some environments replace stdout without implementing isatty
-                # usually those are non-interactive
-                return False
+            # some environments replace stdout without implementing isatty
+            # usually those are non-interactive
+            return util.isatty(self.fout)
 
         return i
 
     def _readline(self, prompt=''):
-        if sys.stdin.isatty():
+        if util.isatty(self.fin):
             try:
                 # magically add command line editing support, where
                 # available
@@ -468,7 +536,14 @@
                 # windows sometimes raises something other than ImportError
             except Exception:
                 pass
+
+        # instead of trying to emulate raw_input, swap our in/out
+        # with sys.stdin/out
+        old = sys.stdout, sys.stdin
+        sys.stdout, sys.stdin = self.fout, self.fin
         line = raw_input(prompt)
+        sys.stdout, sys.stdin = old
+
         # When stdin is in binary mode on Windows, it can cause
         # raw_input() to emit an extra trailing carriage return
         if os.linesep == '\r\n' and line and line[-1] == '\r':
@@ -483,7 +558,7 @@
             self.write(msg, ' ', default, "\n")
             return default
         try:
-            r = self._readline(msg + ' ')
+            r = self._readline(self.label(msg, 'ui.prompt') + ' ')
             if not r:
                 return default
             return r
--- a/mercurial/url.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/url.py	Sat Jun 18 17:03:01 2011 -0500
@@ -7,142 +7,10 @@
 # This software may be used and distributed according to the terms of the
 # GNU General Public License version 2 or any later version.
 
-import urllib, urllib2, urlparse, httplib, os, re, socket, cStringIO
-import __builtin__
+import urllib, urllib2, httplib, os, socket, cStringIO
 from i18n import _
-import keepalive, util
-
-def _urlunparse(scheme, netloc, path, params, query, fragment, url):
-    '''Handle cases where urlunparse(urlparse(x://)) doesn't preserve the "//"'''
-    result = urlparse.urlunparse((scheme, netloc, path, params, query, fragment))
-    if (scheme and
-        result.startswith(scheme + ':') and
-        not result.startswith(scheme + '://') and
-        url.startswith(scheme + '://')
-       ):
-        result = scheme + '://' + result[len(scheme + ':'):]
-    return result
-
-def hidepassword(url):
-    '''hide user credential in a url string'''
-    if url.startswith("ssh://"):
-        # urllib doesn't know about ssh urls
-        return re.sub(r'(ssh://[^/]+):[^/]+(@.*)', r'\1:***\2', url)
-    scheme, netloc, path, params, query, fragment = urlparse.urlparse(url)
-    netloc = re.sub('([^:]*):([^@]*)@(.*)', r'\1:***@\3', netloc)
-    return _urlunparse(scheme, netloc, path, params, query, fragment, url)
-
-def removeauth(url):
-    '''remove all authentication information from a url string'''
-    scheme, netloc, path, params, query, fragment = urlparse.urlparse(url)
-    netloc = netloc[netloc.find('@')+1:]
-    return _urlunparse(scheme, netloc, path, params, query, fragment, url)
-
-def netlocsplit(netloc):
-    '''split [user[:passwd]@]host[:port] into 4-tuple.'''
-
-    a = netloc.find('@')
-    if a == -1:
-        user, passwd = None, None
-    else:
-        userpass, netloc = netloc[:a], netloc[a + 1:]
-        c = userpass.find(':')
-        if c == -1:
-            user, passwd = urllib.unquote(userpass), None
-        else:
-            user = urllib.unquote(userpass[:c])
-            passwd = urllib.unquote(userpass[c + 1:])
-    c = netloc.find(':')
-    if c == -1:
-        host, port = netloc, None
-    else:
-        host, port = netloc[:c], netloc[c + 1:]
-    return host, port, user, passwd
-
-def netlocunsplit(host, port, user=None, passwd=None):
-    '''turn host, port, user, passwd into [user[:passwd]@]host[:port].'''
-    if port:
-        hostport = host + ':' + port
-    else:
-        hostport = host
-    if user:
-        quote = lambda s: urllib.quote(s, safe='')
-        if passwd:
-            userpass = quote(user) + ':' + quote(passwd)
-        else:
-            userpass = quote(user)
-        return userpass + '@' + hostport
-    return hostport
-
-def readauthforuri(ui, uri):
-    # Read configuration
-    config = dict()
-    for key, val in ui.configitems('auth'):
-        if '.' not in key:
-            ui.warn(_("ignoring invalid [auth] key '%s'\n") % key)
-            continue
-        group, setting = key.rsplit('.', 1)
-        gdict = config.setdefault(group, dict())
-        if setting in ('username', 'cert', 'key'):
-            val = util.expandpath(val)
-        gdict[setting] = val
-
-    # Find the best match
-    scheme, hostpath = uri.split('://', 1)
-    bestlen = 0
-    bestauth = None
-    for group, auth in config.iteritems():
-        prefix = auth.get('prefix')
-        if not prefix:
-            continue
-        p = prefix.split('://', 1)
-        if len(p) > 1:
-            schemes, prefix = [p[0]], p[1]
-        else:
-            schemes = (auth.get('schemes') or 'https').split()
-        if (prefix == '*' or hostpath.startswith(prefix)) and \
-            len(prefix) > bestlen and scheme in schemes:
-            bestlen = len(prefix)
-            bestauth = group, auth
-    return bestauth
-
-_safe = ('abcdefghijklmnopqrstuvwxyz'
-         'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
-         '0123456789' '_.-/')
-_safeset = None
-_hex = None
-def quotepath(path):
-    '''quote the path part of a URL
-
-    This is similar to urllib.quote, but it also tries to avoid
-    quoting things twice (inspired by wget):
-
-    >>> quotepath('abc def')
-    'abc%20def'
-    >>> quotepath('abc%20def')
-    'abc%20def'
-    >>> quotepath('abc%20 def')
-    'abc%20%20def'
-    >>> quotepath('abc def%20')
-    'abc%20def%20'
-    >>> quotepath('abc def%2')
-    'abc%20def%252'
-    >>> quotepath('abc def%')
-    'abc%20def%25'
-    '''
-    global _safeset, _hex
-    if _safeset is None:
-        _safeset = set(_safe)
-        _hex = set('abcdefABCDEF0123456789')
-    l = list(path)
-    for i in xrange(len(l)):
-        c = l[i]
-        if (c == '%' and i + 2 < len(l) and
-            l[i + 1] in _hex and l[i + 2] in _hex):
-            pass
-        elif c not in _safeset:
-            l[i] = '%%%02X' % ord(c)
-    return ''.join(l)
+import keepalive, util, sslutil
+import httpconnection as httpconnectionmod
 
 class passwordmgr(urllib2.HTTPPasswordMgrWithDefaultRealm):
     def __init__(self, ui):
@@ -158,7 +26,7 @@
             return (user, passwd)
 
         if not user:
-            res = readauthforuri(self.ui, authuri)
+            res = httpconnectionmod.readauthforuri(self.ui, authuri)
             if res:
                 group, auth = res
                 user, passwd = auth.get('username'), auth.get('password')
@@ -195,14 +63,10 @@
             if not (proxyurl.startswith('http:') or
                     proxyurl.startswith('https:')):
                 proxyurl = 'http://' + proxyurl + '/'
-            snpqf = urlparse.urlsplit(proxyurl)
-            proxyscheme, proxynetloc, proxypath, proxyquery, proxyfrag = snpqf
-            hpup = netlocsplit(proxynetloc)
-
-            proxyhost, proxyport, proxyuser, proxypasswd = hpup
-            if not proxyuser:
-                proxyuser = ui.config("http_proxy", "user")
-                proxypasswd = ui.config("http_proxy", "passwd")
+            proxy = util.url(proxyurl)
+            if not proxy.user:
+                proxy.user = ui.config("http_proxy", "user")
+                proxy.passwd = ui.config("http_proxy", "passwd")
 
             # see if we should use a proxy for this url
             no_list = ["localhost", "127.0.0.1"]
@@ -217,13 +81,10 @@
             else:
                 self.no_list = no_list
 
-            proxyurl = urlparse.urlunsplit((
-                proxyscheme, netlocunsplit(proxyhost, proxyport,
-                                                proxyuser, proxypasswd or ''),
-                proxypath, proxyquery, proxyfrag))
+            proxyurl = str(proxy)
             proxies = {'http': proxyurl, 'https': proxyurl}
             ui.debug('proxying through http://%s:%s\n' %
-                      (proxyhost, proxyport))
+                      (proxy.host, proxy.port))
         else:
             proxies = {}
 
@@ -256,48 +117,10 @@
 
         return urllib2.ProxyHandler.proxy_open(self, req, proxy, type_)
 
-class httpsendfile(object):
-    """This is a wrapper around the objects returned by python's "open".
-
-    Its purpose is to send file-like objects via HTTP and, to do so, it
-    defines a __len__ attribute to feed the Content-Length header.
-    """
-
-    def __init__(self, ui, *args, **kwargs):
-        # We can't just "self._data = open(*args, **kwargs)" here because there
-        # is an "open" function defined in this module that shadows the global
-        # one
-        self.ui = ui
-        self._data = __builtin__.open(*args, **kwargs)
-        self.seek = self._data.seek
-        self.close = self._data.close
-        self.write = self._data.write
-        self._len = os.fstat(self._data.fileno()).st_size
-        self._pos = 0
-        self._total = len(self) / 1024 * 2
-
-    def read(self, *args, **kwargs):
-        try:
-            ret = self._data.read(*args, **kwargs)
-        except EOFError:
-            self.ui.progress(_('sending'), None)
-        self._pos += len(ret)
-        # We pass double the max for total because we currently have
-        # to send the bundle twice in the case of a server that
-        # requires authentication. Since we can't know until we try
-        # once whether authentication will be required, just lie to
-        # the user and maybe the push succeeds suddenly at 50%.
-        self.ui.progress(_('sending'), self._pos / 1024,
-                         unit=_('kb'), total=self._total)
-        return ret
-
-    def __len__(self):
-        return self._len
-
 def _gen_sendfile(orgsend):
     def _sendfile(self, data):
         # send a file
-        if isinstance(data, httpsendfile):
+        if isinstance(data, httpconnectionmod.httpsendfile):
             # if auth required, some data sent twice, so rewind here
             data.seek(0)
             for chunk in util.filechunkiter(data):
@@ -309,23 +132,6 @@
 has_https = hasattr(urllib2, 'HTTPSHandler')
 if has_https:
     try:
-        # avoid using deprecated/broken FakeSocket in python 2.6
-        import ssl
-        _ssl_wrap_socket = ssl.wrap_socket
-        CERT_REQUIRED = ssl.CERT_REQUIRED
-    except ImportError:
-        CERT_REQUIRED = 2
-
-        def _ssl_wrap_socket(sock, key_file, cert_file,
-                             cert_reqs=CERT_REQUIRED, ca_certs=None):
-            if ca_certs:
-                raise util.Abort(_(
-                    'certificate checking requires Python 2.6'))
-
-            ssl = socket.ssl(sock, key_file, cert_file)
-            return httplib.FakeSocket(sock, ssl)
-
-    try:
         _create_connection = socket.create_connection
     except AttributeError:
         _GLOBAL_DEFAULT_TIMEOUT = object()
@@ -364,7 +170,7 @@
             self.sock.connect((self.host, self.port))
             if _generic_proxytunnel(self):
                 # we do not support client x509 certificates
-                self.sock = _ssl_wrap_socket(self.sock, None, None)
+                self.sock = sslutil.ssl_wrap_socket(self.sock, None, None)
         else:
             keepalive.HTTPConnection.connect(self)
 
@@ -390,13 +196,9 @@
         new_tunnel = False
 
     if new_tunnel or tunnel_host == req.get_full_url(): # has proxy
-        urlparts = urlparse.urlparse(tunnel_host)
-        if new_tunnel or urlparts[0] == 'https': # only use CONNECT for HTTPS
-            realhostport = urlparts[1]
-            if realhostport[-1] == ']' or ':' not in realhostport:
-                realhostport += ':443'
-
-            h.realhostport = realhostport
+        u = util.url(tunnel_host)
+        if new_tunnel or u.scheme == 'https': # only use CONNECT for HTTPS
+            h.realhostport = ':'.join([u.host, (u.port or '443')])
             h.headers = req.headers.copy()
             h.headers.update(handler.parent.addheaders)
             return
@@ -509,41 +311,6 @@
         _generic_start_transaction(self, h, req)
         return keepalive.HTTPHandler._start_transaction(self, h, req)
 
-def _verifycert(cert, hostname):
-    '''Verify that cert (in socket.getpeercert() format) matches hostname.
-    CRLs is not handled.
-
-    Returns error message if any problems are found and None on success.
-    '''
-    if not cert:
-        return _('no certificate received')
-    dnsname = hostname.lower()
-    def matchdnsname(certname):
-        return (certname == dnsname or
-                '.' in dnsname and certname == '*.' + dnsname.split('.', 1)[1])
-
-    san = cert.get('subjectAltName', [])
-    if san:
-        certnames = [value.lower() for key, value in san if key == 'DNS']
-        for name in certnames:
-            if matchdnsname(name):
-                return None
-        return _('certificate is for %s') % ', '.join(certnames)
-
-    # subject is only checked when subjectAltName is empty
-    for s in cert.get('subject', []):
-        key, value = s[0]
-        if key == 'commonName':
-            try:
-                # 'subject' entries are unicode
-                certname = value.lower().encode('ascii')
-            except UnicodeEncodeError:
-                return _('IDN in certificate not supported')
-            if matchdnsname(certname):
-                return None
-            return _('certificate is for %s') % certname
-    return _('no commonName or subjectAltName found in certificate')
-
 if has_https:
     class httpsconnection(httplib.HTTPSConnection):
         response_class = keepalive.HTTPResponse
@@ -556,55 +323,12 @@
 
             host = self.host
             if self.realhostport: # use CONNECT proxy
-                something = _generic_proxytunnel(self)
+                _generic_proxytunnel(self)
                 host = self.realhostport.rsplit(':', 1)[0]
-
-            cacerts = self.ui.config('web', 'cacerts')
-            hostfingerprint = self.ui.config('hostfingerprints', host)
-
-            if cacerts and not hostfingerprint:
-                cacerts = util.expandpath(cacerts)
-                if not os.path.exists(cacerts):
-                    raise util.Abort(_('could not find '
-                                       'web.cacerts: %s') % cacerts)
-                self.sock = _ssl_wrap_socket(self.sock, self.key_file,
-                    self.cert_file, cert_reqs=CERT_REQUIRED,
-                    ca_certs=cacerts)
-                msg = _verifycert(self.sock.getpeercert(), host)
-                if msg:
-                    raise util.Abort(_('%s certificate error: %s '
-                                       '(use --insecure to connect '
-                                       'insecurely)') % (host, msg))
-                self.ui.debug('%s certificate successfully verified\n' % host)
-            else:
-                self.sock = _ssl_wrap_socket(self.sock, self.key_file,
-                    self.cert_file)
-                if hasattr(self.sock, 'getpeercert'):
-                    peercert = self.sock.getpeercert(True)
-                    peerfingerprint = util.sha1(peercert).hexdigest()
-                    nicefingerprint = ":".join([peerfingerprint[x:x + 2]
-                        for x in xrange(0, len(peerfingerprint), 2)])
-                    if hostfingerprint:
-                        if peerfingerprint.lower() != \
-                                hostfingerprint.replace(':', '').lower():
-                            raise util.Abort(_('invalid certificate for %s '
-                                               'with fingerprint %s') %
-                                             (host, nicefingerprint))
-                        self.ui.debug('%s certificate matched fingerprint %s\n' %
-                                      (host, nicefingerprint))
-                    else:
-                        self.ui.warn(_('warning: %s certificate '
-                                       'with fingerprint %s not verified '
-                                       '(check hostfingerprints or web.cacerts '
-                                       'config setting)\n') %
-                                     (host, nicefingerprint))
-                else: # python 2.5 ?
-                    if hostfingerprint:
-                        raise util.Abort(_('no certificate for %s with '
-                                           'configured hostfingerprint') % host)
-                    self.ui.warn(_('warning: %s certificate not verified '
-                                   '(check web.cacerts config setting)\n') %
-                                 host)
+            self.sock = sslutil.ssl_wrap_socket(
+                self.sock, self.key_file, self.cert_file,
+                **sslutil.sslkwargs(self.ui, host))
+            sslutil.validator(self.ui, host)(self.sock)
 
     class httpshandler(keepalive.KeepAliveHandler, urllib2.HTTPSHandler):
         def __init__(self, ui):
@@ -618,7 +342,7 @@
             return keepalive.KeepAliveHandler._start_transaction(self, h, req)
 
         def https_open(self, req):
-            res = readauthforuri(self.ui, req.get_full_url())
+            res = httpconnectionmod.readauthforuri(self.ui, req.get_full_url())
             if res:
                 group, auth = res
                 self.auth = auth
@@ -694,31 +418,6 @@
         return urllib2.HTTPBasicAuthHandler.http_error_auth_reqed(
                         self, auth_header, host, req, headers)
 
-def getauthinfo(path):
-    scheme, netloc, urlpath, query, frag = urlparse.urlsplit(path)
-    if not urlpath:
-        urlpath = '/'
-    if scheme != 'file':
-        # XXX: why are we quoting the path again with some smart
-        # heuristic here? Anyway, it cannot be done with file://
-        # urls since path encoding is os/fs dependent (see
-        # urllib.pathname2url() for details).
-        urlpath = quotepath(urlpath)
-    host, port, user, passwd = netlocsplit(netloc)
-
-    # urllib cannot handle URLs with embedded user or passwd
-    url = urlparse.urlunsplit((scheme, netlocunsplit(host, port),
-                              urlpath, query, frag))
-    if user:
-        netloc = host
-        if port:
-            netloc += ':' + port
-        # Python < 2.4.3 uses only the netloc to search for a password
-        authinfo = (None, (url, netloc), user, passwd or '')
-    else:
-        authinfo = None
-    return url, authinfo
-
 handlerfuncs = []
 
 def opener(ui, authinfo=None):
@@ -726,9 +425,12 @@
     construct an opener suitable for urllib2
     authinfo will be added to the password manager
     '''
-    handlers = [httphandler()]
-    if has_https:
-        handlers.append(httpshandler(ui))
+    if ui.configbool('ui', 'usehttp2', False):
+        handlers = [httpconnectionmod.http2handler(ui, passwordmgr(ui))]
+    else:
+        handlers = [httphandler()]
+        if has_https:
+            handlers.append(httpshandler(ui))
 
     handlers.append(proxyhandler(ui))
 
@@ -749,17 +451,13 @@
     opener.addheaders.append(('Accept', 'application/mercurial-0.1'))
     return opener
 
-scheme_re = re.compile(r'^([a-zA-Z0-9+-.]+)://')
-
-def open(ui, url, data=None):
-    scheme = None
-    m = scheme_re.search(url)
-    if m:
-        scheme = m.group(1).lower()
-    if not scheme:
-        path = util.normpath(os.path.abspath(url))
-        url = 'file://' + urllib.pathname2url(path)
+def open(ui, url_, data=None):
+    u = util.url(url_)
+    if u.scheme:
+        u.scheme = u.scheme.lower()
+        url_, authinfo = u.authinfo()
+    else:
+        path = util.normpath(os.path.abspath(url_))
+        url_ = 'file://' + urllib.pathname2url(path)
         authinfo = None
-    else:
-        url, authinfo = getauthinfo(url)
-    return opener(ui, authinfo).open(url, data)
+    return opener(ui, authinfo).open(url_, data)
--- a/mercurial/util.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/util.py	Sat Jun 18 17:03:01 2011 -0500
@@ -16,8 +16,8 @@
 from i18n import _
 import error, osutil, encoding
 import errno, re, shutil, sys, tempfile, traceback
-import os, stat, time, calendar, textwrap, unicodedata, signal
-import imp, socket
+import os, time, calendar, textwrap, unicodedata, signal
+import imp, socket, urllib
 
 # Python compatibility
 
@@ -197,7 +197,7 @@
             code = 0
         if code:
             raise Abort(_("command '%s' failed: %s") %
-                        (cmd, explain_exit(code)))
+                        (cmd, explainexit(code)))
         fp = open(outname, 'rb')
         r = fp.read()
         fp.close()
@@ -206,12 +206,12 @@
         try:
             if inname:
                 os.unlink(inname)
-        except:
+        except OSError:
             pass
         try:
             if outname:
                 os.unlink(outname)
-        except:
+        except OSError:
             pass
 
 filtertable = {
@@ -295,57 +295,9 @@
     b.reverse()
     return os.sep.join((['..'] * len(a)) + b) or '.'
 
-def canonpath(root, cwd, myname, auditor=None):
-    """return the canonical path of myname, given cwd and root"""
-    if endswithsep(root):
-        rootsep = root
-    else:
-        rootsep = root + os.sep
-    name = myname
-    if not os.path.isabs(name):
-        name = os.path.join(root, cwd, name)
-    name = os.path.normpath(name)
-    if auditor is None:
-        auditor = path_auditor(root)
-    if name != rootsep and name.startswith(rootsep):
-        name = name[len(rootsep):]
-        auditor(name)
-        return pconvert(name)
-    elif name == root:
-        return ''
-    else:
-        # Determine whether `name' is in the hierarchy at or beneath `root',
-        # by iterating name=dirname(name) until that causes no change (can't
-        # check name == '/', because that doesn't work on windows).  For each
-        # `name', compare dev/inode numbers.  If they match, the list `rel'
-        # holds the reversed list of components making up the relative file
-        # name we want.
-        root_st = os.stat(root)
-        rel = []
-        while True:
-            try:
-                name_st = os.stat(name)
-            except OSError:
-                break
-            if samestat(name_st, root_st):
-                if not rel:
-                    # name was actually the same as root (maybe a symlink)
-                    return ''
-                rel.reverse()
-                name = os.path.join(*rel)
-                auditor(name)
-                return pconvert(name)
-            dirname, basename = os.path.split(name)
-            rel.append(basename)
-            if dirname == name:
-                break
-            name = dirname
-
-        raise Abort('%s not under root' % myname)
-
 _hgexecutable = None
 
-def main_is_frozen():
+def mainfrozen():
     """return True if we are a frozen executable.
 
     The code supports py2exe (most common, Windows only) and tools/freeze
@@ -363,15 +315,15 @@
     if _hgexecutable is None:
         hg = os.environ.get('HG')
         if hg:
-            set_hgexecutable(hg)
-        elif main_is_frozen():
-            set_hgexecutable(sys.executable)
+            _sethgexecutable(hg)
+        elif mainfrozen():
+            _sethgexecutable(sys.executable)
         else:
-            exe = find_exe('hg') or os.path.basename(sys.argv[0])
-            set_hgexecutable(exe)
+            exe = findexe('hg') or os.path.basename(sys.argv[0])
+            _sethgexecutable(exe)
     return _hgexecutable
 
-def set_hgexecutable(path):
+def _sethgexecutable(path):
     """set location of the 'hg' executable"""
     global _hgexecutable
     _hgexecutable = path
@@ -402,7 +354,7 @@
     env = dict(os.environ)
     env.update((k, py2shell(v)) for k, v in environ.iteritems())
     env['HG'] = hgexecutable()
-    if out is None:
+    if out is None or out == sys.__stdout__:
         rc = subprocess.call(cmd, shell=True, close_fds=closefds,
                              env=env, cwd=cwd)
     else:
@@ -417,7 +369,7 @@
         rc = 0
     if rc and onerr:
         errmsg = '%s %s' % (os.path.basename(origcmd.split(None, 1)[0]),
-                            explain_exit(rc)[0])
+                            explainexit(rc)[0])
         if errprefix:
             errmsg = '%s: %s' % (errprefix, errmsg)
         try:
@@ -438,6 +390,9 @@
 
     return check
 
+def makedir(path, notindexed):
+    os.mkdir(path)
+
 def unlinkpath(f):
     """unlink and remove the directory if it is empty"""
     os.unlink(f)
@@ -452,7 +407,7 @@
     if os.path.islink(src):
         try:
             os.unlink(dest)
-        except:
+        except OSError:
             pass
         os.symlink(os.readlink(src), dest)
     else:
@@ -480,7 +435,7 @@
     else:
         if hardlink:
             try:
-                os_link(src, dst)
+                oslink(src, dst)
             except (IOError, OSError):
                 hardlink = False
                 shutil.copy(src, dst)
@@ -490,78 +445,49 @@
 
     return hardlink, num
 
-class path_auditor(object):
-    '''ensure that a filesystem path contains no banned components.
-    the following properties of a path are checked:
-
-    - ends with a directory separator
-    - under top-level .hg
-    - starts at the root of a windows drive
-    - contains ".."
-    - traverses a symlink (e.g. a/symlink_here/b)
-    - inside a nested repository (a callback can be used to approve
-      some nested repositories, e.g., subrepositories)
-    '''
-
-    def __init__(self, root, callback=None):
-        self.audited = set()
-        self.auditeddir = set()
-        self.root = root
-        self.callback = callback
+_winreservednames = '''con prn aux nul
+    com1 com2 com3 com4 com5 com6 com7 com8 com9
+    lpt1 lpt2 lpt3 lpt4 lpt5 lpt6 lpt7 lpt8 lpt9'''.split()
+_winreservedchars = ':*?"<>|'
+def checkwinfilename(path):
+    '''Check that the base-relative path is a valid filename on Windows.
+    Returns None if the path is ok, or a UI string describing the problem.
 
-    def __call__(self, path):
-        if path in self.audited:
-            return
-        # AIX ignores "/" at end of path, others raise EISDIR.
-        if endswithsep(path):
-            raise Abort(_("path ends in directory separator: %s") % path)
-        normpath = os.path.normcase(path)
-        parts = splitpath(normpath)
-        if (os.path.splitdrive(path)[0]
-            or parts[0].lower() in ('.hg', '.hg.', '')
-            or os.pardir in parts):
-            raise Abort(_("path contains illegal component: %s") % path)
-        if '.hg' in path.lower():
-            lparts = [p.lower() for p in parts]
-            for p in '.hg', '.hg.':
-                if p in lparts[1:]:
-                    pos = lparts.index(p)
-                    base = os.path.join(*parts[:pos])
-                    raise Abort(_('path %r is inside repo %r') % (path, base))
-        def check(prefix):
-            curpath = os.path.join(self.root, prefix)
-            try:
-                st = os.lstat(curpath)
-            except OSError, err:
-                # EINVAL can be raised as invalid path syntax under win32.
-                # They must be ignored for patterns can be checked too.
-                if err.errno not in (errno.ENOENT, errno.ENOTDIR, errno.EINVAL):
-                    raise
-            else:
-                if stat.S_ISLNK(st.st_mode):
-                    raise Abort(_('path %r traverses symbolic link %r') %
-                                (path, prefix))
-                elif (stat.S_ISDIR(st.st_mode) and
-                      os.path.isdir(os.path.join(curpath, '.hg'))):
-                    if not self.callback or not self.callback(curpath):
-                        raise Abort(_('path %r is inside repo %r') %
-                                    (path, prefix))
-        parts.pop()
-        prefixes = []
-        while parts:
-            prefix = os.sep.join(parts)
-            if prefix in self.auditeddir:
-                break
-            check(prefix)
-            prefixes.append(prefix)
-            parts.pop()
+    >>> checkwinfilename("just/a/normal/path")
+    >>> checkwinfilename("foo/bar/con.xml")
+    "filename contains 'con', which is reserved on Windows"
+    >>> checkwinfilename("foo/con.xml/bar")
+    "filename contains 'con', which is reserved on Windows"
+    >>> checkwinfilename("foo/bar/xml.con")
+    >>> checkwinfilename("foo/bar/AUX/bla.txt")
+    "filename contains 'AUX', which is reserved on Windows"
+    >>> checkwinfilename("foo/bar/bla:.txt")
+    "filename contains ':', which is reserved on Windows"
+    >>> checkwinfilename("foo/bar/b\07la.txt")
+    "filename contains '\\\\x07', which is invalid on Windows"
+    >>> checkwinfilename("foo/bar/bla ")
+    "filename ends with ' ', which is not allowed on Windows"
+    '''
+    for n in path.replace('\\', '/').split('/'):
+        if not n:
+            continue
+        for c in n:
+            if c in _winreservedchars:
+                return _("filename contains '%s', which is reserved "
+                         "on Windows") % c
+            if ord(c) <= 31:
+                return _("filename contains %r, which is invalid "
+                         "on Windows") % c
+        base = n.split('.')[0]
+        if base and base.lower() in _winreservednames:
+            return _("filename contains '%s', which is reserved "
+                     "on Windows") % base
+        t = n[-1]
+        if t in '. ':
+            return _("filename ends with '%s', which is not allowed "
+                     "on Windows") % t
 
-        self.audited.add(path)
-        # only add prefixes to the cache after checking everything: we don't
-        # want to add "foo/bar/baz" before checking if there's a "foo/.hg"
-        self.auditeddir.update(prefixes)
-
-def lookup_reg(key, name=None, scope=None):
+def lookupreg(key, name=None, scope=None):
     return None
 
 def hidewindow():
@@ -573,6 +499,7 @@
     pass
 
 if os.name == 'nt':
+    checkosfilename = checkwinfilename
     from windows import *
 else:
     from posix import *
@@ -629,7 +556,7 @@
         if s2 == s1:
             return False
         return True
-    except:
+    except OSError:
         return True
 
 _fspathcache = {}
@@ -680,45 +607,6 @@
 
     return ''.join(result)
 
-def checkexec(path):
-    """
-    Check whether the given path is on a filesystem with UNIX-like exec flags
-
-    Requires a directory (like /foo/.hg)
-    """
-
-    # VFAT on some Linux versions can flip mode but it doesn't persist
-    # a FS remount. Frequently we can detect it if files are created
-    # with exec bit on.
-
-    try:
-        EXECFLAGS = stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH
-        fh, fn = tempfile.mkstemp(dir=path, prefix='hg-checkexec-')
-        try:
-            os.close(fh)
-            m = os.stat(fn).st_mode & 0777
-            new_file_has_exec = m & EXECFLAGS
-            os.chmod(fn, m ^ EXECFLAGS)
-            exec_flags_cannot_flip = ((os.stat(fn).st_mode & 0777) == m)
-        finally:
-            os.unlink(fn)
-    except (IOError, OSError):
-        # we don't care, the user probably won't be able to commit anyway
-        return False
-    return not (new_file_has_exec or exec_flags_cannot_flip)
-
-def checklink(path):
-    """check whether the given path is on a symlink-capable filesystem"""
-    # mktemp is not racy because symlink creation will fail if the
-    # file already exists
-    name = tempfile.mktemp(dir=path, prefix='hg-checklink-')
-    try:
-        os.symlink(".", name)
-        os.unlink(name)
-        return True
-    except (OSError, AttributeError):
-        return False
-
 def checknlink(testfile):
     '''check whether hardlink count reporting works properly'''
 
@@ -736,7 +624,7 @@
     fd = None
     try:
         try:
-            os_link(f1, f2)
+            oslink(f1, f2)
         except OSError:
             return False
 
@@ -769,7 +657,18 @@
 
 def gui():
     '''Are we running in a GUI?'''
-    return os.name == "nt" or os.name == "mac" or os.environ.get("DISPLAY")
+    if sys.platform == 'darwin':
+        if 'SSH_CONNECTION' in os.environ:
+            # handle SSH access to a box where the user is logged in
+            return False
+        elif getattr(osutil, 'isgui', None):
+            # check if a CoreGraphics session is available
+            return osutil.isgui()
+        else:
+            # pure build; use a safe default
+            return True
+    else:
+        return os.name == "nt" or os.environ.get("DISPLAY")
 
 def mktempcopy(name, emptyok=False, createmode=None):
     """Create a temporary file with the same contents from name
@@ -820,38 +719,41 @@
     return temp
 
 class atomictempfile(object):
-    """file-like object that atomically updates a file
+    '''writeable file object that atomically updates a file
 
-    All writes will be redirected to a temporary copy of the original
-    file.  When rename is called, the copy is renamed to the original
-    name, making the changes visible.
-    """
+    All writes will go to a temporary copy of the original file. Call
+    rename() when you are done writing, and atomictempfile will rename
+    the temporary copy to the original name, making the changes visible.
+
+    Unlike other file-like objects, close() discards your writes by
+    simply deleting the temporary file.
+    '''
     def __init__(self, name, mode='w+b', createmode=None):
-        self.__name = name
-        self._fp = None
-        self.temp = mktempcopy(name, emptyok=('w' in mode),
-                               createmode=createmode)
-        self._fp = posixfile(self.temp, mode)
+        self.__name = name      # permanent name
+        self._tempname = mktempcopy(name, emptyok=('w' in mode),
+                                    createmode=createmode)
+        self._fp = posixfile(self._tempname, mode)
 
-    def __getattr__(self, name):
-        return getattr(self._fp, name)
+        # delegated methods
+        self.write = self._fp.write
+        self.fileno = self._fp.fileno
 
     def rename(self):
         if not self._fp.closed:
             self._fp.close()
-            rename(self.temp, localpath(self.__name))
+            rename(self._tempname, localpath(self.__name))
 
     def close(self):
-        if not self._fp:
-            return
         if not self._fp.closed:
             try:
-                os.unlink(self.temp)
-            except: pass
+                os.unlink(self._tempname)
+            except OSError:
+                pass
             self._fp.close()
 
     def __del__(self):
-        self.close()
+        if hasattr(self, '_fp'): # constructor actually did something
+            self.close()
 
 def makedirs(name, mode=None):
     """recursive directory creation with parent mode inheritance"""
@@ -869,97 +771,26 @@
     makedirs(parent, mode)
     makedirs(name, mode)
 
-class opener(object):
-    """Open files relative to a base directory
-
-    This class is used to hide the details of COW semantics and
-    remote file access from higher level code.
-    """
-    def __init__(self, base, audit=True):
-        self.base = base
-        if audit:
-            self.auditor = path_auditor(base)
-        else:
-            self.auditor = always
-        self.createmode = None
-        self._trustnlink = None
-
-    @propertycache
-    def _can_symlink(self):
-        return checklink(self.base)
-
-    def _fixfilemode(self, name):
-        if self.createmode is None:
-            return
-        os.chmod(name, self.createmode & 0666)
-
-    def __call__(self, path, mode="r", text=False, atomictemp=False):
-        self.auditor(path)
-        f = os.path.join(self.base, path)
-
-        if not text and "b" not in mode:
-            mode += "b" # for that other OS
+def readfile(path):
+    fp = open(path, 'rb')
+    try:
+        return fp.read()
+    finally:
+        fp.close()
 
-        nlink = -1
-        dirname, basename = os.path.split(f)
-        # If basename is empty, then the path is malformed because it points
-        # to a directory. Let the posixfile() call below raise IOError.
-        if basename and mode not in ('r', 'rb'):
-            if atomictemp:
-                if not os.path.isdir(dirname):
-                    makedirs(dirname, self.createmode)
-                return atomictempfile(f, mode, self.createmode)
-            try:
-                if 'w' in mode:
-                    unlink(f)
-                    nlink = 0
-                else:
-                    # nlinks() may behave differently for files on Windows
-                    # shares if the file is open.
-                    fd = posixfile(f)
-                    nlink = nlinks(f)
-                    if nlink < 1:
-                        nlink = 2 # force mktempcopy (issue1922)
-                    fd.close()
-            except (OSError, IOError), e:
-                if e.errno != errno.ENOENT:
-                    raise
-                nlink = 0
-                if not os.path.isdir(dirname):
-                    makedirs(dirname, self.createmode)
-            if nlink > 0:
-                if self._trustnlink is None:
-                    self._trustnlink = nlink > 1 or checknlink(f)
-                if nlink > 1 or not self._trustnlink:
-                    rename(mktempcopy(f), f)
-        fp = posixfile(f, mode)
-        if nlink == 0:
-            self._fixfilemode(f)
-        return fp
+def writefile(path, text):
+    fp = open(path, 'wb')
+    try:
+        fp.write(text)
+    finally:
+        fp.close()
 
-    def symlink(self, src, dst):
-        self.auditor(dst)
-        linkname = os.path.join(self.base, dst)
-        try:
-            os.unlink(linkname)
-        except OSError:
-            pass
-
-        dirname = os.path.dirname(linkname)
-        if not os.path.exists(dirname):
-            makedirs(dirname, self.createmode)
-
-        if self._can_symlink:
-            try:
-                os.symlink(src, linkname)
-            except OSError, err:
-                raise OSError(err.errno, _('could not symlink to %r: %s') %
-                              (src, err.strerror), linkname)
-        else:
-            f = self(dst, "w")
-            f.write(src)
-            f.close()
-            self._fixfilemode(dst)
+def appendfile(path, text):
+    fp = open(path, 'ab')
+    try:
+        fp.write(text)
+    finally:
+        fp.close()
 
 class chunkbuffer(object):
     """Allow arbitrary sized chunks of data to be efficiently read from an
@@ -1123,7 +954,6 @@
         # fill out defaults
         now = makedate()
         defaults = {}
-        nowmap = {}
         for part in ("d", "mb", "yY", "HI", "M", "S"):
             # this piece is for rounding the specific end of unknowns
             b = bias.get(part)
@@ -1204,10 +1034,17 @@
         return parsedate(date, extendeddateformats, d)[0]
 
     date = date.strip()
-    if date[0] == "<":
+
+    if not date:
+        raise Abort(_("dates cannot consist entirely of whitespace"))
+    elif date[0] == "<":
+        if not date[1:]:
+            raise Abort(_("invalid day spec, use '<DATE'"))
         when = upper(date[1:])
         return lambda x: x <= when
     elif date[0] == ">":
+        if not date[1:]:
+            raise Abort(_("invalid day spec, use '>DATE'"))
         when = lower(date[1:])
         return lambda x: x >= when
     elif date[0] == "-":
@@ -1215,6 +1052,9 @@
             days = int(date[1:])
         except ValueError:
             raise Abort(_("invalid day spec: %s") % date[1:])
+        if days < 0:
+            raise Abort(_("%s must be nonnegative (see 'hg help dates')")
+                % date[1:])
         when = makedate()[0] - days * 3600 * 24
         return lambda x: x >= when
     elif " to " in date:
@@ -1266,86 +1106,6 @@
     except (UnicodeDecodeError, UnicodeEncodeError):
         return _ellipsis(text, maxlength)[0]
 
-def walkrepos(path, followsym=False, seen_dirs=None, recurse=False):
-    '''yield every hg repository under path, recursively.'''
-    def errhandler(err):
-        if err.filename == path:
-            raise err
-    if followsym and hasattr(os.path, 'samestat'):
-        def _add_dir_if_not_there(dirlst, dirname):
-            match = False
-            samestat = os.path.samestat
-            dirstat = os.stat(dirname)
-            for lstdirstat in dirlst:
-                if samestat(dirstat, lstdirstat):
-                    match = True
-                    break
-            if not match:
-                dirlst.append(dirstat)
-            return not match
-    else:
-        followsym = False
-
-    if (seen_dirs is None) and followsym:
-        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')
-            if os.path.isdir(os.path.join(qroot, '.hg')):
-                yield qroot # we have a patch queue repo here
-            if recurse:
-                # avoid recursing inside the .hg directory
-                dirs.remove('.hg')
-            else:
-                dirs[:] = [] # don't descend further
-        elif followsym:
-            newdirs = []
-            for d in dirs:
-                fname = os.path.join(root, d)
-                if _add_dir_if_not_there(seen_dirs, fname):
-                    if os.path.islink(fname):
-                        for hgname in walkrepos(fname, True, seen_dirs):
-                            yield hgname
-                    else:
-                        newdirs.append(d)
-            dirs[:] = newdirs
-
-_rcpath = None
-
-def os_rcpath():
-    '''return default os-specific hgrc search path'''
-    path = system_rcpath()
-    path.extend(user_rcpath())
-    path = [os.path.normpath(f) for f in path]
-    return path
-
-def rcpath():
-    '''return hgrc search path. if env var HGRCPATH is set, use it.
-    for each item in path, if directory, use files ending in .rc,
-    else use item.
-    make HGRCPATH empty to only look in .hg/hgrc of current repo.
-    if no HGRCPATH, use default os-specific path.'''
-    global _rcpath
-    if _rcpath is None:
-        if 'HGRCPATH' in os.environ:
-            _rcpath = []
-            for p in os.environ['HGRCPATH'].split(os.pathsep):
-                if not p:
-                    continue
-                p = expandpath(p)
-                if os.path.isdir(p):
-                    for f, kind in osutil.listdir(p):
-                        if f.endswith('.rc'):
-                            _rcpath.append(os.path.join(p, f))
-                else:
-                    _rcpath.append(p)
-        else:
-            _rcpath = os_rcpath()
-    return _rcpath
-
 def bytecount(nbytes):
     '''return byte count formatted as readable string, with units'''
 
@@ -1367,26 +1127,6 @@
             return format % (nbytes / float(divisor))
     return units[-1][2] % nbytes
 
-def drop_scheme(scheme, path):
-    sc = scheme + ':'
-    if path.startswith(sc):
-        path = path[len(sc):]
-        if path.startswith('//'):
-            if scheme == 'file':
-                i = path.find('/', 2)
-                if i == -1:
-                    return ''
-                # On Windows, absolute paths are rooted at the current drive
-                # root. On POSIX they are rooted at the file system root.
-                if os.name == 'nt':
-                    droot = os.path.splitdrive(os.getcwd())[0] + '/'
-                    path = os.path.join(droot, path[i + 1:])
-                else:
-                    path = path[i:]
-            else:
-                path = path[2:]
-    return path
-
 def uirepr(s):
     # Avoid double backslash in Windows path repr()
     return repr(s).replace('\\\\', '\\')
@@ -1459,7 +1199,7 @@
     to avoid things opening new shell windows like batch files, so we
     get either the python call or current executable.
     """
-    if main_is_frozen():
+    if mainfrozen():
         return [sys.executable]
     return gethgcmd()
 
@@ -1564,3 +1304,296 @@
     If s is not a valid boolean, returns None.
     """
     return _booleans.get(s.lower(), None)
+
+_hexdig = '0123456789ABCDEFabcdef'
+_hextochr = dict((a + b, chr(int(a + b, 16)))
+                 for a in _hexdig for b in _hexdig)
+
+def _urlunquote(s):
+    """unquote('abc%20def') -> 'abc def'."""
+    res = s.split('%')
+    # fastpath
+    if len(res) == 1:
+        return s
+    s = res[0]
+    for item in res[1:]:
+        try:
+            s += _hextochr[item[:2]] + item[2:]
+        except KeyError:
+            s += '%' + item
+        except UnicodeDecodeError:
+            s += unichr(int(item[:2], 16)) + item[2:]
+    return s
+
+class url(object):
+    r"""Reliable URL parser.
+
+    This parses URLs and provides attributes for the following
+    components:
+
+    <scheme>://<user>:<passwd>@<host>:<port>/<path>?<query>#<fragment>
+
+    Missing components are set to None. The only exception is
+    fragment, which is set to '' if present but empty.
+
+    If parsefragment is False, fragment is included in query. If
+    parsequery is False, query is included in path. If both are
+    False, both fragment and query are included in path.
+
+    See http://www.ietf.org/rfc/rfc2396.txt for more information.
+
+    Note that for backward compatibility reasons, bundle URLs do not
+    take host names. That means 'bundle://../' has a path of '../'.
+
+    Examples:
+
+    >>> url('http://www.ietf.org/rfc/rfc2396.txt')
+    <url scheme: 'http', host: 'www.ietf.org', path: 'rfc/rfc2396.txt'>
+    >>> url('ssh://[::1]:2200//home/joe/repo')
+    <url scheme: 'ssh', host: '[::1]', port: '2200', path: '/home/joe/repo'>
+    >>> url('file:///home/joe/repo')
+    <url scheme: 'file', path: '/home/joe/repo'>
+    >>> url('bundle:foo')
+    <url scheme: 'bundle', path: 'foo'>
+    >>> url('bundle://../foo')
+    <url scheme: 'bundle', path: '../foo'>
+    >>> url(r'c:\foo\bar')
+    <url path: 'c:\\foo\\bar'>
+
+    Authentication credentials:
+
+    >>> url('ssh://joe:xyz@x/repo')
+    <url scheme: 'ssh', user: 'joe', passwd: 'xyz', host: 'x', path: 'repo'>
+    >>> url('ssh://joe@x/repo')
+    <url scheme: 'ssh', user: 'joe', host: 'x', path: 'repo'>
+
+    Query strings and fragments:
+
+    >>> url('http://host/a?b#c')
+    <url scheme: 'http', host: 'host', path: 'a', query: 'b', fragment: 'c'>
+    >>> url('http://host/a?b#c', parsequery=False, parsefragment=False)
+    <url scheme: 'http', host: 'host', path: 'a?b#c'>
+    """
+
+    _safechars = "!~*'()+"
+    _safepchars = "/!~*'()+"
+    _matchscheme = re.compile(r'^[a-zA-Z0-9+.\-]+:').match
+
+    def __init__(self, path, parsequery=True, parsefragment=True):
+        # We slowly chomp away at path until we have only the path left
+        self.scheme = self.user = self.passwd = self.host = None
+        self.port = self.path = self.query = self.fragment = None
+        self._localpath = True
+        self._hostport = ''
+        self._origpath = path
+
+        # special case for Windows drive letters
+        if hasdriveletter(path):
+            self.path = path
+            return
+
+        # For compatibility reasons, we can't handle bundle paths as
+        # normal URLS
+        if path.startswith('bundle:'):
+            self.scheme = 'bundle'
+            path = path[7:]
+            if path.startswith('//'):
+                path = path[2:]
+            self.path = path
+            return
+
+        if self._matchscheme(path):
+            parts = path.split(':', 1)
+            if parts[0]:
+                self.scheme, path = parts
+                self._localpath = False
+
+        if not path:
+            path = None
+            if self._localpath:
+                self.path = ''
+                return
+        else:
+            if parsefragment and '#' in path:
+                path, self.fragment = path.split('#', 1)
+                if not path:
+                    path = None
+            if self._localpath:
+                self.path = path
+                return
+
+            if parsequery and '?' in path:
+                path, self.query = path.split('?', 1)
+                if not path:
+                    path = None
+                if not self.query:
+                    self.query = None
+
+            # // is required to specify a host/authority
+            if path and path.startswith('//'):
+                parts = path[2:].split('/', 1)
+                if len(parts) > 1:
+                    self.host, path = parts
+                    path = path
+                else:
+                    self.host = parts[0]
+                    path = None
+                if not self.host:
+                    self.host = None
+                    if path:
+                        path = '/' + path
+
+            if self.host and '@' in self.host:
+                self.user, self.host = self.host.rsplit('@', 1)
+                if ':' in self.user:
+                    self.user, self.passwd = self.user.split(':', 1)
+                if not self.host:
+                    self.host = None
+
+            # Don't split on colons in IPv6 addresses without ports
+            if (self.host and ':' in self.host and
+                not (self.host.startswith('[') and self.host.endswith(']'))):
+                self._hostport = self.host
+                self.host, self.port = self.host.rsplit(':', 1)
+                if not self.host:
+                    self.host = None
+
+            if (self.host and self.scheme == 'file' and
+                self.host not in ('localhost', '127.0.0.1', '[::1]')):
+                raise Abort(_('file:// URLs can only refer to localhost'))
+
+        self.path = path
+
+        for a in ('user', 'passwd', 'host', 'port',
+                  'path', 'query', 'fragment'):
+            v = getattr(self, a)
+            if v is not None:
+                setattr(self, a, _urlunquote(v))
+
+    def __repr__(self):
+        attrs = []
+        for a in ('scheme', 'user', 'passwd', 'host', 'port', 'path',
+                  'query', 'fragment'):
+            v = getattr(self, a)
+            if v is not None:
+                attrs.append('%s: %r' % (a, v))
+        return '<url %s>' % ', '.join(attrs)
+
+    def __str__(self):
+        r"""Join the URL's components back into a URL string.
+
+        Examples:
+
+        >>> str(url('http://user:pw@host:80/?foo#bar'))
+        'http://user:pw@host:80/?foo#bar'
+        >>> str(url('ssh://user:pw@[::1]:2200//home/joe#'))
+        'ssh://user:pw@[::1]:2200//home/joe#'
+        >>> str(url('http://localhost:80//'))
+        'http://localhost:80//'
+        >>> str(url('http://localhost:80/'))
+        'http://localhost:80/'
+        >>> str(url('http://localhost:80'))
+        'http://localhost:80/'
+        >>> str(url('bundle:foo'))
+        'bundle:foo'
+        >>> str(url('bundle://../foo'))
+        'bundle:../foo'
+        >>> str(url('path'))
+        'path'
+        >>> str(url('file:///tmp/foo/bar'))
+        'file:///tmp/foo/bar'
+        >>> print url(r'bundle:foo\bar')
+        bundle:foo\bar
+        """
+        if self._localpath:
+            s = self.path
+            if self.scheme == 'bundle':
+                s = 'bundle:' + s
+            if self.fragment:
+                s += '#' + self.fragment
+            return s
+
+        s = self.scheme + ':'
+        if self.user or self.passwd or self.host:
+            s += '//'
+        elif self.scheme and (not self.path or self.path.startswith('/')):
+            s += '//'
+        if self.user:
+            s += urllib.quote(self.user, safe=self._safechars)
+        if self.passwd:
+            s += ':' + urllib.quote(self.passwd, safe=self._safechars)
+        if self.user or self.passwd:
+            s += '@'
+        if self.host:
+            if not (self.host.startswith('[') and self.host.endswith(']')):
+                s += urllib.quote(self.host)
+            else:
+                s += self.host
+        if self.port:
+            s += ':' + urllib.quote(self.port)
+        if self.host:
+            s += '/'
+        if self.path:
+            s += urllib.quote(self.path, safe=self._safepchars)
+        if self.query:
+            s += '?' + urllib.quote(self.query, safe=self._safepchars)
+        if self.fragment is not None:
+            s += '#' + urllib.quote(self.fragment, safe=self._safepchars)
+        return s
+
+    def authinfo(self):
+        user, passwd = self.user, self.passwd
+        try:
+            self.user, self.passwd = None, None
+            s = str(self)
+        finally:
+            self.user, self.passwd = user, passwd
+        if not self.user:
+            return (s, None)
+        return (s, (None, (str(self), self.host),
+                    self.user, self.passwd or ''))
+
+    def localpath(self):
+        if self.scheme == 'file' or self.scheme == 'bundle':
+            path = self.path or '/'
+            # For Windows, we need to promote hosts containing drive
+            # letters to paths with drive letters.
+            if hasdriveletter(self._hostport):
+                path = self._hostport + '/' + self.path
+            elif self.host is not None and self.path:
+                path = '/' + path
+            # We also need to handle the case of file:///C:/, which
+            # should return C:/, not /C:/.
+            elif hasdriveletter(path):
+                # Strip leading slash from paths with drive names
+                return path[1:]
+            return path
+        return self._origpath
+
+def hasscheme(path):
+    return bool(url(path).scheme)
+
+def hasdriveletter(path):
+    return path[1:2] == ':' and path[0:1].isalpha()
+
+def localpath(path):
+    return url(path, parsequery=False, parsefragment=False).localpath()
+
+def hidepassword(u):
+    '''hide user credential in a url string'''
+    u = url(u)
+    if u.passwd:
+        u.passwd = '***'
+    return str(u)
+
+def removeauth(u):
+    '''remove all authentication information from a url string'''
+    u = url(u)
+    u.user = u.passwd = None
+    return str(u)
+
+def isatty(fd):
+    try:
+        return fd.isatty()
+    except AttributeError:
+        return False
--- a/mercurial/win32.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/win32.py	Sat Jun 18 17:03:01 2011 -0500
@@ -6,18 +6,22 @@
 # GNU General Public License version 2 or any later version.
 
 import encoding
-import ctypes, errno, os, struct, subprocess
+import ctypes, errno, os, struct, subprocess, random
 
 _kernel32 = ctypes.windll.kernel32
+_advapi32 = ctypes.windll.advapi32
+_user32 = ctypes.windll.user32
 
 _BOOL = ctypes.c_long
 _WORD = ctypes.c_ushort
 _DWORD = ctypes.c_ulong
+_UINT = ctypes.c_uint
+_LONG = ctypes.c_long
 _LPCSTR = _LPSTR = ctypes.c_char_p
 _HANDLE = ctypes.c_void_p
 _HWND = _HANDLE
 
-_INVALID_HANDLE_VALUE = -1
+_INVALID_HANDLE_VALUE = _HANDLE(-1).value
 
 # GetLastError
 _ERROR_SUCCESS = 0
@@ -56,6 +60,10 @@
 
 _OPEN_EXISTING = 3
 
+# SetFileAttributes
+_FILE_ATTRIBUTE_NORMAL = 0x80
+_FILE_ATTRIBUTE_NOT_CONTENT_INDEXED = 0x2000
+
 # Process Security and Access Rights
 _PROCESS_QUERY_INFORMATION = 0x0400
 
@@ -116,7 +124,82 @@
                 ('srWindow', _SMALL_RECT),
                 ('dwMaximumWindowSize', _COORD)]
 
-_STD_ERROR_HANDLE = 0xfffffff4L # (DWORD)-12
+_STD_ERROR_HANDLE = _DWORD(-12).value
+
+# types of parameters of C functions used (required by pypy)
+
+_kernel32.CreateFileA.argtypes = [_LPCSTR, _DWORD, _DWORD, ctypes.c_void_p,
+    _DWORD, _DWORD, _HANDLE]
+_kernel32.CreateFileA.restype = _HANDLE
+
+_kernel32.GetFileInformationByHandle.argtypes = [_HANDLE, ctypes.c_void_p]
+_kernel32.GetFileInformationByHandle.restype = _BOOL
+
+_kernel32.CloseHandle.argtypes = [_HANDLE]
+_kernel32.CloseHandle.restype = _BOOL
+
+_kernel32.CreateHardLinkA.argtypes = [_LPCSTR, _LPCSTR, ctypes.c_void_p]
+_kernel32.CreateHardLinkA.restype = _BOOL
+
+_kernel32.SetFileAttributesA.argtypes = [_LPCSTR, _DWORD]
+_kernel32.SetFileAttributesA.restype = _BOOL
+
+_kernel32.OpenProcess.argtypes = [_DWORD, _BOOL, _DWORD]
+_kernel32.OpenProcess.restype = _HANDLE
+
+_kernel32.GetExitCodeProcess.argtypes = [_HANDLE, ctypes.c_void_p]
+_kernel32.GetExitCodeProcess.restype = _BOOL
+
+_kernel32.GetLastError.argtypes = []
+_kernel32.GetLastError.restype = _DWORD
+
+_kernel32.GetModuleFileNameA.argtypes = [_HANDLE, ctypes.c_void_p, _DWORD]
+_kernel32.GetModuleFileNameA.restype = _DWORD
+
+_kernel32.CreateProcessA.argtypes = [_LPCSTR, _LPCSTR, ctypes.c_void_p,
+    ctypes.c_void_p, _BOOL, _DWORD, ctypes.c_void_p, _LPCSTR, ctypes.c_void_p,
+    ctypes.c_void_p]
+_kernel32.CreateProcessA.restype = _BOOL
+
+_kernel32.ExitProcess.argtypes = [_UINT]
+_kernel32.ExitProcess.restype = None
+
+_kernel32.GetCurrentProcessId.argtypes = []
+_kernel32.GetCurrentProcessId.restype = _DWORD
+
+_SIGNAL_HANDLER = ctypes.WINFUNCTYPE(_BOOL, _DWORD)
+_kernel32.SetConsoleCtrlHandler.argtypes = [_SIGNAL_HANDLER, _BOOL]
+_kernel32.SetConsoleCtrlHandler.restype = _BOOL
+
+_kernel32.GetStdHandle.argtypes = [_DWORD]
+_kernel32.GetStdHandle.restype = _HANDLE
+
+_kernel32.GetConsoleScreenBufferInfo.argtypes = [_HANDLE, ctypes.c_void_p]
+_kernel32.GetConsoleScreenBufferInfo.restype = _BOOL
+
+_advapi32.RegOpenKeyExA.argtypes = [_HANDLE, _LPCSTR, _DWORD, _DWORD,
+    ctypes.c_void_p]
+_advapi32.RegOpenKeyExA.restype = _LONG
+
+_advapi32.RegQueryValueExA.argtypes = [_HANDLE, _LPCSTR, ctypes.c_void_p,
+    ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p]
+_advapi32.RegQueryValueExA.restype = _LONG
+
+_advapi32.RegCloseKey.argtypes = [_HANDLE]
+_advapi32.RegCloseKey.restype = _LONG
+
+_advapi32.GetUserNameA.argtypes = [ctypes.c_void_p, ctypes.c_void_p]
+_advapi32.GetUserNameA.restype = _BOOL
+
+_user32.GetWindowThreadProcessId.argtypes = [_HANDLE, ctypes.c_void_p]
+_user32.GetWindowThreadProcessId.restype = _DWORD
+
+_user32.ShowWindow.argtypes = [_HANDLE, ctypes.c_int]
+_user32.ShowWindow.restype = _BOOL
+
+_WNDENUMPROC = ctypes.WINFUNCTYPE(_BOOL, _HWND, _LPARAM)
+_user32.EnumWindows.argtypes = [_WNDENUMPROC, _LPARAM]
+_user32.EnumWindows.restype = _BOOL
 
 def _raiseoserror(name):
     err = ctypes.WinError()
@@ -136,8 +219,11 @@
     finally:
         _kernel32.CloseHandle(fh)
 
-def os_link(src, dst):
-    if not _kernel32.CreateHardLinkA(dst, src, None):
+def oslink(src, dst):
+    try:
+        if not _kernel32.CreateHardLinkA(dst, src, None):
+            _raiseoserror(src)
+    except AttributeError: # Wine doesn't support this function
         _raiseoserror(src)
 
 def nlinks(name):
@@ -173,7 +259,7 @@
             _kernel32.CloseHandle(h)
     return _kernel32.GetLastError() != _ERROR_INVALID_PARAMETER
 
-def lookup_reg(key, valname=None, scope=None):
+def lookupreg(key, valname=None, scope=None):
     ''' Look up a key/value name in the Windows registry.
 
     valname: value name. If unspecified, the default value for the key
@@ -182,7 +268,6 @@
     a sequence of scopes to look up in order. Default (CURRENT_USER,
     LOCAL_MACHINE).
     '''
-    adv = ctypes.windll.advapi32
     byref = ctypes.byref
     if scope is None:
         scope = (_HKEY_CURRENT_USER, _HKEY_LOCAL_MACHINE)
@@ -190,14 +275,14 @@
         scope = (scope,)
     for s in scope:
         kh = _HANDLE()
-        res = adv.RegOpenKeyExA(s, key, 0, _KEY_READ, ctypes.byref(kh))
+        res = _advapi32.RegOpenKeyExA(s, key, 0, _KEY_READ, ctypes.byref(kh))
         if res != _ERROR_SUCCESS:
             continue
         try:
             size = _DWORD(600)
             type = _DWORD()
             buf = ctypes.create_string_buffer(size.value + 1)
-            res = adv.RegQueryValueExA(kh.value, valname, None,
+            res = _advapi32.RegQueryValueExA(kh.value, valname, None,
                                        byref(type), buf, byref(size))
             if res != _ERROR_SUCCESS:
                 continue
@@ -209,9 +294,9 @@
                 s = ctypes.string_at(byref(buf), struct.calcsize(fmt))
                 return struct.unpack(fmt, s)[0]
         finally:
-            adv.RegCloseKey(kh.value)
+            _advapi32.RegCloseKey(kh.value)
 
-def executable_path():
+def executablepath():
     '''return full path of hg.exe'''
     size = 600
     buf = ctypes.create_string_buffer(size + 1)
@@ -224,17 +309,15 @@
 
 def getuser():
     '''return name of current user'''
-    adv = ctypes.windll.advapi32
     size = _DWORD(300)
     buf = ctypes.create_string_buffer(size.value + 1)
-    if not adv.GetUserNameA(ctypes.byref(buf), ctypes.byref(size)):
+    if not _advapi32.GetUserNameA(ctypes.byref(buf), ctypes.byref(size)):
         raise ctypes.WinError()
     return buf.value
 
-_SIGNAL_HANDLER = ctypes.WINFUNCTYPE(_BOOL, _DWORD)
-_signal_handler = []
+_signalhandler = []
 
-def set_signal_handler():
+def setsignalhandler():
     '''Register a termination handler for console events including
     CTRL+C. python signal handlers do not work well with socket
     operations.
@@ -242,28 +325,25 @@
     def handler(event):
         _kernel32.ExitProcess(1)
 
-    if _signal_handler:
+    if _signalhandler:
         return # already registered
     h = _SIGNAL_HANDLER(handler)
-    _signal_handler.append(h) # needed to prevent garbage collection
+    _signalhandler.append(h) # needed to prevent garbage collection
     if not _kernel32.SetConsoleCtrlHandler(h, True):
         raise ctypes.WinError()
 
-_WNDENUMPROC = ctypes.WINFUNCTYPE(_BOOL, _HWND, _LPARAM)
-
 def hidewindow():
-    user32 = ctypes.windll.user32
 
     def callback(hwnd, pid):
         wpid = _DWORD()
-        user32.GetWindowThreadProcessId(hwnd, ctypes.byref(wpid))
+        _user32.GetWindowThreadProcessId(hwnd, ctypes.byref(wpid))
         if pid == wpid.value:
-            user32.ShowWindow(hwnd, _SW_HIDE)
+            _user32.ShowWindow(hwnd, _SW_HIDE)
             return False # stop enumerating windows
         return True
 
     pid = _kernel32.GetCurrentProcessId()
-    user32.EnumWindows(_WNDENUMPROC(callback), pid)
+    _user32.EnumWindows(_WNDENUMPROC(callback), pid)
 
 def termwidth():
     # cmd.exe does not handle CR like a unix console, the CR is
@@ -316,3 +396,54 @@
         raise ctypes.WinError()
 
     return pi.dwProcessId
+
+def unlink(f):
+    '''try to implement POSIX' unlink semantics on Windows'''
+
+    # POSIX allows to unlink and rename open files. Windows has serious
+    # problems with doing that:
+    # - Calling os.unlink (or os.rename) on a file f fails if f or any
+    #   hardlinked copy of f has been opened with Python's open(). There is no
+    #   way such a file can be deleted or renamed on Windows (other than
+    #   scheduling the delete or rename for the next reboot).
+    # - Calling os.unlink on a file that has been opened with Mercurial's
+    #   posixfile (or comparable methods) will delay the actual deletion of
+    #   the file for as long as the file is held open. The filename is blocked
+    #   during that time and cannot be used for recreating a new file under
+    #   that same name ("zombie file"). Directories containing such zombie files
+    #   cannot be removed or moved.
+    # A file that has been opened with posixfile can be renamed, so we rename
+    # f to a random temporary name before calling os.unlink on it. This allows
+    # callers to recreate f immediately while having other readers do their
+    # implicit zombie filename blocking on a temporary name.
+
+    for tries in xrange(10):
+        temp = '%s-%08x' % (f, random.randint(0, 0xffffffff))
+        try:
+            os.rename(f, temp)  # raises OSError EEXIST if temp exists
+            break
+        except OSError, e:
+            if e.errno != errno.EEXIST:
+                raise
+    else:
+        raise IOError, (errno.EEXIST, "No usable temporary filename found")
+
+    try:
+        os.unlink(temp)
+    except OSError:
+        # The unlink might have failed because the READONLY attribute may heave
+        # been set on the original file. Rename works fine with READONLY set,
+        # but not os.unlink. Reset all attributes and try again.
+        _kernel32.SetFileAttributesA(temp, _FILE_ATTRIBUTE_NORMAL)
+        try:
+            os.unlink(temp)
+        except OSError:
+            # The unlink might have failed due to some very rude AV-Scanners.
+            # Leaking a tempfile is the lesser evil than aborting here and
+            # leaving some potentially serious inconsistencies.
+            pass
+
+def makedir(path, notindexed):
+    os.mkdir(path)
+    if notindexed:
+        _kernel32.SetFileAttributesA(path, _FILE_ATTRIBUTE_NOT_CONTENT_INDEXED)
--- a/mercurial/windows.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/windows.py	Sat Jun 18 17:03:01 2011 -0500
@@ -6,8 +6,8 @@
 # GNU General Public License version 2 or any later version.
 
 from i18n import _
-import osutil, error
-import errno, msvcrt, os, re, sys, random, subprocess
+import osutil
+import errno, msvcrt, os, re, sys
 
 nulldev = 'NUL:'
 umask = 002
@@ -32,7 +32,8 @@
     def close(self):
         try:
             self.fp.close()
-        except: pass
+        except IOError:
+            pass
 
     def write(self, s):
         try:
@@ -73,50 +74,7 @@
 def openhardlinks():
     return not _is_win_9x()
 
-_HKEY_LOCAL_MACHINE = 0x80000002L
-
-def system_rcpath():
-    '''return default os-specific hgrc search path'''
-    rcpath = []
-    filename = executable_path()
-    # Use mercurial.ini found in directory with hg.exe
-    progrc = os.path.join(os.path.dirname(filename), 'mercurial.ini')
-    if os.path.isfile(progrc):
-        rcpath.append(progrc)
-        return rcpath
-    # Use hgrc.d found in directory with hg.exe
-    progrcd = os.path.join(os.path.dirname(filename), 'hgrc.d')
-    if os.path.isdir(progrcd):
-        for f, kind in osutil.listdir(progrcd):
-            if f.endswith('.rc'):
-                rcpath.append(os.path.join(progrcd, f))
-        return rcpath
-    # else look for a system rcpath in the registry
-    value = lookup_reg('SOFTWARE\\Mercurial', None, _HKEY_LOCAL_MACHINE)
-    if not isinstance(value, str) or not value:
-        return rcpath
-    value = value.replace('/', os.sep)
-    for p in value.split(os.pathsep):
-        if p.lower().endswith('mercurial.ini'):
-            rcpath.append(p)
-        elif os.path.isdir(p):
-            for f, kind in osutil.listdir(p):
-                if f.endswith('.rc'):
-                    rcpath.append(os.path.join(p, f))
-    return rcpath
-
-def user_rcpath():
-    '''return os-specific hgrc search path to the user dir'''
-    home = os.path.expanduser('~')
-    path = [os.path.join(home, 'mercurial.ini'),
-            os.path.join(home, '.hgrc')]
-    userprofile = os.environ.get('USERPROFILE')
-    if userprofile:
-        path.append(os.path.join(userprofile, 'mercurial.ini'))
-        path.append(os.path.join(userprofile, '.hgrc'))
-    return path
-
-def parse_patch_output(output_line):
+def parsepatchoutput(output_line):
     """parses the output produced by patch and returns the filename"""
     pf = output_line[14:]
     if pf[0] == '`':
@@ -129,10 +87,16 @@
     args = user and ("%s@%s" % (user, host)) or host
     return port and ("%s %s %s" % (args, pflag, port)) or args
 
-def set_flags(f, l, x):
+def setflags(f, l, x):
     pass
 
-def set_binary(fd):
+def checkexec(path):
+    return False
+
+def checklink(path):
+    return False
+
+def setbinary(fd):
     # When run without console, pipes may expose invalid
     # fileno(), usually set to -1.
     if hasattr(fd, 'fileno') and fd.fileno() >= 0:
@@ -191,7 +155,7 @@
     command += " 2> %s" % nulldev
     return os.popen(quotecommand(command), mode)
 
-def explain_exit(code):
+def explainexit(code):
     return _("exited with status %d") % code, code
 
 # if you change this stub into a real check, please try to implement the
@@ -199,7 +163,7 @@
 def isowner(st):
     return True
 
-def find_exe(command):
+def findexe(command):
     '''Find executable for command searching like cmd.exe does.
     If command is a basename then PATH is searched for command.
     PATH isn't searched if command is an absolute or relative path.
@@ -280,59 +244,19 @@
             if osutil.listdir(head):
                 return
             os.rmdir(head)
-        except:
+        except (ValueError, OSError):
             break
         head, tail = os.path.split(head)
 
 def unlinkpath(f):
     """unlink and remove the directory if it is empty"""
-    os.unlink(f)
+    unlink(f)
     # try removing directories that might now be empty
     try:
         _removedirs(os.path.dirname(f))
     except OSError:
         pass
 
-def unlink(f):
-    '''try to implement POSIX' unlink semantics on Windows'''
-
-    # POSIX allows to unlink and rename open files. Windows has serious
-    # problems with doing that:
-    # - Calling os.unlink (or os.rename) on a file f fails if f or any
-    #   hardlinked copy of f has been opened with Python's open(). There is no
-    #   way such a file can be deleted or renamed on Windows (other than
-    #   scheduling the delete or rename for the next reboot).
-    # - Calling os.unlink on a file that has been opened with Mercurial's
-    #   posixfile (or comparable methods) will delay the actual deletion of
-    #   the file for as long as the file is held open. The filename is blocked
-    #   during that time and cannot be used for recreating a new file under
-    #   that same name ("zombie file"). Directories containing such zombie files
-    #   cannot be removed or moved.
-    # A file that has been opened with posixfile can be renamed, so we rename
-    # f to a random temporary name before calling os.unlink on it. This allows
-    # callers to recreate f immediately while having other readers do their
-    # implicit zombie filename blocking on a temporary name.
-
-    for tries in xrange(10):
-        temp = '%s-%08x' % (f, random.randint(0, 0xffffffff))
-        try:
-            os.rename(f, temp)  # raises OSError EEXIST if temp exists
-            break
-        except OSError, e:
-            if e.errno != errno.EEXIST:
-                raise
-    else:
-        raise IOError, (errno.EEXIST, "No usable temporary filename found")
-
-    try:
-        os.unlink(temp)
-    except:
-        # Some very rude AV-scanners on Windows may cause this unlink to fail.
-        # Not aborting here just leaks the temp file, whereas aborting at this
-        # point may leave serious inconsistencies. Ideally, we would notify
-        # the user in this case here.
-        pass
-
 def rename(src, dst):
     '''atomically rename file src to dst, replacing dst if it exists'''
     try:
--- a/mercurial/wireproto.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/mercurial/wireproto.py	Sat Jun 18 17:03:01 2011 -0500
@@ -12,34 +12,191 @@
 import repo, error, encoding, util, store
 import pushkey as pushkeymod
 
+# abstract batching support
+
+class future(object):
+    '''placeholder for a value to be set later'''
+    def set(self, value):
+        if hasattr(self, 'value'):
+            raise error.RepoError("future is already set")
+        self.value = value
+
+class batcher(object):
+    '''base class for batches of commands submittable in a single request
+
+    All methods invoked on instances of this class are simply queued and return a
+    a future for the result. Once you call submit(), all the queued calls are
+    performed and the results set in their respective futures.
+    '''
+    def __init__(self):
+        self.calls = []
+    def __getattr__(self, name):
+        def call(*args, **opts):
+            resref = future()
+            self.calls.append((name, args, opts, resref,))
+            return resref
+        return call
+    def submit(self):
+        pass
+
+class localbatch(batcher):
+    '''performs the queued calls directly'''
+    def __init__(self, local):
+        batcher.__init__(self)
+        self.local = local
+    def submit(self):
+        for name, args, opts, resref in self.calls:
+            resref.set(getattr(self.local, name)(*args, **opts))
+
+class remotebatch(batcher):
+    '''batches the queued calls; uses as few roundtrips as possible'''
+    def __init__(self, remote):
+        '''remote must support _submitbatch(encbatch) and _submitone(op, encargs)'''
+        batcher.__init__(self)
+        self.remote = remote
+    def submit(self):
+        req, rsp = [], []
+        for name, args, opts, resref in self.calls:
+            mtd = getattr(self.remote, name)
+            if hasattr(mtd, 'batchable'):
+                batchable = getattr(mtd, 'batchable')(mtd.im_self, *args, **opts)
+                encargsorres, encresref = batchable.next()
+                if encresref:
+                    req.append((name, encargsorres,))
+                    rsp.append((batchable, encresref, resref,))
+                else:
+                    resref.set(encargsorres)
+            else:
+                if req:
+                    self._submitreq(req, rsp)
+                    req, rsp = [], []
+                resref.set(mtd(*args, **opts))
+        if req:
+            self._submitreq(req, rsp)
+    def _submitreq(self, req, rsp):
+        encresults = self.remote._submitbatch(req)
+        for encres, r in zip(encresults, rsp):
+            batchable, encresref, resref = r
+            encresref.set(encres)
+            resref.set(batchable.next())
+
+def batchable(f):
+    '''annotation for batchable methods
+
+    Such methods must implement a coroutine as follows:
+
+    @batchable
+    def sample(self, one, two=None):
+        # Handle locally computable results first:
+        if not one:
+            yield "a local result", None
+        # Build list of encoded arguments suitable for your wire protocol:
+        encargs = [('one', encode(one),), ('two', encode(two),)]
+        # Create future for injection of encoded result:
+        encresref = future()
+        # Return encoded arguments and future:
+        yield encargs, encresref
+        # Assuming the future to be filled with the result from the batched request
+        # now. Decode it:
+        yield decode(encresref.value)
+
+    The decorator returns a function which wraps this coroutine as a plain method,
+    but adds the original method as an attribute called "batchable", which is
+    used by remotebatch to split the call into separate encoding and decoding
+    phases.
+    '''
+    def plain(*args, **opts):
+        batchable = f(*args, **opts)
+        encargsorres, encresref = batchable.next()
+        if not encresref:
+            return encargsorres # a local result in this case
+        self = args[0]
+        encresref.set(self._submitone(f.func_name, encargsorres))
+        return batchable.next()
+    setattr(plain, 'batchable', f)
+    return plain
+
 # list of nodes encoding / decoding
 
 def decodelist(l, sep=' '):
-    return map(bin, l.split(sep))
+    if l:
+        return map(bin, l.split(sep))
+    return []
 
 def encodelist(l, sep=' '):
     return sep.join(map(hex, l))
 
+# batched call argument encoding
+
+def escapearg(plain):
+    return (plain
+            .replace(':', '::')
+            .replace(',', ':,')
+            .replace(';', ':;')
+            .replace('=', ':='))
+
+def unescapearg(escaped):
+    return (escaped
+            .replace(':=', '=')
+            .replace(':;', ';')
+            .replace(':,', ',')
+            .replace('::', ':'))
+
 # client side
 
+def todict(**args):
+    return args
+
 class wirerepository(repo.repository):
+
+    def batch(self):
+        return remotebatch(self)
+    def _submitbatch(self, req):
+        cmds = []
+        for op, argsdict in req:
+            args = ','.join('%s=%s' % p for p in argsdict.iteritems())
+            cmds.append('%s %s' % (op, args))
+        rsp = self._call("batch", cmds=';'.join(cmds))
+        return rsp.split(';')
+    def _submitone(self, op, args):
+        return self._call(op, **args)
+
+    @batchable
     def lookup(self, key):
         self.requirecap('lookup', _('look up remote revision'))
-        d = self._call("lookup", key=encoding.fromlocal(key))
+        f = future()
+        yield todict(key=encoding.fromlocal(key)), f
+        d = f.value
         success, data = d[:-1].split(" ", 1)
         if int(success):
-            return bin(data)
+            yield bin(data)
         self._abort(error.RepoError(data))
 
+    @batchable
     def heads(self):
-        d = self._call("heads")
+        f = future()
+        yield {}, f
+        d = f.value
         try:
-            return decodelist(d[:-1])
-        except:
+            yield decodelist(d[:-1])
+        except ValueError:
             self._abort(error.ResponseError(_("unexpected response:"), d))
 
+    @batchable
+    def known(self, nodes):
+        f = future()
+        yield todict(nodes=encodelist(nodes)), f
+        d = f.value
+        try:
+            yield [bool(int(f)) for f in d]
+        except ValueError:
+            self._abort(error.ResponseError(_("unexpected response:"), d))
+
+    @batchable
     def branchmap(self):
-        d = self._call("branchmap")
+        f = future()
+        yield {}, f
+        d = f.value
         try:
             branchmap = {}
             for branchpart in d.splitlines():
@@ -47,7 +204,7 @@
                 branchname = encoding.tolocal(urllib.unquote(branchname))
                 branchheads = decodelist(branchheads)
                 branchmap[branchname] = branchheads
-            return branchmap
+            yield branchmap
         except TypeError:
             self._abort(error.ResponseError(_("unexpected response:"), d))
 
@@ -57,7 +214,7 @@
         try:
             br = [tuple(decodelist(b)) for b in d.splitlines()]
             return br
-        except:
+        except ValueError:
             self._abort(error.ResponseError(_("unexpected response:"), d))
 
     def between(self, pairs):
@@ -68,34 +225,39 @@
             d = self._call("between", pairs=n)
             try:
                 r.extend(l and decodelist(l) or [] for l in d.splitlines())
-            except:
+            except ValueError:
                 self._abort(error.ResponseError(_("unexpected response:"), d))
         return r
 
+    @batchable
     def pushkey(self, namespace, key, old, new):
         if not self.capable('pushkey'):
-            return False
-        d = self._call("pushkey",
-                       namespace=encoding.fromlocal(namespace),
-                       key=encoding.fromlocal(key),
-                       old=encoding.fromlocal(old),
-                       new=encoding.fromlocal(new))
+            yield False, None
+        f = future()
+        yield todict(namespace=encoding.fromlocal(namespace),
+                     key=encoding.fromlocal(key),
+                     old=encoding.fromlocal(old),
+                     new=encoding.fromlocal(new)), f
+        d = f.value
         try:
             d = bool(int(d))
         except ValueError:
             raise error.ResponseError(
                 _('push failed (unexpected response):'), d)
-        return d
+        yield d
 
+    @batchable
     def listkeys(self, namespace):
         if not self.capable('pushkey'):
-            return {}
-        d = self._call("listkeys", namespace=encoding.fromlocal(namespace))
+            yield {}, None
+        f = future()
+        yield todict(namespace=encoding.fromlocal(namespace)), f
+        d = f.value
         r = {}
         for l in d.splitlines():
             k, v = l.split('\t')
             r[encoding.tolocal(k)] = encoding.tolocal(v)
-        return r
+        yield r
 
     def stream_out(self):
         return self._callstream('stream_out')
@@ -113,13 +275,29 @@
                              bases=bases, heads=heads)
         return changegroupmod.unbundle10(self._decompress(f), 'UN')
 
+    def getbundle(self, source, heads=None, common=None):
+        self.requirecap('getbundle', _('look up remote changes'))
+        opts = {}
+        if heads is not None:
+            opts['heads'] = encodelist(heads)
+        if common is not None:
+            opts['common'] = encodelist(common)
+        f = self._callstream("getbundle", **opts)
+        return changegroupmod.unbundle10(self._decompress(f), 'UN')
+
     def unbundle(self, cg, heads, source):
         '''Send cg (a readable file-like object representing the
         changegroup to push, typically a chunkbuffer object) to the
         remote server as a bundle. Return an integer indicating the
         result of the push (see localrepository.addchangegroup()).'''
 
-        ret, output = self._callpush("unbundle", cg, heads=encodelist(heads))
+        if heads != ['force'] and self.capable('unbundlehash'):
+            heads = encodelist(['hashed',
+                                util.sha1(''.join(sorted(heads))).digest()])
+        else:
+            heads = encodelist(heads)
+
+        ret, output = self._callpush("unbundle", cg, heads=heads)
         if ret == "":
             raise error.ResponseError(
                 _('push failed:'), output)
@@ -133,6 +311,15 @@
             self.ui.status(_('remote: '), l)
         return ret
 
+    def debugwireargs(self, one, two, three=None, four=None, five=None):
+        # don't pass optional arguments left at their default value
+        opts = {}
+        if three is not None:
+            opts['three'] = three
+        if four is not None:
+            opts['four'] = four
+        return self._call('debugwireargs', one=one, two=two, **opts)
+
 # server side
 
 class streamres(object):
@@ -152,6 +339,45 @@
     args = proto.getargs(spec)
     return func(repo, proto, *args)
 
+def options(cmd, keys, others):
+    opts = {}
+    for k in keys:
+        if k in others:
+            opts[k] = others[k]
+            del others[k]
+    if others:
+        sys.stderr.write("abort: %s got unexpected arguments %s\n"
+                         % (cmd, ",".join(others)))
+    return opts
+
+def batch(repo, proto, cmds, others):
+    res = []
+    for pair in cmds.split(';'):
+        op, args = pair.split(' ', 1)
+        vals = {}
+        for a in args.split(','):
+            if a:
+                n, v = a.split('=')
+                vals[n] = unescapearg(v)
+        func, spec = commands[op]
+        if spec:
+            keys = spec.split()
+            data = {}
+            for k in keys:
+                if k == '*':
+                    star = {}
+                    for key in vals.keys():
+                        if key not in keys:
+                            star[key] = vals[key]
+                    data['*'] = star
+                else:
+                    data[k] = vals[k]
+            result = func(repo, proto, *[data[k] for k in keys])
+        else:
+            result = func(repo, proto)
+        res.append(escapearg(result))
+    return ';'.join(res)
+
 def between(repo, proto, pairs):
     pairs = [decodelist(p, '-') for p in pairs.split(" ")]
     r = []
@@ -176,7 +402,8 @@
     return "".join(r)
 
 def capabilities(repo, proto):
-    caps = 'lookup changegroupsubset branchmap pushkey'.split()
+    caps = ('lookup changegroupsubset branchmap pushkey known getbundle '
+            'unbundlehash batch').split()
     if _allowstream(repo.ui):
         requiredformats = repo.requirements & repo.supportedformats
         # if our local revlogs are just revlogv1, add 'stream' cap
@@ -186,6 +413,7 @@
         else:
             caps.append('streamreqs=%s' % ','.join(requiredformats))
     caps.append('unbundle=%s' % ','.join(changegroupmod.bundlepriority))
+    caps.append('httpheader=1024')
     return ' '.join(caps)
 
 def changegroup(repo, proto, roots):
@@ -199,6 +427,18 @@
     cg = repo.changegroupsubset(bases, heads, 'serve')
     return streamres(proto.groupchunks(cg))
 
+def debugwireargs(repo, proto, one, two, others):
+    # only accept optional args from the known set
+    opts = options('debugwireargs', ['three', 'four'], others)
+    return repo.debugwireargs(one, two, **opts)
+
+def getbundle(repo, proto, others):
+    opts = options('getbundle', ['heads', 'common'], others)
+    for k, v in opts.iteritems():
+        opts[k] = decodelist(v)
+    cg = repo.getbundle('serve', **opts)
+    return streamres(proto.groupchunks(cg))
+
 def heads(repo, proto):
     h = repo.heads()
     return encodelist(h) + "\n"
@@ -228,13 +468,16 @@
         success = 0
     return "%s %s\n" % (success, r)
 
+def known(repo, proto, nodes, others):
+    return ''.join(b and "1" or "0" for b in repo.known(decodelist(nodes)))
+
 def pushkey(repo, proto, namespace, key, old, new):
     # compatibility with pre-1.8 clients which were accidentally
     # sending raw binary nodes rather than utf-8-encoded hex
     if len(new) == 20 and new.encode('string-escape') != new:
         # looks like it could be a binary node
         try:
-            u = new.decode('utf-8')
+            new.decode('utf-8')
             new = encoding.tolocal(new) # but cleanly decodes as UTF-8
         except UnicodeDecodeError:
             pass # binary, leave unmodified
@@ -298,7 +541,9 @@
 
     def check_heads():
         heads = repo.heads()
-        return their_heads == ['force'] or their_heads == heads
+        heads_hash = util.sha1(''.join(sorted(heads))).digest()
+        return (their_heads == ['force'] or their_heads == heads or
+                their_heads == ['hashed', heads_hash])
 
     proto.redirect()
 
@@ -337,14 +582,18 @@
         os.unlink(tempname)
 
 commands = {
+    'batch': (batch, 'cmds *'),
     'between': (between, 'pairs'),
     'branchmap': (branchmap, ''),
     'branches': (branches, 'nodes'),
     'capabilities': (capabilities, ''),
     'changegroup': (changegroup, 'roots'),
     'changegroupsubset': (changegroupsubset, 'bases heads'),
+    'debugwireargs': (debugwireargs, 'one two *'),
+    'getbundle': (getbundle, '*'),
     'heads': (heads, ''),
     'hello': (hello, ''),
+    'known': (known, 'nodes *'),
     'listkeys': (listkeys, 'namespace'),
     'lookup': (lookup, 'key'),
     'pushkey': (pushkey, 'namespace key old new'),
--- a/setup.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/setup.py	Sat Jun 18 17:03:01 2011 -0500
@@ -4,7 +4,7 @@
 # 'python setup.py install', or
 # 'python setup.py --help' for more options
 
-import sys
+import sys, platform
 if not hasattr(sys, 'version_info') or sys.version_info < (2, 4, 0, 'final'):
     raise SystemExit("Mercurial requires Python 2.4 or later.")
 
@@ -36,17 +36,27 @@
     raise SystemExit(
         "Couldn't import standard zlib (incomplete Python install).")
 
+# The base IronPython distribution (as of 2.7.1) doesn't support bz2
+isironpython = False
 try:
-    import bz2
+    isironpython = platform.python_implementation().lower().find("ironpython") != -1
 except:
-    raise SystemExit(
-        "Couldn't import standard bz2 (incomplete Python install).")
+    pass
+
+if isironpython:
+    print "warning: IronPython detected (no bz2 support)"
+else:
+    try:
+        import bz2
+    except:
+        raise SystemExit(
+            "Couldn't import standard bz2 (incomplete Python install).")
 
 import os, subprocess, time
 import shutil
 import tempfile
 from distutils import log
-from distutils.core import setup, Extension
+from distutils.core import setup, Command, Extension
 from distutils.dist import Distribution
 from distutils.command.build import build
 from distutils.command.build_ext import build_ext
@@ -54,7 +64,7 @@
 from distutils.command.install_scripts import install_scripts
 from distutils.spawn import spawn, find_executable
 from distutils.ccompiler import new_compiler
-from distutils.errors import CCompilerError
+from distutils.errors import CCompilerError, DistutilsExecError
 from distutils.sysconfig import get_python_inc
 from distutils.version import StrictVersion
 
@@ -98,24 +108,8 @@
 try:
     import py2exe
     py2exeloaded = True
-
-    # Help py2exe to find win32com.shell
-    try:
-        import modulefinder
-        import win32com
-        for p in win32com.__path__[1:]: # Take the path to win32comext
-            modulefinder.AddPackagePath("win32com", p)
-        pn = "win32com.shell"
-        __import__(pn)
-        m = sys.modules[pn]
-        for p in m.__path__[1:]:
-            modulefinder.AddPackagePath(pn, p)
-    except ImportError:
-        pass
-
 except ImportError:
     py2exeloaded = False
-    pass
 
 def runcmd(cmd, env):
     p = subprocess.Popen(cmd, stdout=subprocess.PIPE,
@@ -266,6 +260,34 @@
             else:
                 yield module
 
+class buildhgextindex(Command):
+    description = 'generate prebuilt index of hgext (for frozen package)'
+    user_options = []
+    _indexfilename = 'hgext/__index__.py'
+
+    def initialize_options(self):
+        pass
+
+    def finalize_options(self):
+        pass
+
+    def run(self):
+        if os.path.exists(self._indexfilename):
+            os.unlink(self._indexfilename)
+
+        # here no extension enabled, disabled() lists up everything
+        code = ('import pprint; from mercurial import extensions; '
+                'pprint.pprint(extensions.disabled())')
+        out, err = runcmd([sys.executable, '-c', code], env)
+        if err:
+            raise DistutilsExecError(err)
+
+        f = open(self._indexfilename, 'w')
+        f.write('# this file is autogenerated by setup.py\n')
+        f.write('docs = ')
+        f.write(out)
+        f.close()
+
 class hginstallscripts(install_scripts):
     '''
     This is a specialization of install_scripts that replaces the @LIBDIR@ with
@@ -315,10 +337,12 @@
 cmdclass = {'build_mo': hgbuildmo,
             'build_ext': hgbuildext,
             'build_py': hgbuildpy,
+            'build_hgextindex': buildhgextindex,
             'install_scripts': hginstallscripts}
 
-packages = ['mercurial', 'mercurial.hgweb', 'hgext', 'hgext.convert',
-            'hgext.highlight', 'hgext.zeroconf']
+packages = ['mercurial', 'mercurial.hgweb',
+            'mercurial.httpclient', 'mercurial.httpclient.tests',
+            'hgext', 'hgext.convert', 'hgext.highlight', 'hgext.zeroconf']
 
 pymodules = []
 
@@ -330,11 +354,17 @@
     Extension('mercurial.parsers', ['mercurial/parsers.c']),
     ]
 
+osutil_ldflags = []
+
+if sys.platform == 'darwin':
+    osutil_ldflags += ['-framework', 'ApplicationServices']
+
 # disable osutil.c under windows + python 2.4 (issue1364)
 if sys.platform == 'win32' and sys.version_info < (2, 5, 0, 'final'):
     pymodules.append('mercurial.pure.osutil')
 else:
-    extmodules.append(Extension('mercurial.osutil', ['mercurial/osutil.c']))
+    extmodules.append(Extension('mercurial.osutil', ['mercurial/osutil.c'],
+                                extra_link_args=osutil_ldflags))
 
 if sys.platform == 'linux2' and os.uname()[2] > '2.6':
     # The inotify extension is only usable with Linux 2.6 kernels.
@@ -372,6 +402,8 @@
         {'script':'hg',
          'copyright':'Copyright (C) 2005-2010 Matt Mackall and others',
          'product_version':version}]
+    # sub command of 'build' because 'py2exe' does not handle sub_commands
+    build.sub_commands.insert(0, ('build_hgextindex', None))
 
 if os.name == 'nt':
     # Windows binary file versions for exe/dll files must have the
@@ -385,7 +417,7 @@
     # Also parse only first digit, because 3.2.1 can't be parsed nicely
     if (version.startswith('Xcode') and
         StrictVersion(version.split()[1]) >= StrictVersion('4.0')):
-        os.environ['ARCHFLAGS'] = '-arch i386 -arch x86_64'
+        os.environ['ARCHFLAGS'] = ''
 
 setup(name='mercurial',
       version=setupversion,
--- a/tests/autodiff.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/autodiff.py	Sat Jun 18 17:03:01 2011 -0500
@@ -1,7 +1,7 @@
 # Extension dedicated to test patch.diff() upgrade modes
 #
 #
-from mercurial import cmdutil, patch, util
+from mercurial import scmutil, patch, util
 
 def autodiff(ui, repo, *pats, **opts):
     diffopts = patch.diffopts(ui, opts)
@@ -28,8 +28,8 @@
     else:
         raise util.Abort('--git must be yes, no or auto')
 
-    node1, node2 = cmdutil.revpair(repo, [])
-    m = cmdutil.match(repo, pats, opts)
+    node1, node2 = scmutil.revpair(repo, [])
+    m = scmutil.match(repo[node2], pats, opts)
     it = patch.diff(repo, node1, node2, match=m, opts=diffopts,
                     losedatafn=losedatafn)
     for chunk in it:
Binary file tests/bundles/darcs1.hg has changed
Binary file tests/bundles/legacy-encoding.hg has changed
Binary file tests/bundles/rebase.hg has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/bundles/rebase.sh	Sat Jun 18 17:03:01 2011 -0500
@@ -0,0 +1,44 @@
+#!/bin/bash
+hg init rebase
+cd rebase
+
+#  @  7: 'H'
+#  |
+#  | o  6: 'G'
+#  |/|
+#  o |  5: 'F'
+#  | |
+#  | o  4: 'E'
+#  |/
+#  | o  3: 'D'
+#  | |
+#  | o  2: 'C'
+#  | |
+#  | o  1: 'B'
+#  |/
+#  o  0: 'A'
+
+echo A > A
+hg ci -Am A
+echo B > B
+hg ci -Am B
+echo C > C
+hg ci -Am C
+echo D > D
+hg ci -Am D
+hg up -q -C 0
+echo E > E
+hg ci -Am E
+hg up -q -C 0
+echo F > F
+hg ci -Am F
+hg merge -r 4
+hg ci -m G
+hg up -q -C 5
+echo H > H
+hg ci -Am H
+
+hg bundle -a ../rebase.hg
+
+cd ..
+rm -Rf rebase
Binary file tests/bundles/remote.hg has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/bundles/remote.sh	Sat Jun 18 17:03:01 2011 -0500
@@ -0,0 +1,32 @@
+#!/bin/bash
+hg init remote
+cd remote
+
+echo "0" >> afile
+hg add afile
+hg commit -m "0.0"
+echo "1" >> afile
+hg commit -m "0.1"
+echo "2" >> afile
+hg commit -m "0.2"
+echo "3" >> afile
+hg commit -m "0.3"
+hg update -C 0
+echo "1" >> afile
+hg commit -m "1.1"
+echo "2" >> afile
+hg commit -m "1.2"
+echo "a line" > fred
+echo "3" >> afile
+hg add fred
+hg commit -m "1.3"
+hg mv afile adifferentfile
+hg commit -m "1.3m"
+hg update -C 3
+hg mv afile anotherfile
+hg commit -m "0.3m"
+
+hg bundle -a ../remote.hg
+
+cd ..
+rm -Rf remote
Binary file tests/bundles/tampered.hg has changed
Binary file tests/bundles/test-keyword.hg has changed
Binary file tests/bundles/test-manifest.hg has changed
Binary file tests/bundles/test-merge-symlinks.hg has changed
Binary file tests/bundles/test-no-symlinks.hg has changed
Binary file tests/darcs1.hg has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/dummyssh	Sat Jun 18 17:03:01 2011 -0500
@@ -0,0 +1,20 @@
+#!/usr/bin/env python
+
+import sys
+import os
+
+os.chdir(os.getenv('TESTTMP'))
+
+if sys.argv[1] != "user@dummy":
+    sys.exit(-1)
+
+os.environ["SSH_CLIENT"] = "127.0.0.1 1 2"
+
+log = open("dummylog", "ab")
+log.write("Got arguments")
+for i, arg in enumerate(sys.argv[1:]):
+    log.write(" %d:%s" % (i+1, arg))
+log.write("\n")
+log.close()
+r = os.system(sys.argv[2])
+sys.exit(bool(r))
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/filterpyflakes.py	Sat Jun 18 17:03:01 2011 -0500
@@ -0,0 +1,38 @@
+#!/usr/bin/env python
+
+# Filter output by pyflakes to control which warnings we check
+
+import sys, re, os
+
+def makekey(message):
+    # "path/file:line: message"
+    match = re.search(r"(line \d+)", message)
+    line = ''
+    if match:
+        line = match.group(0)
+        message = re.sub(r"(line \d+)", '', message)
+    return re.sub(r"([^:]*):([^:]+):([^']*)('[^']*')(.*)$",
+                  r'\3:\5:\4:\1:\2:' + line,
+                  message)
+
+lines = []
+for line in sys.stdin:
+    # We whitelist tests
+    pats = [
+            r"imported but unused",
+            r"local variable '.*' is assigned to but never used",
+            r"unable to detect undefined names",
+           ]
+    if not re.search('|'.join(pats), line):
+        continue
+    fn = line.split(':', 1)[0]
+    f = open(os.path.join(os.path.dirname(os.path.dirname(__file__)), fn))
+    data = f.read()
+    f.close()
+    if 'no-check-code' in data:
+        continue
+    lines.append(line)
+
+for line in sorted(lines, key = makekey):
+    sys.stdout.write(line)
+print
--- a/tests/hghave	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/hghave	Sat Jun 18 17:03:01 2011 -0500
@@ -52,7 +52,7 @@
 
 def has_mtn():
     return matchoutput('mtn --version', r'monotone', True) and not matchoutput(
-        'mtn --version', r'monotone 0\.(\d|[12]\d|3[01])[^\d]', True)
+        'mtn --version', r'monotone 0\.', True)
 
 def has_eol_in_paths():
     try:
@@ -172,6 +172,11 @@
     finally:
         os.rmdir(d)
 
+def has_pyflakes():
+    return matchoutput('echo "import re" 2>&1 | pyflakes',
+                       r"<stdin>:1: 're' imported but unused",
+                       True)
+
 def has_pygments():
     try:
         import pygments
@@ -207,9 +212,10 @@
     "icasefs": (has_icasefs, "case insensitive file system"),
     "inotify": (has_inotify, "inotify extension support"),
     "lsprof": (has_lsprof, "python lsprof module"),
-    "mtn": (has_mtn, "monotone client (> 0.31)"),
+    "mtn": (has_mtn, "monotone client (>= 1.0)"),
     "outer-repo": (has_outer_repo, "outer repo"),
     "p4": (has_p4, "Perforce server and client"),
+    "pyflakes": (has_pyflakes, "Pyflakes python linter"),
     "pygments": (has_pygments, "Pygments source highlighting library"),
     "ssl": (has_ssl, "python >= 2.6 ssl module and python OpenSSL"),
     "svn": (has_svn, "subversion client and admin tools"),
Binary file tests/legacy-encoding.hg has changed
--- a/tests/md5sum.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/md5sum.py	Sat Jun 18 17:03:01 2011 -0500
@@ -29,7 +29,7 @@
 
     m = md5()
     try:
-        while 1:
+        while True:
             data = fp.read(8192)
             if not data:
                 break
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/notcapable	Sat Jun 18 17:03:01 2011 -0500
@@ -0,0 +1,19 @@
+# Disable the $CAP wire protocol capability.
+
+if test -z "$CAP"
+then
+    echo "CAP environment variable not set."
+fi
+
+cat > notcapable-$CAP.py << EOF
+from mercurial import extensions, repo
+def extsetup():
+    extensions.wrapfunction(repo.repository, 'capable', wrapper)
+def wrapper(orig, self, name, *args, **kwargs):
+    if name in '$CAP'.split(' '):
+        return False
+    return orig(self, name, *args, **kwargs)
+EOF
+
+echo '[extensions]' >> $HGRCPATH
+echo "notcapable-$CAP = `pwd`/notcapable-$CAP.py" >> $HGRCPATH
--- a/tests/run-tests.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/run-tests.py	Sat Jun 18 17:03:01 2011 -0500
@@ -53,16 +53,37 @@
 import tempfile
 import time
 import re
+import threading
+
+processlock = threading.Lock()
 
 closefds = os.name == 'posix'
-def Popen4(cmd, bufsize=-1):
-    p = subprocess.Popen(cmd, shell=True, bufsize=bufsize,
+def Popen4(cmd, wd, timeout):
+    processlock.acquire()
+    p = subprocess.Popen(cmd, shell=True, bufsize=-1, cwd=wd,
                          close_fds=closefds,
                          stdin=subprocess.PIPE, stdout=subprocess.PIPE,
                          stderr=subprocess.STDOUT)
+    processlock.release()
+
     p.fromchild = p.stdout
     p.tochild = p.stdin
     p.childerr = p.stderr
+
+    p.timeout = False
+    if timeout:
+        def t():
+            start = time.time()
+            while time.time() - start < timeout and p.returncode is None:
+                time.sleep(1)
+            p.timeout = True
+            if p.returncode is None:
+                try:
+                    p.terminate()
+                except OSError:
+                    pass
+        threading.Thread(target=t).start()
+
     return p
 
 # reserved exit code to skip test (used by hghave)
@@ -80,14 +101,38 @@
     'jobs': ('HGTEST_JOBS', 1),
     'timeout': ('HGTEST_TIMEOUT', 180),
     'port': ('HGTEST_PORT', 20059),
+    'shell': ('HGTEST_SHELL', '/bin/sh'),
 }
 
+def parselistfiles(files, listtype, warn=True):
+    entries = dict()
+    for filename in files:
+        try:
+            path = os.path.expanduser(os.path.expandvars(filename))
+            f = open(path, "r")
+        except IOError, err:
+            if err.errno != errno.ENOENT:
+                raise
+            if warn:
+                print "warning: no such %s file: %s" % (listtype, filename)
+            continue
+
+        for line in f.readlines():
+            line = line.split('#', 1)[0].strip()
+            if line:
+                entries[line] = filename
+
+        f.close()
+    return entries
+
 def parseargs():
     parser = optparse.OptionParser("%prog [options] [tests]")
 
     # keep these sorted
     parser.add_option("--blacklist", action="append",
         help="skip tests listed in the specified blacklist file")
+    parser.add_option("--whitelist", action="append",
+        help="always run tests listed in the specified whitelist file")
     parser.add_option("-C", "--annotate", action="store_true",
         help="output files annotated with coverage")
     parser.add_option("--child", type="int",
@@ -125,6 +170,8 @@
         help="retest failed tests")
     parser.add_option("-S", "--noskips", action="store_true",
         help="don't report skip tests verbosely")
+    parser.add_option("--shell", type="string",
+        help="shell to use (default: $%s or %s)" % defaults['shell'])
     parser.add_option("-t", "--timeout", type="int",
         help="kill errant tests after TIMEOUT seconds"
              " (default: $%s or %d)" % defaults['timeout'])
@@ -141,9 +188,11 @@
              "temporary installation")
     parser.add_option("-3", "--py3k-warnings", action="store_true",
         help="enable Py3k warnings on Python 2.6+")
+    parser.add_option('--extra-config-opt', action="append",
+                      help='set the given config opt in the test hgrc')
 
-    for option, default in defaults.items():
-        defaults[option] = int(os.environ.get(*default))
+    for option, (envvar, default) in defaults.items():
+        defaults[option] = type(default)(os.environ.get(envvar, default))
     parser.set_defaults(**defaults)
     (options, args) = parser.parse_args()
 
@@ -156,7 +205,7 @@
                 os.access(options.with_hg, os.X_OK)):
             parser.error('--with-hg must specify an executable hg script')
         if not os.path.basename(options.with_hg) == 'hg':
-            sys.stderr.write('warning: --with-hg should specify an hg script')
+            sys.stderr.write('warning: --with-hg should specify an hg script\n')
     if options.local:
         testdir = os.path.dirname(os.path.realpath(sys.argv[0]))
         hgbin = os.path.join(os.path.dirname(testdir), 'hg')
@@ -187,12 +236,14 @@
         else:
             pid = None
         def vlog(*msg):
+            iolock.acquire()
             if pid:
                 print pid,
             for m in msg:
                 print m,
             print
             sys.stdout.flush()
+            iolock.release()
     else:
         vlog = lambda *msg: None
 
@@ -211,29 +262,20 @@
             sys.stderr.write(
                 'warning: --timeout option ignored with --debug\n')
         options.timeout = 0
+    if options.timeout and not hasattr(subprocess.Popen, 'terminate'):
+        sys.stderr.write('warning: timeout is not supported on this '
+                         'platform and will be ignored\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+')
     if options.blacklist:
-        blacklist = dict()
-        for filename in options.blacklist:
-            try:
-                path = os.path.expanduser(os.path.expandvars(filename))
-                f = open(path, "r")
-            except IOError, err:
-                if err.errno != errno.ENOENT:
-                    raise
-                print "warning: no such blacklist file: %s" % filename
-                continue
-
-            for line in f.readlines():
-                line = line.strip()
-                if line and not line.startswith('#'):
-                    blacklist[line] = filename
-
-            f.close()
-
-        options.blacklist = blacklist
+        options.blacklist = parselistfiles(options.blacklist, 'blacklist')
+    if options.whitelist:
+        options.whitelisted = parselistfiles(options.whitelist, 'whitelist',
+                                             warn=options.child is None)
+    else:
+        options.whitelisted = {}
 
     return (options, args)
 
@@ -277,6 +319,7 @@
     return missing, failed
 
 def showdiff(expected, output, ref, err):
+    print
     for line in difflib.unified_diff(expected, output, ref, err):
         sys.stdout.write(line)
 
@@ -284,7 +327,7 @@
     """Search PATH for a executable program"""
     for p in os.environ.get('PATH', os.defpath).split(os.pathsep):
         name = os.path.join(p, program)
-        if os.access(name, os.X_OK):
+        if os.name == 'nt' or os.access(name, os.X_OK):
             return name
     return None
 
@@ -334,12 +377,14 @@
     # some tests run python interpreter. they must use same
     # interpreter we use or bad things will happen.
     exedir, exename = os.path.split(sys.executable)
-    if exename == 'python':
-        path = findprogram('python')
+    if exename in ('python', 'python.exe'):
+        path = findprogram(exename)
         if os.path.dirname(path) == exedir:
             return
+    else:
+        exename = 'python'
     vlog('# Making python executable in test path use correct Python')
-    mypython = os.path.join(BINDIR, 'python')
+    mypython = os.path.join(BINDIR, exename)
     try:
         os.symlink(sys.executable, mypython)
     except AttributeError:
@@ -406,6 +451,22 @@
             f.write(line + '\n')
         f.close()
 
+    hgbat = os.path.join(BINDIR, 'hg.bat')
+    if os.path.isfile(hgbat):
+        # hg.bat expects to be put in bin/scripts while run-tests.py
+        # installation layout put it in bin/ directly. Fix it
+        f = open(hgbat, 'rb')
+        data = f.read()
+        f.close()
+        if '"%~dp0..\python" "%~dp0hg" %*' in data:
+            data = data.replace('"%~dp0..\python" "%~dp0hg" %*',
+                                '"%~dp0python" "%~dp0hg" %*')
+            f = open(hgbat, 'wb')
+            f.write(data)
+            f.close()
+        else:
+            print 'WARNING: cannot fix hg.bat reference to python.exe'
+
     if options.anycoverage:
         custom = os.path.join(TESTDIR, 'sitecustomize.py')
         target = os.path.join(PYTHONDIR, 'sitecustomize.py')
@@ -439,22 +500,16 @@
             os.mkdir(adir)
         covrun('-i', '-a', '"--directory=%s"' % adir, '"--omit=%s"' % omit)
 
-class Timeout(Exception):
-    pass
-
-def alarmed(signum, frame):
-    raise Timeout
-
-def pytest(test, options, replacements):
+def pytest(test, wd, options, replacements):
     py3kswitch = options.py3k_warnings and ' -3' or ''
     cmd = '%s%s "%s"' % (PYTHON, py3kswitch, test)
     vlog("# Running", cmd)
-    return run(cmd, options, replacements)
+    return run(cmd, wd, options, replacements)
 
-def shtest(test, options, replacements):
+def shtest(test, wd, options, replacements):
     cmd = '"%s"' % test
     vlog("# Running", cmd)
-    return run(cmd, options, replacements)
+    return run(cmd, wd, options, replacements)
 
 needescape = re.compile(r'[\x00-\x08\x0b-\x1f\x7f-\xff]').search
 escapesub = re.compile(r'[\x00-\x08\x0b-\x1f\\\x7f-\xff]').sub
@@ -465,7 +520,7 @@
 def stringescape(s):
     return escapesub(escapef, s)
 
-def tsttest(test, options, replacements):
+def tsttest(test, wd, options, replacements):
     t = open(test)
     out = []
     script = []
@@ -504,9 +559,9 @@
             os.write(fd, l)
         os.close(fd)
 
-        cmd = '/bin/sh "%s"' % name
+        cmd = '"%s" "%s"' % (options.shell, name)
         vlog("# Running", cmd)
-        exitcode, output = run(cmd, options, replacements)
+        exitcode, output = run(cmd, wd, options, replacements)
         # do not merge output if skipped, return hghave message instead
         # similarly, with --debug, output is None
         if exitcode == SKIPPED_STATUS or output is None:
@@ -585,71 +640,129 @@
     return exitcode, postout
 
 wifexited = getattr(os, "WIFEXITED", lambda x: False)
-def run(cmd, options, replacements):
+def run(cmd, wd, options, replacements):
     """Run command in a sub-process, capturing the output (stdout and stderr).
     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)
+        proc = subprocess.Popen(cmd, shell=True, cwd=wd)
         ret = proc.wait()
         return (ret, None)
 
-    if os.name == 'nt' or sys.platform.startswith('java'):
-        tochild, fromchild = os.popen4(cmd)
-        tochild.close()
-        output = fromchild.read()
-        ret = fromchild.close()
-        if ret is None:
-            ret = 0
-    else:
-        proc = Popen4(cmd)
-        def cleanup():
-            os.kill(proc.pid, signal.SIGTERM)
-            ret = proc.wait()
-            if ret == 0:
-                ret = signal.SIGTERM << 8
-            killdaemons()
-            return ret
+    proc = Popen4(cmd, wd, options.timeout)
+    def cleanup():
+        try:
+            proc.terminate()
+        except OSError:
+            pass
+        ret = proc.wait()
+        if ret == 0:
+            ret = signal.SIGTERM << 8
+        killdaemons()
+        return ret
+
+    output = ''
+    proc.tochild.close()
 
-        try:
-            output = ''
-            proc.tochild.close()
-            output = proc.fromchild.read()
-            ret = proc.wait()
-            if wifexited(ret):
-                ret = os.WEXITSTATUS(ret)
-        except Timeout:
-            vlog('# Process %d timed out - killing it' % proc.pid)
-            ret = cleanup()
-            output += ("\n### Abort: timeout after %d seconds.\n"
-                       % options.timeout)
-        except KeyboardInterrupt:
-            vlog('# Handling keyboard interrupt')
-            cleanup()
-            raise
+    try:
+        output = proc.fromchild.read()
+    except KeyboardInterrupt:
+        vlog('# Handling keyboard interrupt')
+        cleanup()
+        raise
+
+    ret = proc.wait()
+    if wifexited(ret):
+        ret = os.WEXITSTATUS(ret)
+
+    if proc.timeout:
+        ret = 'timeout'
+
+    if ret:
+        killdaemons()
 
     for s, r in replacements:
         output = re.sub(s, r, output)
     return ret, splitnewlines(output)
 
-def runone(options, test, skips, fails):
+def runone(options, test):
     '''tristate output:
     None -> skipped
     True -> passed
     False -> failed'''
 
+    global results, resultslock, iolock
+
+    testpath = os.path.join(TESTDIR, test)
+
+    def result(l, e):
+        resultslock.acquire()
+        results[l].append(e)
+        resultslock.release()
+
     def skip(msg):
         if not options.verbose:
-            skips.append((test, msg))
+            result('s', (test, msg))
         else:
+            iolock.acquire()
             print "\nSkipping %s: %s" % (testpath, msg)
+            iolock.release()
         return None
 
-    def fail(msg):
-        fails.append((test, msg))
+    def fail(msg, ret):
         if not options.nodiff:
+            iolock.acquire()
             print "\nERROR: %s %s" % (testpath, msg)
-        return None
+            iolock.release()
+        if (not ret and options.interactive
+            and os.path.exists(testpath + ".err")):
+            iolock.acquire()
+            print "Accept this change? [n] ",
+            answer = sys.stdin.readline().strip()
+            iolock.release()
+            if answer.lower() in "y yes".split():
+                if test.endswith(".t"):
+                    rename(testpath + ".err", testpath)
+                else:
+                    rename(testpath + ".err", testpath + ".out")
+                return
+        result('f', (test, msg))
+
+    def success():
+        result('p', test)
+
+    def ignore(msg):
+        result('i', (test, msg))
+
+    if (os.path.basename(test).startswith("test-") and '~' not in test and
+        ('.' not in test or test.endswith('.py') or
+         test.endswith('.bat') or test.endswith('.t'))):
+        if not os.path.exists(test):
+            skip("doesn't exist")
+            return None
+    else:
+        vlog('# Test file', test, 'not supported, ignoring')
+        return None # not a supported test, don't record
+
+    if not (options.whitelisted and test in options.whitelisted):
+        if options.blacklist and test in options.blacklist:
+            skip("blacklisted")
+            return None
+
+        if options.retest and not os.path.exists(test + ".err"):
+            ignore("not retesting")
+            return None
+
+        if options.keywords:
+            fp = open(test)
+            t = fp.read().lower() + test.lower()
+            fp.close()
+            for k in options.keywords.lower().split():
+                if k in t:
+                    break
+                else:
+                    ignore("doesn't match keyword")
+                    return None
 
     vlog("# Test", test)
 
@@ -667,9 +780,14 @@
         hgrc.write('[inotify]\n')
         hgrc.write('pidfile=%s\n' % DAEMON_PIDS)
         hgrc.write('appendpid=True\n')
+    if options.extra_config_opt:
+        for opt in options.extra_config_opt:
+            section, key = opt.split('.', 1)
+            assert '=' in key, ('extra config opt %s must '
+                                'have an = for assignment' % opt)
+            hgrc.write('[%s]\n%s\n' % (section, key))
     hgrc.close()
 
-    testpath = os.path.join(TESTDIR, test)
     ref = os.path.join(TESTDIR, test+".out")
     err = os.path.join(TESTDIR, test+".err")
     if os.path.exists(err):
@@ -694,14 +812,11 @@
         runner = shtest
 
     # Make a tmp subdirectory to work in
-    testtmp = os.environ["TESTTMP"] = os.path.join(HGTMP, test)
-    os.mkdir(testtmp)
-    os.chdir(testtmp)
+    testtmp = os.environ["TESTTMP"] = os.environ["HOME"] = \
+        os.path.join(HGTMP, os.path.basename(test))
 
-    if options.timeout > 0:
-        signal.alarm(options.timeout)
-
-    ret, out = runner(testpath, options, [
+    os.mkdir(testtmp)
+    ret, out = runner(testpath, testtmp, options, [
         (re.escape(testtmp), '$TESTTMP'),
         (r':%s\b' % options.port, ':$HGPORT'),
         (r':%s\b' % (options.port + 1), ':$HGPORT1'),
@@ -709,9 +824,6 @@
         ])
     vlog("# Ret was:", ret)
 
-    if options.timeout > 0:
-        signal.alarm(0)
-
     mark = '.'
 
     skipped = (ret == SKIPPED_STATUS)
@@ -744,33 +856,41 @@
         if not missing:
             missing = ['irrelevant']
         if failed:
-            fail("hghave failed checking for %s" % failed[-1])
+            fail("hghave failed checking for %s" % failed[-1], ret)
             skipped = False
         else:
             skip(missing[-1])
+    elif ret == 'timeout':
+        mark = 't'
+        fail("timed out", ret)
     elif out != refout:
         mark = '!'
-        if ret:
-            fail("output changed and returned error code %d" % ret)
-        else:
-            fail("output changed")
         if not options.nodiff:
+            iolock.acquire()
             if options.view:
                 os.system("%s %s %s" % (options.view, ref, err))
             else:
                 showdiff(refout, out, ref, err)
+            iolock.release()
+        if ret:
+            fail("output changed and returned error code %d" % ret, ret)
+        else:
+            fail("output changed", ret)
         ret = 1
     elif ret:
         mark = '!'
-        fail("returned error code %d" % ret)
+        fail("returned error code %d" % ret, ret)
+    else:
+        success()
 
     if not options.verbose:
+        iolock.acquire()
         sys.stdout.write(mark)
         sys.stdout.flush()
+        iolock.release()
 
     killdaemons()
 
-    os.chdir(TESTDIR)
     if not options.keep_tmpdir:
         shutil.rmtree(testtmp, True)
     if skipped:
@@ -799,7 +919,7 @@
     the one we expect it to be.  If not, print a warning to stderr."""
     expecthg = os.path.join(PYTHONDIR, 'mercurial')
     actualhg = _gethgpath()
-    if actualhg != expecthg:
+    if os.path.abspath(actualhg) != os.path.abspath(expecthg):
         sys.stderr.write('warning: %s with unexpected mercurial lib: %s\n'
                          '         (expected %s)\n'
                          % (verb, actualhg, expecthg))
@@ -811,7 +931,19 @@
 
     optcopy = dict(options.__dict__)
     optcopy['jobs'] = 1
+
+    # Because whitelist has to override keyword matches, we have to
+    # actually load the whitelist in the children as well, so we allow
+    # the list of whitelist files to pass through and be parsed in the
+    # children, but not the dict of whitelisted tests resulting from
+    # the parse, used here to override blacklisted tests.
+    whitelist = optcopy['whitelisted'] or []
+    del optcopy['whitelisted']
+
+    blacklist = optcopy['blacklist'] or []
     del optcopy['blacklist']
+    blacklisted = []
+
     if optcopy['with_hg'] is None:
         optcopy['with_hg'] = os.path.join(BINDIR, "hg")
     optcopy.pop('anycoverage', None)
@@ -821,6 +953,9 @@
         name = '--' + opt.replace('_', '-')
         if value is True:
             opts.append(name)
+        elif isinstance(value, list):
+            for v in value:
+                opts.append(name + '=' + str(v))
         elif value is not None:
             opts.append(name + '=' + str(value))
 
@@ -830,7 +965,11 @@
         for job in jobs:
             if not tests:
                 break
-            job.append(tests.pop())
+            test = tests.pop()
+            if test not in whitelist and test in blacklist:
+                blacklisted.append(test)
+            else:
+                job.append(test)
     fps = {}
 
     for j, job in enumerate(jobs):
@@ -868,9 +1007,12 @@
         vlog('pid %d exited, status %d' % (pid, status))
         failures |= status
     print
+    skipped += len(blacklisted)
     if not options.noskips:
         for s in skips:
             print "Skipped %s: %s" % (s[0], s[1])
+        for s in blacklisted:
+            print "Skipped %s: blacklisted" % s
     for s in fails:
         print "Failed %s: %s" % (s[0], s[1])
 
@@ -882,6 +1024,16 @@
         outputcoverage(options)
     sys.exit(failures != 0)
 
+results = dict(p=[], f=[], s=[], i=[])
+resultslock = threading.Lock()
+iolock = threading.Lock()
+
+def runqueue(options, tests, results):
+    for test in tests:
+        ret = runone(options, test)
+        if options.first and ret is not None and not ret:
+            break
+
 def runtests(options, tests):
     global DAEMON_PIDS, HGRCPATH
     DAEMON_PIDS = os.environ["DAEMON_PIDS"] = os.path.join(HGTMP, 'daemon.pids')
@@ -892,19 +1044,6 @@
             installhg(options)
             _checkhglib("Testing")
 
-        if options.timeout > 0:
-            try:
-                signal.signal(signal.SIGALRM, alarmed)
-                vlog('# Running each test with %d second timeout' %
-                     options.timeout)
-            except AttributeError:
-                print 'WARNING: cannot run tests with timeouts'
-                options.timeout = 0
-
-        tested = 0
-        failed = 0
-        skipped = 0
-
         if options.restart:
             orig = list(tests)
             while tests:
@@ -915,69 +1054,30 @@
                 print "running all tests"
                 tests = orig
 
-        skips = []
-        fails = []
-
-        for test in tests:
-            if options.blacklist:
-                filename = options.blacklist.get(test)
-                if filename is not None:
-                    skips.append((test, "blacklisted (%s)" % filename))
-                    skipped += 1
-                    continue
-
-            if options.retest and not os.path.exists(test + ".err"):
-                skipped += 1
-                continue
+        runqueue(options, tests, results)
 
-            if options.keywords:
-                fp = open(test)
-                t = fp.read().lower() + test.lower()
-                fp.close()
-                for k in options.keywords.lower().split():
-                    if k in t:
-                        break
-                else:
-                    skipped += 1
-                    continue
-
-            ret = runone(options, test, skips, fails)
-            if ret is None:
-                skipped += 1
-            elif not ret:
-                if options.interactive:
-                    print "Accept this change? [n] ",
-                    answer = sys.stdin.readline().strip()
-                    if answer.lower() in "y yes".split():
-                        if test.endswith(".t"):
-                            rename(test + ".err", test)
-                        else:
-                            rename(test + ".err", test + ".out")
-                        tested += 1
-                        fails.pop()
-                        continue
-                failed += 1
-                if options.first:
-                    break
-            tested += 1
+        failed = len(results['f'])
+        tested = len(results['p']) + failed
+        skipped = len(results['s'])
+        ignored = len(results['i'])
 
         if options.child:
             fp = os.fdopen(options.child, 'w')
             fp.write('%d\n%d\n%d\n' % (tested, skipped, failed))
-            for s in skips:
+            for s in results['s']:
                 fp.write("%s %s\n" % s)
-            for s in fails:
+            for s in results['f']:
                 fp.write("%s %s\n" % s)
             fp.close()
         else:
             print
-            for s in skips:
+            for s in results['s']:
                 print "Skipped %s: %s" % s
-            for s in fails:
+            for s in results['f']:
                 print "Failed %s: %s" % s
             _checkhglib("Tested")
             print "# Ran %d tests, %d skipped, %d failed." % (
-                tested, skipped, failed)
+                tested, skipped + ignored, failed)
 
         if options.anycoverage:
             outputcoverage(options)
@@ -999,22 +1099,7 @@
         args = os.listdir(".")
     args.sort()
 
-    tests = []
-    skipped = []
-    for test in args:
-        if (test.startswith("test-") and '~' not in test and
-            ('.' not in test or test.endswith('.py') or
-             test.endswith('.bat') or test.endswith('.t'))):
-            if not os.path.exists(test):
-                skipped.append(test)
-            else:
-                tests.append(test)
-    if not tests:
-        for test in skipped:
-            print 'Skipped %s: does not exist' % test
-        print "# Ran 0 tests, %d skipped, 0 failed." % len(skipped)
-        return
-    tests = tests + skipped
+    tests = args
 
     # Reset some environment variables to well-known values so that
     # the tests produce repeatable output.
Binary file tests/tampered.hg has changed
--- a/tests/test-586.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-586.t	Sat Jun 18 17:03:01 2011 -0500
@@ -17,6 +17,7 @@
   pulling from ../a
   searching for changes
   warning: repository is unrelated
+  requesting all changes
   adding changesets
   adding manifests
   adding file changes
@@ -66,6 +67,7 @@
   pulling from ../repob
   searching for changes
   warning: repository is unrelated
+  requesting all changes
   adding changesets
   adding manifests
   adding file changes
--- a/tests/test-acl.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-acl.t	Sat Jun 18 17:03:01 2011 -0500
@@ -82,46 +82,24 @@
   hgrc = """
   """
   pushing to ../b
+  query 1; heads
   searching for changes
-  common changesets up to 6675d58eff77
+  all remote heads known locally
   3 changesets found
   list of changesets:
   ef1ea85a6374b77d6da9dcda9541f498f2d17df7
   f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
   911600dab2ae7a9baff75958b84fe606851ce955
   adding changesets
-  bundling: 0 changesets
-  bundling: 0 changesets
-  bundling: 0 changesets
-  bundling: 1 changesets
-  bundling: 1 changesets
-  bundling: 1 changesets
-  bundling: 2 changesets
-  bundling: 2 changesets
-  bundling: 2 changesets
-  bundling: 3 changesets
-  bundling: 0/3 manifests (0.00%)
-  bundling: 0/3 manifests (0.00%)
-  bundling: 0/3 manifests (0.00%)
-  bundling: 1/3 manifests (33.33%)
-  bundling: 1/3 manifests (33.33%)
+  bundling: 1/3 changesets (33.33%)
+  bundling: 2/3 changesets (66.67%)
+  bundling: 3/3 changesets (100.00%)
   bundling: 1/3 manifests (33.33%)
   bundling: 2/3 manifests (66.67%)
-  bundling: 2/3 manifests (66.67%)
-  bundling: 2/3 manifests (66.67%)
   bundling: 3/3 manifests (100.00%)
-  bundling: foo/Bar/file.txt 0/3 files (0.00%)
-  bundling: foo/Bar/file.txt 0/3 files (0.00%)
-  bundling: foo/Bar/file.txt 0/3 files (0.00%)
-  bundling: foo/Bar/file.txt 0/3 files (0.00%)
-  bundling: foo/file.txt 1/3 files (33.33%)
-  bundling: foo/file.txt 1/3 files (33.33%)
-  bundling: foo/file.txt 1/3 files (33.33%)
-  bundling: foo/file.txt 1/3 files (33.33%)
-  bundling: quux/file.py 2/3 files (66.67%)
-  bundling: quux/file.py 2/3 files (66.67%)
-  bundling: quux/file.py 2/3 files (66.67%)
-  bundling: quux/file.py 2/3 files (66.67%)
+  bundling: foo/Bar/file.txt 1/3 files (33.33%)
+  bundling: foo/file.txt 2/3 files (66.67%)
+  bundling: quux/file.py 3/3 files (100.00%)
   changesets: 1 chunks
   add changeset ef1ea85a6374
   changesets: 2 chunks
@@ -159,8 +137,9 @@
   pretxnchangegroup.acl = python:hgext.acl.hook
   """
   pushing to ../b
+  query 1; heads
   searching for changes
-  common changesets up to 6675d58eff77
+  all remote heads known locally
   invalidating branch cache (tip differs)
   3 changesets found
   list of changesets:
@@ -168,38 +147,15 @@
   f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
   911600dab2ae7a9baff75958b84fe606851ce955
   adding changesets
-  bundling: 0 changesets
-  bundling: 0 changesets
-  bundling: 0 changesets
-  bundling: 1 changesets
-  bundling: 1 changesets
-  bundling: 1 changesets
-  bundling: 2 changesets
-  bundling: 2 changesets
-  bundling: 2 changesets
-  bundling: 3 changesets
-  bundling: 0/3 manifests (0.00%)
-  bundling: 0/3 manifests (0.00%)
-  bundling: 0/3 manifests (0.00%)
-  bundling: 1/3 manifests (33.33%)
-  bundling: 1/3 manifests (33.33%)
+  bundling: 1/3 changesets (33.33%)
+  bundling: 2/3 changesets (66.67%)
+  bundling: 3/3 changesets (100.00%)
   bundling: 1/3 manifests (33.33%)
   bundling: 2/3 manifests (66.67%)
-  bundling: 2/3 manifests (66.67%)
-  bundling: 2/3 manifests (66.67%)
   bundling: 3/3 manifests (100.00%)
-  bundling: foo/Bar/file.txt 0/3 files (0.00%)
-  bundling: foo/Bar/file.txt 0/3 files (0.00%)
-  bundling: foo/Bar/file.txt 0/3 files (0.00%)
-  bundling: foo/Bar/file.txt 0/3 files (0.00%)
-  bundling: foo/file.txt 1/3 files (33.33%)
-  bundling: foo/file.txt 1/3 files (33.33%)
-  bundling: foo/file.txt 1/3 files (33.33%)
-  bundling: foo/file.txt 1/3 files (33.33%)
-  bundling: quux/file.py 2/3 files (66.67%)
-  bundling: quux/file.py 2/3 files (66.67%)
-  bundling: quux/file.py 2/3 files (66.67%)
-  bundling: quux/file.py 2/3 files (66.67%)
+  bundling: foo/Bar/file.txt 1/3 files (33.33%)
+  bundling: foo/file.txt 2/3 files (66.67%)
+  bundling: quux/file.py 3/3 files (100.00%)
   changesets: 1 chunks
   add changeset ef1ea85a6374
   changesets: 2 chunks
@@ -240,8 +196,9 @@
   sources = push
   """
   pushing to ../b
+  query 1; heads
   searching for changes
-  common changesets up to 6675d58eff77
+  all remote heads known locally
   invalidating branch cache (tip differs)
   3 changesets found
   list of changesets:
@@ -249,38 +206,15 @@
   f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
   911600dab2ae7a9baff75958b84fe606851ce955
   adding changesets
-  bundling: 0 changesets
-  bundling: 0 changesets
-  bundling: 0 changesets
-  bundling: 1 changesets
-  bundling: 1 changesets
-  bundling: 1 changesets
-  bundling: 2 changesets
-  bundling: 2 changesets
-  bundling: 2 changesets
-  bundling: 3 changesets
-  bundling: 0/3 manifests (0.00%)
-  bundling: 0/3 manifests (0.00%)
-  bundling: 0/3 manifests (0.00%)
-  bundling: 1/3 manifests (33.33%)
-  bundling: 1/3 manifests (33.33%)
+  bundling: 1/3 changesets (33.33%)
+  bundling: 2/3 changesets (66.67%)
+  bundling: 3/3 changesets (100.00%)
   bundling: 1/3 manifests (33.33%)
   bundling: 2/3 manifests (66.67%)
-  bundling: 2/3 manifests (66.67%)
-  bundling: 2/3 manifests (66.67%)
   bundling: 3/3 manifests (100.00%)
-  bundling: foo/Bar/file.txt 0/3 files (0.00%)
-  bundling: foo/Bar/file.txt 0/3 files (0.00%)
-  bundling: foo/Bar/file.txt 0/3 files (0.00%)
-  bundling: foo/Bar/file.txt 0/3 files (0.00%)
-  bundling: foo/file.txt 1/3 files (33.33%)
-  bundling: foo/file.txt 1/3 files (33.33%)
-  bundling: foo/file.txt 1/3 files (33.33%)
-  bundling: foo/file.txt 1/3 files (33.33%)
-  bundling: quux/file.py 2/3 files (66.67%)
-  bundling: quux/file.py 2/3 files (66.67%)
-  bundling: quux/file.py 2/3 files (66.67%)
-  bundling: quux/file.py 2/3 files (66.67%)
+  bundling: foo/Bar/file.txt 1/3 files (33.33%)
+  bundling: foo/file.txt 2/3 files (66.67%)
+  bundling: quux/file.py 3/3 files (100.00%)
   changesets: 1 chunks
   add changeset ef1ea85a6374
   changesets: 2 chunks
@@ -330,8 +264,9 @@
   [acl.allow]
   """
   pushing to ../b
+  query 1; heads
   searching for changes
-  common changesets up to 6675d58eff77
+  all remote heads known locally
   invalidating branch cache (tip differs)
   3 changesets found
   list of changesets:
@@ -339,38 +274,15 @@
   f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
   911600dab2ae7a9baff75958b84fe606851ce955
   adding changesets
-  bundling: 0 changesets
-  bundling: 0 changesets
-  bundling: 0 changesets
-  bundling: 1 changesets
-  bundling: 1 changesets
-  bundling: 1 changesets
-  bundling: 2 changesets
-  bundling: 2 changesets
-  bundling: 2 changesets
-  bundling: 3 changesets
-  bundling: 0/3 manifests (0.00%)
-  bundling: 0/3 manifests (0.00%)
-  bundling: 0/3 manifests (0.00%)
-  bundling: 1/3 manifests (33.33%)
-  bundling: 1/3 manifests (33.33%)
+  bundling: 1/3 changesets (33.33%)
+  bundling: 2/3 changesets (66.67%)
+  bundling: 3/3 changesets (100.00%)
   bundling: 1/3 manifests (33.33%)
   bundling: 2/3 manifests (66.67%)
-  bundling: 2/3 manifests (66.67%)
-  bundling: 2/3 manifests (66.67%)
   bundling: 3/3 manifests (100.00%)
-  bundling: foo/Bar/file.txt 0/3 files (0.00%)
-  bundling: foo/Bar/file.txt 0/3 files (0.00%)
-  bundling: foo/Bar/file.txt 0/3 files (0.00%)
-  bundling: foo/Bar/file.txt 0/3 files (0.00%)
-  bundling: foo/file.txt 1/3 files (33.33%)
-  bundling: foo/file.txt 1/3 files (33.33%)
-  bundling: foo/file.txt 1/3 files (33.33%)
-  bundling: foo/file.txt 1/3 files (33.33%)
-  bundling: quux/file.py 2/3 files (66.67%)
-  bundling: quux/file.py 2/3 files (66.67%)
-  bundling: quux/file.py 2/3 files (66.67%)
-  bundling: quux/file.py 2/3 files (66.67%)
+  bundling: foo/Bar/file.txt 1/3 files (33.33%)
+  bundling: foo/file.txt 2/3 files (66.67%)
+  bundling: quux/file.py 3/3 files (100.00%)
   changesets: 1 chunks
   add changeset ef1ea85a6374
   changesets: 2 chunks
@@ -418,46 +330,24 @@
   foo/** = fred
   """
   pushing to ../b
+  query 1; heads
   searching for changes
-  common changesets up to 6675d58eff77
+  all remote heads known locally
   3 changesets found
   list of changesets:
   ef1ea85a6374b77d6da9dcda9541f498f2d17df7
   f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
   911600dab2ae7a9baff75958b84fe606851ce955
   adding changesets
-  bundling: 0 changesets
-  bundling: 0 changesets
-  bundling: 0 changesets
-  bundling: 1 changesets
-  bundling: 1 changesets
-  bundling: 1 changesets
-  bundling: 2 changesets
-  bundling: 2 changesets
-  bundling: 2 changesets
-  bundling: 3 changesets
-  bundling: 0/3 manifests (0.00%)
-  bundling: 0/3 manifests (0.00%)
-  bundling: 0/3 manifests (0.00%)
-  bundling: 1/3 manifests (33.33%)
-  bundling: 1/3 manifests (33.33%)
+  bundling: 1/3 changesets (33.33%)
+  bundling: 2/3 changesets (66.67%)
+  bundling: 3/3 changesets (100.00%)
   bundling: 1/3 manifests (33.33%)
   bundling: 2/3 manifests (66.67%)
-  bundling: 2/3 manifests (66.67%)
-  bundling: 2/3 manifests (66.67%)
   bundling: 3/3 manifests (100.00%)
-  bundling: foo/Bar/file.txt 0/3 files (0.00%)
-  bundling: foo/Bar/file.txt 0/3 files (0.00%)
-  bundling: foo/Bar/file.txt 0/3 files (0.00%)
-  bundling: foo/Bar/file.txt 0/3 files (0.00%)
-  bundling: foo/file.txt 1/3 files (33.33%)
-  bundling: foo/file.txt 1/3 files (33.33%)
-  bundling: foo/file.txt 1/3 files (33.33%)
-  bundling: foo/file.txt 1/3 files (33.33%)
-  bundling: quux/file.py 2/3 files (66.67%)
-  bundling: quux/file.py 2/3 files (66.67%)
-  bundling: quux/file.py 2/3 files (66.67%)
-  bundling: quux/file.py 2/3 files (66.67%)
+  bundling: foo/Bar/file.txt 1/3 files (33.33%)
+  bundling: foo/file.txt 2/3 files (66.67%)
+  bundling: quux/file.py 3/3 files (100.00%)
   changesets: 1 chunks
   add changeset ef1ea85a6374
   changesets: 2 chunks
@@ -510,46 +400,24 @@
   [acl.deny]
   """
   pushing to ../b
+  query 1; heads
   searching for changes
-  common changesets up to 6675d58eff77
+  all remote heads known locally
   3 changesets found
   list of changesets:
   ef1ea85a6374b77d6da9dcda9541f498f2d17df7
   f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
   911600dab2ae7a9baff75958b84fe606851ce955
   adding changesets
-  bundling: 0 changesets
-  bundling: 0 changesets
-  bundling: 0 changesets
-  bundling: 1 changesets
-  bundling: 1 changesets
-  bundling: 1 changesets
-  bundling: 2 changesets
-  bundling: 2 changesets
-  bundling: 2 changesets
-  bundling: 3 changesets
-  bundling: 0/3 manifests (0.00%)
-  bundling: 0/3 manifests (0.00%)
-  bundling: 0/3 manifests (0.00%)
-  bundling: 1/3 manifests (33.33%)
-  bundling: 1/3 manifests (33.33%)
+  bundling: 1/3 changesets (33.33%)
+  bundling: 2/3 changesets (66.67%)
+  bundling: 3/3 changesets (100.00%)
   bundling: 1/3 manifests (33.33%)
   bundling: 2/3 manifests (66.67%)
-  bundling: 2/3 manifests (66.67%)
-  bundling: 2/3 manifests (66.67%)
   bundling: 3/3 manifests (100.00%)
-  bundling: foo/Bar/file.txt 0/3 files (0.00%)
-  bundling: foo/Bar/file.txt 0/3 files (0.00%)
-  bundling: foo/Bar/file.txt 0/3 files (0.00%)
-  bundling: foo/Bar/file.txt 0/3 files (0.00%)
-  bundling: foo/file.txt 1/3 files (33.33%)
-  bundling: foo/file.txt 1/3 files (33.33%)
-  bundling: foo/file.txt 1/3 files (33.33%)
-  bundling: foo/file.txt 1/3 files (33.33%)
-  bundling: quux/file.py 2/3 files (66.67%)
-  bundling: quux/file.py 2/3 files (66.67%)
-  bundling: quux/file.py 2/3 files (66.67%)
-  bundling: quux/file.py 2/3 files (66.67%)
+  bundling: foo/Bar/file.txt 1/3 files (33.33%)
+  bundling: foo/file.txt 2/3 files (66.67%)
+  bundling: quux/file.py 3/3 files (100.00%)
   changesets: 1 chunks
   add changeset ef1ea85a6374
   changesets: 2 chunks
@@ -599,46 +467,24 @@
   foo/bar/** = fred
   """
   pushing to ../b
+  query 1; heads
   searching for changes
-  common changesets up to 6675d58eff77
+  all remote heads known locally
   3 changesets found
   list of changesets:
   ef1ea85a6374b77d6da9dcda9541f498f2d17df7
   f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
   911600dab2ae7a9baff75958b84fe606851ce955
   adding changesets
-  bundling: 0 changesets
-  bundling: 0 changesets
-  bundling: 0 changesets
-  bundling: 1 changesets
-  bundling: 1 changesets
-  bundling: 1 changesets
-  bundling: 2 changesets
-  bundling: 2 changesets
-  bundling: 2 changesets
-  bundling: 3 changesets
-  bundling: 0/3 manifests (0.00%)
-  bundling: 0/3 manifests (0.00%)
-  bundling: 0/3 manifests (0.00%)
-  bundling: 1/3 manifests (33.33%)
-  bundling: 1/3 manifests (33.33%)
+  bundling: 1/3 changesets (33.33%)
+  bundling: 2/3 changesets (66.67%)
+  bundling: 3/3 changesets (100.00%)
   bundling: 1/3 manifests (33.33%)
   bundling: 2/3 manifests (66.67%)
-  bundling: 2/3 manifests (66.67%)
-  bundling: 2/3 manifests (66.67%)
   bundling: 3/3 manifests (100.00%)
-  bundling: foo/Bar/file.txt 0/3 files (0.00%)
-  bundling: foo/Bar/file.txt 0/3 files (0.00%)
-  bundling: foo/Bar/file.txt 0/3 files (0.00%)
-  bundling: foo/Bar/file.txt 0/3 files (0.00%)
-  bundling: foo/file.txt 1/3 files (33.33%)
-  bundling: foo/file.txt 1/3 files (33.33%)
-  bundling: foo/file.txt 1/3 files (33.33%)
-  bundling: foo/file.txt 1/3 files (33.33%)
-  bundling: quux/file.py 2/3 files (66.67%)
-  bundling: quux/file.py 2/3 files (66.67%)
-  bundling: quux/file.py 2/3 files (66.67%)
-  bundling: quux/file.py 2/3 files (66.67%)
+  bundling: foo/Bar/file.txt 1/3 files (33.33%)
+  bundling: foo/file.txt 2/3 files (66.67%)
+  bundling: quux/file.py 3/3 files (100.00%)
   changesets: 1 chunks
   add changeset ef1ea85a6374
   changesets: 2 chunks
@@ -693,46 +539,24 @@
   foo/Bar/** = fred
   """
   pushing to ../b
+  query 1; heads
   searching for changes
-  common changesets up to 6675d58eff77
+  all remote heads known locally
   3 changesets found
   list of changesets:
   ef1ea85a6374b77d6da9dcda9541f498f2d17df7
   f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
   911600dab2ae7a9baff75958b84fe606851ce955
   adding changesets
-  bundling: 0 changesets
-  bundling: 0 changesets
-  bundling: 0 changesets
-  bundling: 1 changesets
-  bundling: 1 changesets
-  bundling: 1 changesets
-  bundling: 2 changesets
-  bundling: 2 changesets
-  bundling: 2 changesets
-  bundling: 3 changesets
-  bundling: 0/3 manifests (0.00%)
-  bundling: 0/3 manifests (0.00%)
-  bundling: 0/3 manifests (0.00%)
-  bundling: 1/3 manifests (33.33%)
-  bundling: 1/3 manifests (33.33%)
+  bundling: 1/3 changesets (33.33%)
+  bundling: 2/3 changesets (66.67%)
+  bundling: 3/3 changesets (100.00%)
   bundling: 1/3 manifests (33.33%)
   bundling: 2/3 manifests (66.67%)
-  bundling: 2/3 manifests (66.67%)
-  bundling: 2/3 manifests (66.67%)
   bundling: 3/3 manifests (100.00%)
-  bundling: foo/Bar/file.txt 0/3 files (0.00%)
-  bundling: foo/Bar/file.txt 0/3 files (0.00%)
-  bundling: foo/Bar/file.txt 0/3 files (0.00%)
-  bundling: foo/Bar/file.txt 0/3 files (0.00%)
-  bundling: foo/file.txt 1/3 files (33.33%)
-  bundling: foo/file.txt 1/3 files (33.33%)
-  bundling: foo/file.txt 1/3 files (33.33%)
-  bundling: foo/file.txt 1/3 files (33.33%)
-  bundling: quux/file.py 2/3 files (66.67%)
-  bundling: quux/file.py 2/3 files (66.67%)
-  bundling: quux/file.py 2/3 files (66.67%)
-  bundling: quux/file.py 2/3 files (66.67%)
+  bundling: foo/Bar/file.txt 1/3 files (33.33%)
+  bundling: foo/file.txt 2/3 files (66.67%)
+  bundling: quux/file.py 3/3 files (100.00%)
   changesets: 1 chunks
   add changeset ef1ea85a6374
   changesets: 2 chunks
@@ -784,46 +608,24 @@
   foo/Bar/** = fred
   """
   pushing to ../b
+  query 1; heads
   searching for changes
-  common changesets up to 6675d58eff77
+  all remote heads known locally
   3 changesets found
   list of changesets:
   ef1ea85a6374b77d6da9dcda9541f498f2d17df7
   f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
   911600dab2ae7a9baff75958b84fe606851ce955
   adding changesets
-  bundling: 0 changesets
-  bundling: 0 changesets
-  bundling: 0 changesets
-  bundling: 1 changesets
-  bundling: 1 changesets
-  bundling: 1 changesets
-  bundling: 2 changesets
-  bundling: 2 changesets
-  bundling: 2 changesets
-  bundling: 3 changesets
-  bundling: 0/3 manifests (0.00%)
-  bundling: 0/3 manifests (0.00%)
-  bundling: 0/3 manifests (0.00%)
-  bundling: 1/3 manifests (33.33%)
-  bundling: 1/3 manifests (33.33%)
+  bundling: 1/3 changesets (33.33%)
+  bundling: 2/3 changesets (66.67%)
+  bundling: 3/3 changesets (100.00%)
   bundling: 1/3 manifests (33.33%)
   bundling: 2/3 manifests (66.67%)
-  bundling: 2/3 manifests (66.67%)
-  bundling: 2/3 manifests (66.67%)
   bundling: 3/3 manifests (100.00%)
-  bundling: foo/Bar/file.txt 0/3 files (0.00%)
-  bundling: foo/Bar/file.txt 0/3 files (0.00%)
-  bundling: foo/Bar/file.txt 0/3 files (0.00%)
-  bundling: foo/Bar/file.txt 0/3 files (0.00%)
-  bundling: foo/file.txt 1/3 files (33.33%)
-  bundling: foo/file.txt 1/3 files (33.33%)
-  bundling: foo/file.txt 1/3 files (33.33%)
-  bundling: foo/file.txt 1/3 files (33.33%)
-  bundling: quux/file.py 2/3 files (66.67%)
-  bundling: quux/file.py 2/3 files (66.67%)
-  bundling: quux/file.py 2/3 files (66.67%)
-  bundling: quux/file.py 2/3 files (66.67%)
+  bundling: foo/Bar/file.txt 1/3 files (33.33%)
+  bundling: foo/file.txt 2/3 files (66.67%)
+  bundling: quux/file.py 3/3 files (100.00%)
   changesets: 1 chunks
   add changeset ef1ea85a6374
   changesets: 2 chunks
@@ -877,46 +679,24 @@
   ** = barney
   """
   pushing to ../b
+  query 1; heads
   searching for changes
-  common changesets up to 6675d58eff77
+  all remote heads known locally
   3 changesets found
   list of changesets:
   ef1ea85a6374b77d6da9dcda9541f498f2d17df7
   f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
   911600dab2ae7a9baff75958b84fe606851ce955
   adding changesets
-  bundling: 0 changesets
-  bundling: 0 changesets
-  bundling: 0 changesets
-  bundling: 1 changesets
-  bundling: 1 changesets
-  bundling: 1 changesets
-  bundling: 2 changesets
-  bundling: 2 changesets
-  bundling: 2 changesets
-  bundling: 3 changesets
-  bundling: 0/3 manifests (0.00%)
-  bundling: 0/3 manifests (0.00%)
-  bundling: 0/3 manifests (0.00%)
-  bundling: 1/3 manifests (33.33%)
-  bundling: 1/3 manifests (33.33%)
+  bundling: 1/3 changesets (33.33%)
+  bundling: 2/3 changesets (66.67%)
+  bundling: 3/3 changesets (100.00%)
   bundling: 1/3 manifests (33.33%)
   bundling: 2/3 manifests (66.67%)
-  bundling: 2/3 manifests (66.67%)
-  bundling: 2/3 manifests (66.67%)
   bundling: 3/3 manifests (100.00%)
-  bundling: foo/Bar/file.txt 0/3 files (0.00%)
-  bundling: foo/Bar/file.txt 0/3 files (0.00%)
-  bundling: foo/Bar/file.txt 0/3 files (0.00%)
-  bundling: foo/Bar/file.txt 0/3 files (0.00%)
-  bundling: foo/file.txt 1/3 files (33.33%)
-  bundling: foo/file.txt 1/3 files (33.33%)
-  bundling: foo/file.txt 1/3 files (33.33%)
-  bundling: foo/file.txt 1/3 files (33.33%)
-  bundling: quux/file.py 2/3 files (66.67%)
-  bundling: quux/file.py 2/3 files (66.67%)
-  bundling: quux/file.py 2/3 files (66.67%)
-  bundling: quux/file.py 2/3 files (66.67%)
+  bundling: foo/Bar/file.txt 1/3 files (33.33%)
+  bundling: foo/file.txt 2/3 files (66.67%)
+  bundling: quux/file.py 3/3 files (100.00%)
   changesets: 1 chunks
   add changeset ef1ea85a6374
   changesets: 2 chunks
@@ -973,8 +753,9 @@
   **/*.txt = wilma
   """
   pushing to ../b
+  query 1; heads
   searching for changes
-  common changesets up to 6675d58eff77
+  all remote heads known locally
   invalidating branch cache (tip differs)
   3 changesets found
   list of changesets:
@@ -982,38 +763,15 @@
   f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
   911600dab2ae7a9baff75958b84fe606851ce955
   adding changesets
-  bundling: 0 changesets
-  bundling: 0 changesets
-  bundling: 0 changesets
-  bundling: 1 changesets
-  bundling: 1 changesets
-  bundling: 1 changesets
-  bundling: 2 changesets
-  bundling: 2 changesets
-  bundling: 2 changesets
-  bundling: 3 changesets
-  bundling: 0/3 manifests (0.00%)
-  bundling: 0/3 manifests (0.00%)
-  bundling: 0/3 manifests (0.00%)
-  bundling: 1/3 manifests (33.33%)
-  bundling: 1/3 manifests (33.33%)
+  bundling: 1/3 changesets (33.33%)
+  bundling: 2/3 changesets (66.67%)
+  bundling: 3/3 changesets (100.00%)
   bundling: 1/3 manifests (33.33%)
   bundling: 2/3 manifests (66.67%)
-  bundling: 2/3 manifests (66.67%)
-  bundling: 2/3 manifests (66.67%)
   bundling: 3/3 manifests (100.00%)
-  bundling: foo/Bar/file.txt 0/3 files (0.00%)
-  bundling: foo/Bar/file.txt 0/3 files (0.00%)
-  bundling: foo/Bar/file.txt 0/3 files (0.00%)
-  bundling: foo/Bar/file.txt 0/3 files (0.00%)
-  bundling: foo/file.txt 1/3 files (33.33%)
-  bundling: foo/file.txt 1/3 files (33.33%)
-  bundling: foo/file.txt 1/3 files (33.33%)
-  bundling: foo/file.txt 1/3 files (33.33%)
-  bundling: quux/file.py 2/3 files (66.67%)
-  bundling: quux/file.py 2/3 files (66.67%)
-  bundling: quux/file.py 2/3 files (66.67%)
-  bundling: quux/file.py 2/3 files (66.67%)
+  bundling: foo/Bar/file.txt 1/3 files (33.33%)
+  bundling: foo/file.txt 2/3 files (66.67%)
+  bundling: quux/file.py 3/3 files (100.00%)
   changesets: 1 chunks
   add changeset ef1ea85a6374
   changesets: 2 chunks
@@ -1074,46 +832,24 @@
   config = ../acl.config
   """
   pushing to ../b
+  query 1; heads
   searching for changes
-  common changesets up to 6675d58eff77
+  all remote heads known locally
   3 changesets found
   list of changesets:
   ef1ea85a6374b77d6da9dcda9541f498f2d17df7
   f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
   911600dab2ae7a9baff75958b84fe606851ce955
   adding changesets
-  bundling: 0 changesets
-  bundling: 0 changesets
-  bundling: 0 changesets
-  bundling: 1 changesets
-  bundling: 1 changesets
-  bundling: 1 changesets
-  bundling: 2 changesets
-  bundling: 2 changesets
-  bundling: 2 changesets
-  bundling: 3 changesets
-  bundling: 0/3 manifests (0.00%)
-  bundling: 0/3 manifests (0.00%)
-  bundling: 0/3 manifests (0.00%)
-  bundling: 1/3 manifests (33.33%)
-  bundling: 1/3 manifests (33.33%)
+  bundling: 1/3 changesets (33.33%)
+  bundling: 2/3 changesets (66.67%)
+  bundling: 3/3 changesets (100.00%)
   bundling: 1/3 manifests (33.33%)
   bundling: 2/3 manifests (66.67%)
-  bundling: 2/3 manifests (66.67%)
-  bundling: 2/3 manifests (66.67%)
   bundling: 3/3 manifests (100.00%)
-  bundling: foo/Bar/file.txt 0/3 files (0.00%)
-  bundling: foo/Bar/file.txt 0/3 files (0.00%)
-  bundling: foo/Bar/file.txt 0/3 files (0.00%)
-  bundling: foo/Bar/file.txt 0/3 files (0.00%)
-  bundling: foo/file.txt 1/3 files (33.33%)
-  bundling: foo/file.txt 1/3 files (33.33%)
-  bundling: foo/file.txt 1/3 files (33.33%)
-  bundling: foo/file.txt 1/3 files (33.33%)
-  bundling: quux/file.py 2/3 files (66.67%)
-  bundling: quux/file.py 2/3 files (66.67%)
-  bundling: quux/file.py 2/3 files (66.67%)
-  bundling: quux/file.py 2/3 files (66.67%)
+  bundling: foo/Bar/file.txt 1/3 files (33.33%)
+  bundling: foo/file.txt 2/3 files (66.67%)
+  bundling: quux/file.py 3/3 files (100.00%)
   changesets: 1 chunks
   add changeset ef1ea85a6374
   changesets: 2 chunks
@@ -1168,46 +904,24 @@
   foo/** = betty
   """
   pushing to ../b
+  query 1; heads
   searching for changes
-  common changesets up to 6675d58eff77
+  all remote heads known locally
   3 changesets found
   list of changesets:
   ef1ea85a6374b77d6da9dcda9541f498f2d17df7
   f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
   911600dab2ae7a9baff75958b84fe606851ce955
   adding changesets
-  bundling: 0 changesets
-  bundling: 0 changesets
-  bundling: 0 changesets
-  bundling: 1 changesets
-  bundling: 1 changesets
-  bundling: 1 changesets
-  bundling: 2 changesets
-  bundling: 2 changesets
-  bundling: 2 changesets
-  bundling: 3 changesets
-  bundling: 0/3 manifests (0.00%)
-  bundling: 0/3 manifests (0.00%)
-  bundling: 0/3 manifests (0.00%)
-  bundling: 1/3 manifests (33.33%)
-  bundling: 1/3 manifests (33.33%)
+  bundling: 1/3 changesets (33.33%)
+  bundling: 2/3 changesets (66.67%)
+  bundling: 3/3 changesets (100.00%)
   bundling: 1/3 manifests (33.33%)
   bundling: 2/3 manifests (66.67%)
-  bundling: 2/3 manifests (66.67%)
-  bundling: 2/3 manifests (66.67%)
   bundling: 3/3 manifests (100.00%)
-  bundling: foo/Bar/file.txt 0/3 files (0.00%)
-  bundling: foo/Bar/file.txt 0/3 files (0.00%)
-  bundling: foo/Bar/file.txt 0/3 files (0.00%)
-  bundling: foo/Bar/file.txt 0/3 files (0.00%)
-  bundling: foo/file.txt 1/3 files (33.33%)
-  bundling: foo/file.txt 1/3 files (33.33%)
-  bundling: foo/file.txt 1/3 files (33.33%)
-  bundling: foo/file.txt 1/3 files (33.33%)
-  bundling: quux/file.py 2/3 files (66.67%)
-  bundling: quux/file.py 2/3 files (66.67%)
-  bundling: quux/file.py 2/3 files (66.67%)
-  bundling: quux/file.py 2/3 files (66.67%)
+  bundling: foo/Bar/file.txt 1/3 files (33.33%)
+  bundling: foo/file.txt 2/3 files (66.67%)
+  bundling: quux/file.py 3/3 files (100.00%)
   changesets: 1 chunks
   add changeset ef1ea85a6374
   changesets: 2 chunks
@@ -1274,46 +988,24 @@
   changegroup.acl = false
   """
   pushing to ../b
+  query 1; heads
   searching for changes
-  common changesets up to 6675d58eff77
+  all remote heads known locally
   3 changesets found
   list of changesets:
   ef1ea85a6374b77d6da9dcda9541f498f2d17df7
   f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
   911600dab2ae7a9baff75958b84fe606851ce955
   adding changesets
-  bundling: 0 changesets
-  bundling: 0 changesets
-  bundling: 0 changesets
-  bundling: 1 changesets
-  bundling: 1 changesets
-  bundling: 1 changesets
-  bundling: 2 changesets
-  bundling: 2 changesets
-  bundling: 2 changesets
-  bundling: 3 changesets
-  bundling: 0/3 manifests (0.00%)
-  bundling: 0/3 manifests (0.00%)
-  bundling: 0/3 manifests (0.00%)
-  bundling: 1/3 manifests (33.33%)
-  bundling: 1/3 manifests (33.33%)
+  bundling: 1/3 changesets (33.33%)
+  bundling: 2/3 changesets (66.67%)
+  bundling: 3/3 changesets (100.00%)
   bundling: 1/3 manifests (33.33%)
   bundling: 2/3 manifests (66.67%)
-  bundling: 2/3 manifests (66.67%)
-  bundling: 2/3 manifests (66.67%)
   bundling: 3/3 manifests (100.00%)
-  bundling: foo/Bar/file.txt 0/3 files (0.00%)
-  bundling: foo/Bar/file.txt 0/3 files (0.00%)
-  bundling: foo/Bar/file.txt 0/3 files (0.00%)
-  bundling: foo/Bar/file.txt 0/3 files (0.00%)
-  bundling: foo/file.txt 1/3 files (33.33%)
-  bundling: foo/file.txt 1/3 files (33.33%)
-  bundling: foo/file.txt 1/3 files (33.33%)
-  bundling: foo/file.txt 1/3 files (33.33%)
-  bundling: quux/file.py 2/3 files (66.67%)
-  bundling: quux/file.py 2/3 files (66.67%)
-  bundling: quux/file.py 2/3 files (66.67%)
-  bundling: quux/file.py 2/3 files (66.67%)
+  bundling: foo/Bar/file.txt 1/3 files (33.33%)
+  bundling: foo/file.txt 2/3 files (66.67%)
+  bundling: quux/file.py 3/3 files (100.00%)
   changesets: 1 chunks
   add changeset ef1ea85a6374
   changesets: 2 chunks
@@ -1371,8 +1063,9 @@
   ** = fred
   """
   pushing to ../b
+  query 1; heads
   searching for changes
-  common changesets up to 6675d58eff77
+  all remote heads known locally
   invalidating branch cache (tip differs)
   3 changesets found
   list of changesets:
@@ -1380,38 +1073,15 @@
   f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
   911600dab2ae7a9baff75958b84fe606851ce955
   adding changesets
-  bundling: 0 changesets
-  bundling: 0 changesets
-  bundling: 0 changesets
-  bundling: 1 changesets
-  bundling: 1 changesets
-  bundling: 1 changesets
-  bundling: 2 changesets
-  bundling: 2 changesets
-  bundling: 2 changesets
-  bundling: 3 changesets
-  bundling: 0/3 manifests (0.00%)
-  bundling: 0/3 manifests (0.00%)
-  bundling: 0/3 manifests (0.00%)
-  bundling: 1/3 manifests (33.33%)
-  bundling: 1/3 manifests (33.33%)
+  bundling: 1/3 changesets (33.33%)
+  bundling: 2/3 changesets (66.67%)
+  bundling: 3/3 changesets (100.00%)
   bundling: 1/3 manifests (33.33%)
   bundling: 2/3 manifests (66.67%)
-  bundling: 2/3 manifests (66.67%)
-  bundling: 2/3 manifests (66.67%)
   bundling: 3/3 manifests (100.00%)
-  bundling: foo/Bar/file.txt 0/3 files (0.00%)
-  bundling: foo/Bar/file.txt 0/3 files (0.00%)
-  bundling: foo/Bar/file.txt 0/3 files (0.00%)
-  bundling: foo/Bar/file.txt 0/3 files (0.00%)
-  bundling: foo/file.txt 1/3 files (33.33%)
-  bundling: foo/file.txt 1/3 files (33.33%)
-  bundling: foo/file.txt 1/3 files (33.33%)
-  bundling: foo/file.txt 1/3 files (33.33%)
-  bundling: quux/file.py 2/3 files (66.67%)
-  bundling: quux/file.py 2/3 files (66.67%)
-  bundling: quux/file.py 2/3 files (66.67%)
-  bundling: quux/file.py 2/3 files (66.67%)
+  bundling: foo/Bar/file.txt 1/3 files (33.33%)
+  bundling: foo/file.txt 2/3 files (66.67%)
+  bundling: quux/file.py 3/3 files (100.00%)
   changesets: 1 chunks
   add changeset ef1ea85a6374
   changesets: 2 chunks
@@ -1465,8 +1135,9 @@
   foo/Bar/** = *
   """
   pushing to ../b
+  query 1; heads
   searching for changes
-  common changesets up to 6675d58eff77
+  all remote heads known locally
   invalidating branch cache (tip differs)
   3 changesets found
   list of changesets:
@@ -1474,38 +1145,15 @@
   f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
   911600dab2ae7a9baff75958b84fe606851ce955
   adding changesets
-  bundling: 0 changesets
-  bundling: 0 changesets
-  bundling: 0 changesets
-  bundling: 1 changesets
-  bundling: 1 changesets
-  bundling: 1 changesets
-  bundling: 2 changesets
-  bundling: 2 changesets
-  bundling: 2 changesets
-  bundling: 3 changesets
-  bundling: 0/3 manifests (0.00%)
-  bundling: 0/3 manifests (0.00%)
-  bundling: 0/3 manifests (0.00%)
-  bundling: 1/3 manifests (33.33%)
-  bundling: 1/3 manifests (33.33%)
+  bundling: 1/3 changesets (33.33%)
+  bundling: 2/3 changesets (66.67%)
+  bundling: 3/3 changesets (100.00%)
   bundling: 1/3 manifests (33.33%)
   bundling: 2/3 manifests (66.67%)
-  bundling: 2/3 manifests (66.67%)
-  bundling: 2/3 manifests (66.67%)
   bundling: 3/3 manifests (100.00%)
-  bundling: foo/Bar/file.txt 0/3 files (0.00%)
-  bundling: foo/Bar/file.txt 0/3 files (0.00%)
-  bundling: foo/Bar/file.txt 0/3 files (0.00%)
-  bundling: foo/Bar/file.txt 0/3 files (0.00%)
-  bundling: foo/file.txt 1/3 files (33.33%)
-  bundling: foo/file.txt 1/3 files (33.33%)
-  bundling: foo/file.txt 1/3 files (33.33%)
-  bundling: foo/file.txt 1/3 files (33.33%)
-  bundling: quux/file.py 2/3 files (66.67%)
-  bundling: quux/file.py 2/3 files (66.67%)
-  bundling: quux/file.py 2/3 files (66.67%)
-  bundling: quux/file.py 2/3 files (66.67%)
+  bundling: foo/Bar/file.txt 1/3 files (33.33%)
+  bundling: foo/file.txt 2/3 files (66.67%)
+  bundling: quux/file.py 3/3 files (100.00%)
   changesets: 1 chunks
   add changeset ef1ea85a6374
   changesets: 2 chunks
@@ -1562,46 +1210,24 @@
   ** = @group1
   """
   pushing to ../b
+  query 1; heads
   searching for changes
-  common changesets up to 6675d58eff77
+  all remote heads known locally
   3 changesets found
   list of changesets:
   ef1ea85a6374b77d6da9dcda9541f498f2d17df7
   f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
   911600dab2ae7a9baff75958b84fe606851ce955
   adding changesets
-  bundling: 0 changesets
-  bundling: 0 changesets
-  bundling: 0 changesets
-  bundling: 1 changesets
-  bundling: 1 changesets
-  bundling: 1 changesets
-  bundling: 2 changesets
-  bundling: 2 changesets
-  bundling: 2 changesets
-  bundling: 3 changesets
-  bundling: 0/3 manifests (0.00%)
-  bundling: 0/3 manifests (0.00%)
-  bundling: 0/3 manifests (0.00%)
-  bundling: 1/3 manifests (33.33%)
-  bundling: 1/3 manifests (33.33%)
+  bundling: 1/3 changesets (33.33%)
+  bundling: 2/3 changesets (66.67%)
+  bundling: 3/3 changesets (100.00%)
   bundling: 1/3 manifests (33.33%)
   bundling: 2/3 manifests (66.67%)
-  bundling: 2/3 manifests (66.67%)
-  bundling: 2/3 manifests (66.67%)
   bundling: 3/3 manifests (100.00%)
-  bundling: foo/Bar/file.txt 0/3 files (0.00%)
-  bundling: foo/Bar/file.txt 0/3 files (0.00%)
-  bundling: foo/Bar/file.txt 0/3 files (0.00%)
-  bundling: foo/Bar/file.txt 0/3 files (0.00%)
-  bundling: foo/file.txt 1/3 files (33.33%)
-  bundling: foo/file.txt 1/3 files (33.33%)
-  bundling: foo/file.txt 1/3 files (33.33%)
-  bundling: foo/file.txt 1/3 files (33.33%)
-  bundling: quux/file.py 2/3 files (66.67%)
-  bundling: quux/file.py 2/3 files (66.67%)
-  bundling: quux/file.py 2/3 files (66.67%)
-  bundling: quux/file.py 2/3 files (66.67%)
+  bundling: foo/Bar/file.txt 1/3 files (33.33%)
+  bundling: foo/file.txt 2/3 files (66.67%)
+  bundling: quux/file.py 3/3 files (100.00%)
   changesets: 1 chunks
   add changeset ef1ea85a6374
   changesets: 2 chunks
@@ -1656,8 +1282,9 @@
   foo/Bar/** = @group1
   """
   pushing to ../b
+  query 1; heads
   searching for changes
-  common changesets up to 6675d58eff77
+  all remote heads known locally
   invalidating branch cache (tip differs)
   3 changesets found
   list of changesets:
@@ -1665,38 +1292,15 @@
   f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
   911600dab2ae7a9baff75958b84fe606851ce955
   adding changesets
-  bundling: 0 changesets
-  bundling: 0 changesets
-  bundling: 0 changesets
-  bundling: 1 changesets
-  bundling: 1 changesets
-  bundling: 1 changesets
-  bundling: 2 changesets
-  bundling: 2 changesets
-  bundling: 2 changesets
-  bundling: 3 changesets
-  bundling: 0/3 manifests (0.00%)
-  bundling: 0/3 manifests (0.00%)
-  bundling: 0/3 manifests (0.00%)
-  bundling: 1/3 manifests (33.33%)
-  bundling: 1/3 manifests (33.33%)
+  bundling: 1/3 changesets (33.33%)
+  bundling: 2/3 changesets (66.67%)
+  bundling: 3/3 changesets (100.00%)
   bundling: 1/3 manifests (33.33%)
   bundling: 2/3 manifests (66.67%)
-  bundling: 2/3 manifests (66.67%)
-  bundling: 2/3 manifests (66.67%)
   bundling: 3/3 manifests (100.00%)
-  bundling: foo/Bar/file.txt 0/3 files (0.00%)
-  bundling: foo/Bar/file.txt 0/3 files (0.00%)
-  bundling: foo/Bar/file.txt 0/3 files (0.00%)
-  bundling: foo/Bar/file.txt 0/3 files (0.00%)
-  bundling: foo/file.txt 1/3 files (33.33%)
-  bundling: foo/file.txt 1/3 files (33.33%)
-  bundling: foo/file.txt 1/3 files (33.33%)
-  bundling: foo/file.txt 1/3 files (33.33%)
-  bundling: quux/file.py 2/3 files (66.67%)
-  bundling: quux/file.py 2/3 files (66.67%)
-  bundling: quux/file.py 2/3 files (66.67%)
-  bundling: quux/file.py 2/3 files (66.67%)
+  bundling: foo/Bar/file.txt 1/3 files (33.33%)
+  bundling: foo/file.txt 2/3 files (66.67%)
+  bundling: quux/file.py 3/3 files (100.00%)
   changesets: 1 chunks
   add changeset ef1ea85a6374
   changesets: 2 chunks
@@ -1747,3 +1351,570 @@
   acl: "unlikelytoexist" not defined in [acl.groups]
   error: pretxnchangegroup.acl hook failed: group 'unlikelytoexist' is undefined
   abort: group 'unlikelytoexist' is undefined
+
+
+Branch acl tests setup
+
+  $ init_config
+  $ cd b
+  $ hg up
+  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ hg branch foobar
+  marked working directory as branch foobar
+  $ hg commit -m 'create foobar'
+  $ echo 'foo contents' > abc.txt
+  $ hg add abc.txt
+  $ hg commit -m 'foobar contents'
+  $ cd ..
+  $ hg --cwd a pull ../b
+  pulling from ../b
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 2 changesets with 1 changes to 1 files (+1 heads)
+  (run 'hg heads' to see heads)
+
+Create additional changeset on foobar branch
+
+  $ cd a
+  $ hg up -C foobar
+  4 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ echo 'foo contents2' > abc.txt
+  $ hg commit -m 'foobar contents2'
+  $ cd ..
+
+
+No branch acls specified
+
+  $ do_push astro
+  Pushing as user astro
+  hgrc = """
+  [acl]
+  sources = push
+  [extensions]
+  """
+  pushing to ../b
+  query 1; heads
+  searching for changes
+  all remote heads known locally
+  4 changesets found
+  list of changesets:
+  ef1ea85a6374b77d6da9dcda9541f498f2d17df7
+  f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
+  911600dab2ae7a9baff75958b84fe606851ce955
+  e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
+  adding changesets
+  bundling: 1/4 changesets (25.00%)
+  bundling: 2/4 changesets (50.00%)
+  bundling: 3/4 changesets (75.00%)
+  bundling: 4/4 changesets (100.00%)
+  bundling: 1/4 manifests (25.00%)
+  bundling: 2/4 manifests (50.00%)
+  bundling: 3/4 manifests (75.00%)
+  bundling: 4/4 manifests (100.00%)
+  bundling: abc.txt 1/4 files (25.00%)
+  bundling: foo/Bar/file.txt 2/4 files (50.00%)
+  bundling: foo/file.txt 3/4 files (75.00%)
+  bundling: quux/file.py 4/4 files (100.00%)
+  changesets: 1 chunks
+  add changeset ef1ea85a6374
+  changesets: 2 chunks
+  add changeset f9cafe1212c8
+  changesets: 3 chunks
+  add changeset 911600dab2ae
+  changesets: 4 chunks
+  add changeset e8fc755d4d82
+  adding manifests
+  manifests: 1/4 chunks (25.00%)
+  manifests: 2/4 chunks (50.00%)
+  manifests: 3/4 chunks (75.00%)
+  manifests: 4/4 chunks (100.00%)
+  adding file changes
+  adding abc.txt revisions
+  files: 1/4 chunks (25.00%)
+  adding foo/Bar/file.txt revisions
+  files: 2/4 chunks (50.00%)
+  adding foo/file.txt revisions
+  files: 3/4 chunks (75.00%)
+  adding quux/file.py revisions
+  files: 4/4 chunks (100.00%)
+  added 4 changesets with 4 changes to 4 files (+1 heads)
+  calling hook pretxnchangegroup.acl: hgext.acl.hook
+  acl: acl.allow.branches not enabled
+  acl: acl.deny.branches not enabled
+  acl: acl.allow not enabled
+  acl: acl.deny not enabled
+  acl: branch access granted: "ef1ea85a6374" on branch "default"
+  acl: allowing changeset ef1ea85a6374
+  acl: branch access granted: "f9cafe1212c8" on branch "default"
+  acl: allowing changeset f9cafe1212c8
+  acl: branch access granted: "911600dab2ae" on branch "default"
+  acl: allowing changeset 911600dab2ae
+  acl: branch access granted: "e8fc755d4d82" on branch "foobar"
+  acl: allowing changeset e8fc755d4d82
+  updating the branch cache
+  checking for updated bookmarks
+  repository tip rolled back to revision 2 (undo push)
+  working directory now based on revision 2
+  2:fb35475503ef
+  
+
+Branch acl deny test
+
+  $ echo "[acl.deny.branches]" >> $config
+  $ echo "foobar = *" >> $config
+  $ do_push astro
+  Pushing as user astro
+  hgrc = """
+  [acl]
+  sources = push
+  [extensions]
+  [acl.deny.branches]
+  foobar = *
+  """
+  pushing to ../b
+  query 1; heads
+  searching for changes
+  all remote heads known locally
+  invalidating branch cache (tip differs)
+  4 changesets found
+  list of changesets:
+  ef1ea85a6374b77d6da9dcda9541f498f2d17df7
+  f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
+  911600dab2ae7a9baff75958b84fe606851ce955
+  e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
+  adding changesets
+  bundling: 1/4 changesets (25.00%)
+  bundling: 2/4 changesets (50.00%)
+  bundling: 3/4 changesets (75.00%)
+  bundling: 4/4 changesets (100.00%)
+  bundling: 1/4 manifests (25.00%)
+  bundling: 2/4 manifests (50.00%)
+  bundling: 3/4 manifests (75.00%)
+  bundling: 4/4 manifests (100.00%)
+  bundling: abc.txt 1/4 files (25.00%)
+  bundling: foo/Bar/file.txt 2/4 files (50.00%)
+  bundling: foo/file.txt 3/4 files (75.00%)
+  bundling: quux/file.py 4/4 files (100.00%)
+  changesets: 1 chunks
+  add changeset ef1ea85a6374
+  changesets: 2 chunks
+  add changeset f9cafe1212c8
+  changesets: 3 chunks
+  add changeset 911600dab2ae
+  changesets: 4 chunks
+  add changeset e8fc755d4d82
+  adding manifests
+  manifests: 1/4 chunks (25.00%)
+  manifests: 2/4 chunks (50.00%)
+  manifests: 3/4 chunks (75.00%)
+  manifests: 4/4 chunks (100.00%)
+  adding file changes
+  adding abc.txt revisions
+  files: 1/4 chunks (25.00%)
+  adding foo/Bar/file.txt revisions
+  files: 2/4 chunks (50.00%)
+  adding foo/file.txt revisions
+  files: 3/4 chunks (75.00%)
+  adding quux/file.py revisions
+  files: 4/4 chunks (100.00%)
+  added 4 changesets with 4 changes to 4 files (+1 heads)
+  calling hook pretxnchangegroup.acl: hgext.acl.hook
+  acl: acl.allow.branches not enabled
+  acl: acl.deny.branches enabled, 1 entries for user astro
+  acl: acl.allow not enabled
+  acl: acl.deny not enabled
+  acl: branch access granted: "ef1ea85a6374" on branch "default"
+  acl: allowing changeset ef1ea85a6374
+  acl: branch access granted: "f9cafe1212c8" on branch "default"
+  acl: allowing changeset f9cafe1212c8
+  acl: branch access granted: "911600dab2ae" on branch "default"
+  acl: allowing changeset 911600dab2ae
+  error: pretxnchangegroup.acl hook failed: acl: user "astro" denied on branch "foobar" (changeset "e8fc755d4d82")
+  transaction abort!
+  rollback completed
+  abort: acl: user "astro" denied on branch "foobar" (changeset "e8fc755d4d82")
+  no rollback information available
+  2:fb35475503ef
+  
+
+Branch acl empty allow test
+
+  $ init_config
+  $ echo "[acl.allow.branches]" >> $config
+  $ do_push astro
+  Pushing as user astro
+  hgrc = """
+  [acl]
+  sources = push
+  [extensions]
+  [acl.allow.branches]
+  """
+  pushing to ../b
+  query 1; heads
+  searching for changes
+  all remote heads known locally
+  4 changesets found
+  list of changesets:
+  ef1ea85a6374b77d6da9dcda9541f498f2d17df7
+  f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
+  911600dab2ae7a9baff75958b84fe606851ce955
+  e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
+  adding changesets
+  bundling: 1/4 changesets (25.00%)
+  bundling: 2/4 changesets (50.00%)
+  bundling: 3/4 changesets (75.00%)
+  bundling: 4/4 changesets (100.00%)
+  bundling: 1/4 manifests (25.00%)
+  bundling: 2/4 manifests (50.00%)
+  bundling: 3/4 manifests (75.00%)
+  bundling: 4/4 manifests (100.00%)
+  bundling: abc.txt 1/4 files (25.00%)
+  bundling: foo/Bar/file.txt 2/4 files (50.00%)
+  bundling: foo/file.txt 3/4 files (75.00%)
+  bundling: quux/file.py 4/4 files (100.00%)
+  changesets: 1 chunks
+  add changeset ef1ea85a6374
+  changesets: 2 chunks
+  add changeset f9cafe1212c8
+  changesets: 3 chunks
+  add changeset 911600dab2ae
+  changesets: 4 chunks
+  add changeset e8fc755d4d82
+  adding manifests
+  manifests: 1/4 chunks (25.00%)
+  manifests: 2/4 chunks (50.00%)
+  manifests: 3/4 chunks (75.00%)
+  manifests: 4/4 chunks (100.00%)
+  adding file changes
+  adding abc.txt revisions
+  files: 1/4 chunks (25.00%)
+  adding foo/Bar/file.txt revisions
+  files: 2/4 chunks (50.00%)
+  adding foo/file.txt revisions
+  files: 3/4 chunks (75.00%)
+  adding quux/file.py revisions
+  files: 4/4 chunks (100.00%)
+  added 4 changesets with 4 changes to 4 files (+1 heads)
+  calling hook pretxnchangegroup.acl: hgext.acl.hook
+  acl: acl.allow.branches enabled, 0 entries for user astro
+  acl: acl.deny.branches not enabled
+  acl: acl.allow not enabled
+  acl: acl.deny not enabled
+  error: pretxnchangegroup.acl hook failed: acl: user "astro" not allowed on branch "default" (changeset "ef1ea85a6374")
+  transaction abort!
+  rollback completed
+  abort: acl: user "astro" not allowed on branch "default" (changeset "ef1ea85a6374")
+  no rollback information available
+  2:fb35475503ef
+  
+
+Branch acl allow other
+
+  $ init_config
+  $ echo "[acl.allow.branches]" >> $config
+  $ echo "* = george" >> $config
+  $ do_push astro
+  Pushing as user astro
+  hgrc = """
+  [acl]
+  sources = push
+  [extensions]
+  [acl.allow.branches]
+  * = george
+  """
+  pushing to ../b
+  query 1; heads
+  searching for changes
+  all remote heads known locally
+  4 changesets found
+  list of changesets:
+  ef1ea85a6374b77d6da9dcda9541f498f2d17df7
+  f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
+  911600dab2ae7a9baff75958b84fe606851ce955
+  e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
+  adding changesets
+  bundling: 1/4 changesets (25.00%)
+  bundling: 2/4 changesets (50.00%)
+  bundling: 3/4 changesets (75.00%)
+  bundling: 4/4 changesets (100.00%)
+  bundling: 1/4 manifests (25.00%)
+  bundling: 2/4 manifests (50.00%)
+  bundling: 3/4 manifests (75.00%)
+  bundling: 4/4 manifests (100.00%)
+  bundling: abc.txt 1/4 files (25.00%)
+  bundling: foo/Bar/file.txt 2/4 files (50.00%)
+  bundling: foo/file.txt 3/4 files (75.00%)
+  bundling: quux/file.py 4/4 files (100.00%)
+  changesets: 1 chunks
+  add changeset ef1ea85a6374
+  changesets: 2 chunks
+  add changeset f9cafe1212c8
+  changesets: 3 chunks
+  add changeset 911600dab2ae
+  changesets: 4 chunks
+  add changeset e8fc755d4d82
+  adding manifests
+  manifests: 1/4 chunks (25.00%)
+  manifests: 2/4 chunks (50.00%)
+  manifests: 3/4 chunks (75.00%)
+  manifests: 4/4 chunks (100.00%)
+  adding file changes
+  adding abc.txt revisions
+  files: 1/4 chunks (25.00%)
+  adding foo/Bar/file.txt revisions
+  files: 2/4 chunks (50.00%)
+  adding foo/file.txt revisions
+  files: 3/4 chunks (75.00%)
+  adding quux/file.py revisions
+  files: 4/4 chunks (100.00%)
+  added 4 changesets with 4 changes to 4 files (+1 heads)
+  calling hook pretxnchangegroup.acl: hgext.acl.hook
+  acl: acl.allow.branches enabled, 0 entries for user astro
+  acl: acl.deny.branches not enabled
+  acl: acl.allow not enabled
+  acl: acl.deny not enabled
+  error: pretxnchangegroup.acl hook failed: acl: user "astro" not allowed on branch "default" (changeset "ef1ea85a6374")
+  transaction abort!
+  rollback completed
+  abort: acl: user "astro" not allowed on branch "default" (changeset "ef1ea85a6374")
+  no rollback information available
+  2:fb35475503ef
+  
+  $ do_push george
+  Pushing as user george
+  hgrc = """
+  [acl]
+  sources = push
+  [extensions]
+  [acl.allow.branches]
+  * = george
+  """
+  pushing to ../b
+  query 1; heads
+  searching for changes
+  all remote heads known locally
+  4 changesets found
+  list of changesets:
+  ef1ea85a6374b77d6da9dcda9541f498f2d17df7
+  f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
+  911600dab2ae7a9baff75958b84fe606851ce955
+  e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
+  adding changesets
+  bundling: 1/4 changesets (25.00%)
+  bundling: 2/4 changesets (50.00%)
+  bundling: 3/4 changesets (75.00%)
+  bundling: 4/4 changesets (100.00%)
+  bundling: 1/4 manifests (25.00%)
+  bundling: 2/4 manifests (50.00%)
+  bundling: 3/4 manifests (75.00%)
+  bundling: 4/4 manifests (100.00%)
+  bundling: abc.txt 1/4 files (25.00%)
+  bundling: foo/Bar/file.txt 2/4 files (50.00%)
+  bundling: foo/file.txt 3/4 files (75.00%)
+  bundling: quux/file.py 4/4 files (100.00%)
+  changesets: 1 chunks
+  add changeset ef1ea85a6374
+  changesets: 2 chunks
+  add changeset f9cafe1212c8
+  changesets: 3 chunks
+  add changeset 911600dab2ae
+  changesets: 4 chunks
+  add changeset e8fc755d4d82
+  adding manifests
+  manifests: 1/4 chunks (25.00%)
+  manifests: 2/4 chunks (50.00%)
+  manifests: 3/4 chunks (75.00%)
+  manifests: 4/4 chunks (100.00%)
+  adding file changes
+  adding abc.txt revisions
+  files: 1/4 chunks (25.00%)
+  adding foo/Bar/file.txt revisions
+  files: 2/4 chunks (50.00%)
+  adding foo/file.txt revisions
+  files: 3/4 chunks (75.00%)
+  adding quux/file.py revisions
+  files: 4/4 chunks (100.00%)
+  added 4 changesets with 4 changes to 4 files (+1 heads)
+  calling hook pretxnchangegroup.acl: hgext.acl.hook
+  acl: acl.allow.branches enabled, 1 entries for user george
+  acl: acl.deny.branches not enabled
+  acl: acl.allow not enabled
+  acl: acl.deny not enabled
+  acl: branch access granted: "ef1ea85a6374" on branch "default"
+  acl: allowing changeset ef1ea85a6374
+  acl: branch access granted: "f9cafe1212c8" on branch "default"
+  acl: allowing changeset f9cafe1212c8
+  acl: branch access granted: "911600dab2ae" on branch "default"
+  acl: allowing changeset 911600dab2ae
+  acl: branch access granted: "e8fc755d4d82" on branch "foobar"
+  acl: allowing changeset e8fc755d4d82
+  updating the branch cache
+  checking for updated bookmarks
+  repository tip rolled back to revision 2 (undo push)
+  working directory now based on revision 2
+  2:fb35475503ef
+  
+
+Branch acl conflicting allow
+asterisk ends up applying to all branches and allowing george to
+push foobar into the remote
+
+  $ init_config
+  $ echo "[acl.allow.branches]" >> $config
+  $ echo "foobar = astro" >> $config
+  $ echo "* = george" >> $config
+  $ do_push george
+  Pushing as user george
+  hgrc = """
+  [acl]
+  sources = push
+  [extensions]
+  [acl.allow.branches]
+  foobar = astro
+  * = george
+  """
+  pushing to ../b
+  query 1; heads
+  searching for changes
+  all remote heads known locally
+  invalidating branch cache (tip differs)
+  4 changesets found
+  list of changesets:
+  ef1ea85a6374b77d6da9dcda9541f498f2d17df7
+  f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
+  911600dab2ae7a9baff75958b84fe606851ce955
+  e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
+  adding changesets
+  bundling: 1/4 changesets (25.00%)
+  bundling: 2/4 changesets (50.00%)
+  bundling: 3/4 changesets (75.00%)
+  bundling: 4/4 changesets (100.00%)
+  bundling: 1/4 manifests (25.00%)
+  bundling: 2/4 manifests (50.00%)
+  bundling: 3/4 manifests (75.00%)
+  bundling: 4/4 manifests (100.00%)
+  bundling: abc.txt 1/4 files (25.00%)
+  bundling: foo/Bar/file.txt 2/4 files (50.00%)
+  bundling: foo/file.txt 3/4 files (75.00%)
+  bundling: quux/file.py 4/4 files (100.00%)
+  changesets: 1 chunks
+  add changeset ef1ea85a6374
+  changesets: 2 chunks
+  add changeset f9cafe1212c8
+  changesets: 3 chunks
+  add changeset 911600dab2ae
+  changesets: 4 chunks
+  add changeset e8fc755d4d82
+  adding manifests
+  manifests: 1/4 chunks (25.00%)
+  manifests: 2/4 chunks (50.00%)
+  manifests: 3/4 chunks (75.00%)
+  manifests: 4/4 chunks (100.00%)
+  adding file changes
+  adding abc.txt revisions
+  files: 1/4 chunks (25.00%)
+  adding foo/Bar/file.txt revisions
+  files: 2/4 chunks (50.00%)
+  adding foo/file.txt revisions
+  files: 3/4 chunks (75.00%)
+  adding quux/file.py revisions
+  files: 4/4 chunks (100.00%)
+  added 4 changesets with 4 changes to 4 files (+1 heads)
+  calling hook pretxnchangegroup.acl: hgext.acl.hook
+  acl: acl.allow.branches enabled, 1 entries for user george
+  acl: acl.deny.branches not enabled
+  acl: acl.allow not enabled
+  acl: acl.deny not enabled
+  acl: branch access granted: "ef1ea85a6374" on branch "default"
+  acl: allowing changeset ef1ea85a6374
+  acl: branch access granted: "f9cafe1212c8" on branch "default"
+  acl: allowing changeset f9cafe1212c8
+  acl: branch access granted: "911600dab2ae" on branch "default"
+  acl: allowing changeset 911600dab2ae
+  acl: branch access granted: "e8fc755d4d82" on branch "foobar"
+  acl: allowing changeset e8fc755d4d82
+  updating the branch cache
+  checking for updated bookmarks
+  repository tip rolled back to revision 2 (undo push)
+  working directory now based on revision 2
+  2:fb35475503ef
+  
+Branch acl conflicting deny
+
+  $ init_config
+  $ echo "[acl.deny.branches]" >> $config
+  $ echo "foobar = astro" >> $config
+  $ echo "default = astro" >> $config
+  $ echo "* = george" >> $config
+  $ do_push george
+  Pushing as user george
+  hgrc = """
+  [acl]
+  sources = push
+  [extensions]
+  [acl.deny.branches]
+  foobar = astro
+  default = astro
+  * = george
+  """
+  pushing to ../b
+  query 1; heads
+  searching for changes
+  all remote heads known locally
+  invalidating branch cache (tip differs)
+  4 changesets found
+  list of changesets:
+  ef1ea85a6374b77d6da9dcda9541f498f2d17df7
+  f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
+  911600dab2ae7a9baff75958b84fe606851ce955
+  e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
+  adding changesets
+  bundling: 1/4 changesets (25.00%)
+  bundling: 2/4 changesets (50.00%)
+  bundling: 3/4 changesets (75.00%)
+  bundling: 4/4 changesets (100.00%)
+  bundling: 1/4 manifests (25.00%)
+  bundling: 2/4 manifests (50.00%)
+  bundling: 3/4 manifests (75.00%)
+  bundling: 4/4 manifests (100.00%)
+  bundling: abc.txt 1/4 files (25.00%)
+  bundling: foo/Bar/file.txt 2/4 files (50.00%)
+  bundling: foo/file.txt 3/4 files (75.00%)
+  bundling: quux/file.py 4/4 files (100.00%)
+  changesets: 1 chunks
+  add changeset ef1ea85a6374
+  changesets: 2 chunks
+  add changeset f9cafe1212c8
+  changesets: 3 chunks
+  add changeset 911600dab2ae
+  changesets: 4 chunks
+  add changeset e8fc755d4d82
+  adding manifests
+  manifests: 1/4 chunks (25.00%)
+  manifests: 2/4 chunks (50.00%)
+  manifests: 3/4 chunks (75.00%)
+  manifests: 4/4 chunks (100.00%)
+  adding file changes
+  adding abc.txt revisions
+  files: 1/4 chunks (25.00%)
+  adding foo/Bar/file.txt revisions
+  files: 2/4 chunks (50.00%)
+  adding foo/file.txt revisions
+  files: 3/4 chunks (75.00%)
+  adding quux/file.py revisions
+  files: 4/4 chunks (100.00%)
+  added 4 changesets with 4 changes to 4 files (+1 heads)
+  calling hook pretxnchangegroup.acl: hgext.acl.hook
+  acl: acl.allow.branches not enabled
+  acl: acl.deny.branches enabled, 1 entries for user george
+  acl: acl.allow not enabled
+  acl: acl.deny not enabled
+  error: pretxnchangegroup.acl hook failed: acl: user "george" denied on branch "default" (changeset "ef1ea85a6374")
+  transaction abort!
+  rollback completed
+  abort: acl: user "george" denied on branch "default" (changeset "ef1ea85a6374")
+  no rollback information available
+  2:fb35475503ef
+  
--- a/tests/test-add.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-add.t	Sat Jun 18 17:03:01 2011 -0500
@@ -33,6 +33,41 @@
   A a
   A b
 
+  $ echo foo > con.xml
+  $ hg --config ui.portablefilenames=jump add con.xml
+  abort: ui.portablefilenames value is invalid ('jump')
+  [255]
+  $ hg --config ui.portablefilenames=abort add con.xml
+  abort: filename contains 'con', which is reserved on Windows: 'con.xml'
+  [255]
+  $ hg st
+  A a
+  A b
+  ? con.xml
+  $ hg add con.xml
+  warning: filename contains 'con', which is reserved on Windows: 'con.xml'
+  $ hg st
+  A a
+  A b
+  A con.xml
+  $ echo bla > 'hello:world'
+  $ hg --config ui.portablefilenames=abort add
+  adding hello:world
+  abort: filename contains ':', which is reserved on Windows: 'hello:world'
+  [255]
+  $ hg st
+  A a
+  A b
+  A con.xml
+  ? hello:world
+  $ hg --config ui.portablefilenames=ignore add
+  adding hello:world
+  $ hg st
+  A a
+  A b
+  A con.xml
+  A hello:world
+
   $ hg ci -m 0 --traceback
 
 should fail
--- a/tests/test-addremove.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-addremove.t	Sat Jun 18 17:03:01 2011 -0500
@@ -10,14 +10,17 @@
   foo
   committed changeset 0:6f7f953567a2
   $ cd dir/
-  $ touch ../foo_2 bar_2
+  $ touch ../foo_2 bar_2 con.xml
   $ hg -v addremove
   adding dir/bar_2
+  adding dir/con.xml
   adding foo_2
+  warning: filename contains 'con', which is reserved on Windows: 'dir/con.xml'
   $ hg -v commit -m "add 2"
   dir/bar_2
+  dir/con.xml
   foo_2
-  committed changeset 1:e65414bf35c5
+  committed changeset 1:6bb597da00f1
 
   $ cd ..
   $ hg init sim
--- a/tests/test-alias.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-alias.t	Sat Jun 18 17:03:01 2011 -0500
@@ -17,6 +17,7 @@
   > mylog = log
   > lognull = log -r null
   > shortlog = log --template '{rev} {node|short} | {date|isodate}\n'
+  > positional = log --template '{\$2} {\$1} | {date|isodate}\n'
   > dln = lognull --debug
   > nousage = rollback
   > put = export -r 0 -o "\$FOO/%R.diff"
@@ -127,6 +128,10 @@
   $ hg shortlog
   0 e63c23eaa88a | 1970-01-01 00:00 +0000
 
+positional arguments
+
+  $ hg positional 'node|short' rev
+  0 e63c23eaa88a | 1970-01-01 00:00 +0000
 
 interaction with defaults
 
@@ -304,13 +309,7 @@
   
   alias for: hg root
   
-  print the root (top) of the current working directory
-  
-      Print the root directory of the current repository.
-  
-      Returns 0 on success.
-  
-  use "hg -v help rt" to show global options
+  use "hg help rt" to show the full help text
   [255]
 
 invalid global arguments for normal commands, aliases, and shell aliases
--- a/tests/test-annotate.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-annotate.t	Sat Jun 18 17:03:01 2011 -0500
@@ -193,6 +193,26 @@
   3 b:5: b5
   7 b:7: d
 
+Issue2807: alignment of line numbers with -l
+
+  $ echo more >> b
+  $ hg ci -mmore -d '5 0'
+  $ echo more >> b
+  $ hg ci -mmore -d '6 0'
+  $ echo more >> b
+  $ hg ci -mmore -d '7 0'
+  $ hg annotate -nlf b
+   0 a: 1: a
+   6 b: 2: z
+   1 a: 3: a
+   3 b: 4: b4
+   4 b: 5: c
+   3 b: 5: b5
+   7 b: 7: d
+   8 b: 8: more
+   9 b: 9: more
+  10 b:10: more
+
 linkrev vs rev
 
   $ hg annotate -r tip -n a
@@ -228,3 +248,8 @@
   $ hg annotate --follow foo
   foo: foo
 
+missing file
+
+  $ hg ann nosuchfile
+  abort: nosuchfile: no such file in rev e9e6b4fa872f
+  [255]
--- a/tests/test-archive.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-archive.t	Sat Jun 18 17:03:01 2011 -0500
@@ -1,6 +1,5 @@
-  $ mkdir test
+  $ hg init test
   $ cd test
-  $ hg init
   $ echo foo>foo
   $ hg commit -Am 1 -d '1 0'
   adding foo
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-atomictempfile.py	Sat Jun 18 17:03:01 2011 -0500
@@ -0,0 +1,49 @@
+import os
+import glob
+from mercurial.util import atomictempfile
+
+# basic usage
+def test1_simple():
+    if os.path.exists('foo'):
+        os.remove('foo')
+    file = atomictempfile('foo')
+    (dir, basename) = os.path.split(file._tempname)
+    assert not os.path.isfile('foo')
+    assert basename in glob.glob('.foo-*')
+
+    file.write('argh\n')
+    file.rename()
+
+    assert os.path.isfile('foo')
+    assert basename not in glob.glob('.foo-*')
+    print 'OK'
+
+# close() removes the temp file but does not make the write
+# permanent -- essentially discards your work (WTF?!)
+def test2_close():
+    if os.path.exists('foo'):
+        os.remove('foo')
+    file = atomictempfile('foo')
+    (dir, basename) = os.path.split(file._tempname)
+
+    file.write('yo\n')
+    file.close()
+
+    assert not os.path.isfile('foo')
+    assert basename not in os.listdir('.')
+    print 'OK'
+
+# if a programmer screws up and passes bad args to atomictempfile, they
+# get a plain ordinary TypeError, not infinite recursion
+def test3_oops():
+    try:
+        file = atomictempfile()
+    except TypeError:
+        print "OK"
+    else:
+        print "expected TypeError"
+
+if __name__ == '__main__':
+    test1_simple()
+    test2_close()
+    test3_oops()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-atomictempfile.py.out	Sat Jun 18 17:03:01 2011 -0500
@@ -0,0 +1,3 @@
+OK
+OK
+OK
--- a/tests/test-audit-path.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-audit-path.t	Sat Jun 18 17:03:01 2011 -0500
@@ -33,7 +33,7 @@
 
   $ hg init target
   $ cd target
-  $ hg unbundle $TESTDIR/tampered.hg
+  $ hg unbundle $TESTDIR/bundles/tampered.hg
   adding changesets
   adding manifests
   adding file changes
@@ -53,7 +53,7 @@
   $ hg manifest -r1
   foo/.hg/test
   $ hg update -Cr1
-  abort: path 'foo/.hg/test' is inside repo 'foo'
+  abort: path 'foo/.hg/test' is inside nested repo 'foo'
   [255]
 
 attack back/test where back symlinks to ..
--- a/tests/test-bad-extension.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-bad-extension.t	Sat Jun 18 17:03:01 2011 -0500
@@ -10,6 +10,6 @@
   $ hg -q help help
   *** failed to import extension badext from $TESTTMP/badext.py: bit bucket overflow
   *** failed to import extension badext2: No module named badext2
-  hg help [TOPIC]
+  hg help [-ec] [TOPIC]
   
   show help for a given topic or a help overview
--- a/tests/test-basic.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-basic.t	Sat Jun 18 17:03:01 2011 -0500
@@ -1,8 +1,7 @@
 Create a repository:
 
-  $ mkdir t
+  $ hg init t
   $ cd t
-  $ hg init
 
 Make a changeset:
 
@@ -20,6 +19,22 @@
   summary:     test
   
 
+Verify that updating to revision 0 via commands.update() works properly
+
+  $ cat <<EOF > update_to_rev0.py
+  > from mercurial import ui, hg, commands
+  > myui = ui.ui()
+  > repo = hg.repository(myui, path='.')
+  > commands.update(myui, repo, rev=0)
+  > EOF
+  $ hg up null
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ python ./update_to_rev0.py
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ hg identify -n
+  0
+ 
+
 Poke around at hashes:
 
   $ hg manifest --debug
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-batching.py	Sat Jun 18 17:03:01 2011 -0500
@@ -0,0 +1,175 @@
+# test-batching.py - tests for transparent command batching
+#
+# Copyright 2011 Peter Arrenbrecht <peter@arrenbrecht.ch>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2 or any later version.
+
+from mercurial.wireproto import localbatch, remotebatch, batchable, future
+
+# equivalent of repo.repository
+class thing(object):
+    def hello(self):
+        return "Ready."
+
+# equivalent of localrepo.localrepository
+class localthing(thing):
+    def foo(self, one, two=None):
+        if one:
+            return "%s and %s" % (one, two,)
+        return "Nope"
+    def bar(self, b, a):
+        return "%s und %s" % (b, a,)
+    def greet(self, name=None):
+        return "Hello, %s" % name
+    def batch(self):
+        '''Support for local batching.'''
+        return localbatch(self)
+
+# usage of "thing" interface
+def use(it):
+
+    # Direct call to base method shared between client and server.
+    print it.hello()
+
+    # Direct calls to proxied methods. They cause individual roundtrips.
+    print it.foo("Un", two="Deux")
+    print it.bar("Eins", "Zwei")
+
+    # Batched call to a couple of (possibly proxied) methods.
+    batch = it.batch()
+    # The calls return futures to eventually hold results.
+    foo = batch.foo(one="One", two="Two")
+    foo2 = batch.foo(None)
+    bar = batch.bar("Eins", "Zwei")
+    # We can call non-batchable proxy methods, but the break the current batch
+    # request and cause additional roundtrips.
+    greet = batch.greet(name="John Smith")
+    # We can also add local methods into the mix, but they break the batch too.
+    hello = batch.hello()
+    bar2 = batch.bar(b="Uno", a="Due")
+    # Only now are all the calls executed in sequence, with as few roundtrips
+    # as possible.
+    batch.submit()
+    # After the call to submit, the futures actually contain values.
+    print foo.value
+    print foo2.value
+    print bar.value
+    print greet.value
+    print hello.value
+    print bar2.value
+
+# local usage
+mylocal = localthing()
+print
+print "== Local"
+use(mylocal)
+
+# demo remoting; mimicks what wireproto and HTTP/SSH do
+
+# shared
+
+def escapearg(plain):
+    return (plain
+            .replace(':', '::')
+            .replace(',', ':,')
+            .replace(';', ':;')
+            .replace('=', ':='))
+def unescapearg(escaped):
+    return (escaped
+            .replace(':=', '=')
+            .replace(':;', ';')
+            .replace(':,', ',')
+            .replace('::', ':'))
+
+# server side
+
+# equivalent of wireproto's global functions
+class server:
+    def __init__(self, local):
+        self.local = local
+    def _call(self, name, args):
+        args = dict(arg.split('=', 1) for arg in args)
+        return getattr(self, name)(**args)
+    def perform(self, req):
+        print "REQ:", req
+        name, args = req.split('?', 1)
+        args = args.split('&')
+        vals = dict(arg.split('=', 1) for arg in args)
+        res = getattr(self, name)(**vals)
+        print "  ->", res
+        return res
+    def batch(self, cmds):
+        res = []
+        for pair in cmds.split(';'):
+            name, args = pair.split(':', 1)
+            vals = {}
+            for a in args.split(','):
+                if a:
+                    n, v = a.split('=')
+                    vals[n] = unescapearg(v)
+            res.append(escapearg(getattr(self, name)(**vals)))
+        return ';'.join(res)
+    def foo(self, one, two):
+        return mangle(self.local.foo(unmangle(one), unmangle(two)))
+    def bar(self, b, a):
+        return mangle(self.local.bar(unmangle(b), unmangle(a)))
+    def greet(self, name):
+        return mangle(self.local.greet(unmangle(name)))
+myserver = server(mylocal)
+
+# local side
+
+# equivalent of wireproto.encode/decodelist, that is, type-specific marshalling
+# here we just transform the strings a bit to check we're properly en-/decoding
+def mangle(s):
+    return ''.join(chr(ord(c) + 1) for c in s)
+def unmangle(s):
+    return ''.join(chr(ord(c) - 1) for c in s)
+
+# equivalent of wireproto.wirerepository and something like http's wire format
+class remotething(thing):
+    def __init__(self, server):
+        self.server = server
+    def _submitone(self, name, args):
+        req = name + '?' + '&'.join(['%s=%s' % (n, v) for n, v in args])
+        return self.server.perform(req)
+    def _submitbatch(self, cmds):
+        req = []
+        for name, args in cmds:
+            args = ','.join(n + '=' + escapearg(v) for n, v in args)
+            req.append(name + ':' + args)
+        req = ';'.join(req)
+        res = self._submitone('batch', [('cmds', req,)])
+        return res.split(';')
+
+    def batch(self):
+        return remotebatch(self)
+
+    @batchable
+    def foo(self, one, two=None):
+        if not one:
+            yield "Nope", None
+        encargs = [('one', mangle(one),), ('two', mangle(two),)]
+        encresref = future()
+        yield encargs, encresref
+        yield unmangle(encresref.value)
+
+    @batchable
+    def bar(self, b, a):
+        encresref = future()
+        yield [('b', mangle(b),), ('a', mangle(a),)], encresref
+        yield unmangle(encresref.value)
+
+    # greet is coded directly. It therefore does not support batching. If it
+    # does appear in a batch, the batch is split around greet, and the call to
+    # greet is done in its own roundtrip.
+    def greet(self, name=None):
+        return unmangle(self._submitone('greet', [('name', mangle(name),)]))
+
+# demo remote usage
+
+myproxy = remotething(myserver)
+print
+print "== Remote"
+use(myproxy)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-batching.py.out	Sat Jun 18 17:03:01 2011 -0500
@@ -0,0 +1,32 @@
+
+== Local
+Ready.
+Un and Deux
+Eins und Zwei
+One and Two
+Nope
+Eins und Zwei
+Hello, John Smith
+Ready.
+Uno und Due
+
+== Remote
+Ready.
+REQ: foo?one=Vo&two=Efvy
+  -> Vo!boe!Efvy
+Un and Deux
+REQ: bar?b=Fjot&a=[xfj
+  -> Fjot!voe![xfj
+Eins und Zwei
+REQ: batch?cmds=foo:one=Pof,two=Uxp;bar:b=Fjot,a=[xfj
+  -> Pof!boe!Uxp;Fjot!voe![xfj
+REQ: greet?name=Kpio!Tnjui
+  -> Ifmmp-!Kpio!Tnjui
+REQ: batch?cmds=bar:b=Vop,a=Evf
+  -> Vop!voe!Evf
+One and Two
+Nope
+Eins und Zwei
+Hello, John Smith
+Ready.
+Uno und Due
--- a/tests/test-bisect.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-bisect.t	Sat Jun 18 17:03:01 2011 -0500
@@ -377,6 +377,44 @@
   date:        Thu Jan 01 00:00:06 1970 +0000
   summary:     msg 6
   
+  $ hg log -r "bisected(good)"
+  changeset:   0:b99c7b9c8e11
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     msg 0
+  
+  changeset:   5:7874a09ea728
+  user:        test
+  date:        Thu Jan 01 00:00:05 1970 +0000
+  summary:     msg 5
+  
+  $ hg log -r "bisected(bad)"
+  changeset:   6:a3d5c6fdf0d3
+  user:        test
+  date:        Thu Jan 01 00:00:06 1970 +0000
+  summary:     msg 6
+  
+  $ hg log -r "bisected(skip)"
+  changeset:   1:5cd978ea5149
+  user:        test
+  date:        Thu Jan 01 00:00:01 1970 +0000
+  summary:     msg 1
+  
+  changeset:   2:db07c04beaca
+  user:        test
+  date:        Thu Jan 01 00:00:02 1970 +0000
+  summary:     msg 2
+  
+  changeset:   3:b53bea5e2fcb
+  user:        test
+  date:        Thu Jan 01 00:00:03 1970 +0000
+  summary:     msg 3
+  
+  changeset:   4:9b2ba8336a65
+  user:        test
+  date:        Thu Jan 01 00:00:04 1970 +0000
+  summary:     msg 4
+  
 
   $ set +e
 
--- a/tests/test-bisect2.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-bisect2.t	Sat Jun 18 17:03:01 2011 -0500
@@ -416,10 +416,14 @@
   summary:     merge 10,13
   
   Not all ancestors of this changeset have been checked.
-  To check the other ancestors, start from the common ancestor, dab8161ac8fc.
-  $ hg bisect -g 8 # dab8161ac8fc
+  Use bisect --extend to continue the bisection from
+  the common ancestor, dab8161ac8fc.
+  $ hg bisect --extend
+  Extending search to changeset 8:dab8161ac8fc
+  2 files updated, 0 files merged, 2 files removed, 0 files unresolved
+  $ hg bisect -g # dab8161ac8fc
   Testing changeset 9:3c77083deb4a (3 changesets remaining, ~1 tests)
-  1 files updated, 0 files merged, 2 files removed, 0 files unresolved
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
   $ hg bisect -b
   The first bad revision is:
   changeset:   9:3c77083deb4a
--- a/tests/test-bookmarks-current.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-bookmarks-current.t	Sat Jun 18 17:03:01 2011 -0500
@@ -99,3 +99,29 @@
 
   $ hg bookmark
    * Y                         0:719295282060
+
+set bookmark Z using -i
+
+  $ hg bookmark -r . -i Z
+  $ hg bookmarks
+   * Y                         0:719295282060
+     Z                         0:719295282060
+
+deactivate current bookmark using -i
+
+  $ hg bookmark -i Y
+  $ hg bookmarks
+     Y                         0:719295282060
+     Z                         0:719295282060
+
+  $ hg up -q Y
+  $ hg bookmarks
+   * Y                         0:719295282060
+     Z                         0:719295282060
+
+deactivate current bookmark while renaming
+
+  $ hg bookmark -i -m Y X
+  $ hg bookmarks
+     X                         0:719295282060
+     Z                         0:719295282060
--- a/tests/test-bookmarks-pushpull.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-bookmarks-pushpull.t	Sat Jun 18 17:03:01 2011 -0500
@@ -26,6 +26,7 @@
   adding manifests
   adding file changes
   added 1 changesets with 1 changes to 1 files
+  updating bookmark Y
   (run 'hg update' to get a working copy)
   $ hg bookmarks
      Y                         0:4e3505fd9583
@@ -38,7 +39,6 @@
   Z	4e3505fd95835d721066b76e75dbb8cc554d7f77
   $ hg pull -B X ../a
   pulling from ../a
-  searching for changes
   no changes found
   importing bookmark X
   $ hg bookmark
@@ -172,9 +172,22 @@
      foobar                    000000000000
   $ hg pull -B Z http://localhost:$HGPORT/
   pulling from http://localhost:$HGPORT/
-  searching for changes
   no changes found
   not updating divergent bookmark X
   importing bookmark Z
+  $ hg clone http://localhost:$HGPORT/ cloned-bookmarks
+  requesting all changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 3 changesets with 3 changes to 3 files (+1 heads)
+  updating to branch default
+  2 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ hg -R cloned-bookmarks bookmarks
+     X                         1:9b140be10808
+     Y                         0:4e3505fd9583
+     Z                         2:0d2164f0ce0d
+     foo                       -1:000000000000
+     foobar                    -1:000000000000
 
   $ kill `cat ../hg.pid`
--- a/tests/test-bookmarks.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-bookmarks.t	Sat Jun 18 17:03:01 2011 -0500
@@ -84,6 +84,10 @@
   date:        Thu Jan 01 00:00:00 1970 +0000
   summary:     1
   
+  $ hg log -r 'bookmark(unknown)'
+  abort: bookmark 'unknown' does not exist
+  [255]
+
   $ hg help revsets | grep 'bookmark('
       "bookmark([name])"
 
@@ -116,13 +120,13 @@
 rename nonexistent bookmark
 
   $ hg bookmark -m A B
-  abort: a bookmark of this name does not exist
+  abort: bookmark 'A' does not exist
   [255]
 
 rename to existent bookmark
 
   $ hg bookmark -m X Y
-  abort: a bookmark of the same name already exists
+  abort: bookmark 'Y' already exists (use -f to force)
   [255]
 
 force rename to existent bookmark
@@ -151,7 +155,7 @@
 delete nonexistent bookmark
 
   $ hg bookmark -d A
-  abort: a bookmark of this name does not exist
+  abort: bookmark 'A' does not exist
   [255]
 
 bookmark name with spaces should be stripped
@@ -189,7 +193,7 @@
 bookmark with existing name
 
   $ hg bookmark Z
-  abort: a bookmark of the same name already exists
+  abort: bookmark 'Z' already exists (use -f to force)
   [255]
 
 force bookmark with existing name
@@ -248,13 +252,93 @@
 
 test rollback
 
+  $ echo foo > f1
+  $ hg ci -Amr
+  adding f1
   $ hg bookmark -f Y -r 1
   $ hg bookmark -f Z -r 1
   $ hg rollback
-  repository tip rolled back to revision 1 (undo commit)
-  working directory now based on revision 0
+  repository tip rolled back to revision 2 (undo commit)
+  working directory now based on revision 2
+  $ hg bookmarks
+     X2                        1:925d80f479bb
+     Y                         2:db815d6d32e6
+   * Z                         2:db815d6d32e6
+     x  y                      2:db815d6d32e6
+
+test clone
+
   $ hg bookmarks
-     X                         0:f7b1eb17ad24
+     X2                        1:925d80f479bb
+     Y                         2:db815d6d32e6
+   * Z                         2:db815d6d32e6
+     x  y                      2:db815d6d32e6
+  $ hg clone . cloned-bookmarks
+  updating to branch default
+  2 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ hg -R cloned-bookmarks bookmarks
+     X2                        1:925d80f479bb
+     Y                         2:db815d6d32e6
+     Z                         2:db815d6d32e6
+     x  y                      2:db815d6d32e6
+
+test clone with pull protocol
+
+  $ hg clone --pull . cloned-bookmarks-pull
+  requesting all changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 3 changesets with 3 changes to 3 files (+1 heads)
+  updating to branch default
+  2 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ hg -R cloned-bookmarks-pull bookmarks
      X2                        1:925d80f479bb
-     Y                         -1:000000000000
-   * Z                         0:f7b1eb17ad24
+     Y                         2:db815d6d32e6
+     Z                         2:db815d6d32e6
+     x  y                      2:db815d6d32e6
+
+test clone with a specific revision
+
+  $ hg clone -r 925d80 . cloned-bookmarks-rev
+  adding changesets
+  adding manifests
+  adding file changes
+  added 2 changesets with 2 changes to 2 files
+  updating to branch default
+  2 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ hg -R cloned-bookmarks-rev bookmarks
+     X2                        1:925d80f479bb
+
+create bundle with two heads
+
+  $ hg clone . tobundle
+  updating to branch default
+  2 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ echo x > tobundle/x
+  $ hg -R tobundle add tobundle/x
+  $ hg -R tobundle commit -m'x'
+  $ hg -R tobundle update -r -2
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ echo y > tobundle/y
+  $ hg -R tobundle branch test
+  marked working directory as branch test
+  $ hg -R tobundle add tobundle/y
+  $ hg -R tobundle commit -m'y'
+  $ hg -R tobundle bundle tobundle.hg
+  searching for changes
+  2 changesets found
+  $ hg unbundle tobundle.hg
+  adding changesets
+  adding manifests
+  adding file changes
+  added 2 changesets with 2 changes to 2 files (+1 heads)
+  (run 'hg heads' to see heads, 'hg merge' to merge)
+  $ hg update
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ hg bookmarks
+     X2                        1:925d80f479bb
+     Y                         2:db815d6d32e6
+   * Z                         3:125c9a1d6df6
+     x  y                      2:db815d6d32e6
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-branch-tag-confict.t	Sat Jun 18 17:03:01 2011 -0500
@@ -0,0 +1,62 @@
+Initial setup.
+
+  $ hg init repo
+  $ cd repo
+  $ touch thefile
+  $ hg ci -A -m 'Initial commit.'
+  adding thefile
+
+Create a tag.
+
+  $ hg tag branchortag
+
+Create a branch with the same name as the tag.
+
+  $ hg branch branchortag
+  marked working directory as branch branchortag
+  $ hg ci -m 'Create a branch with the same name as a tag.'
+
+This is what we have:
+
+  $ hg log
+  changeset:   2:10519b3f489a
+  branch:      branchortag
+  tag:         tip
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     Create a branch with the same name as a tag.
+  
+  changeset:   1:2635c45ca99b
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     Added tag branchortag for changeset f57387372b5d
+  
+  changeset:   0:f57387372b5d
+  tag:         branchortag
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     Initial commit.
+  
+Update to the tag:
+
+  $ hg up 'tag(branchortag)'
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ hg parents
+  changeset:   0:f57387372b5d
+  tag:         branchortag
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     Initial commit.
+  
+Updating to the branch:
+
+  $ hg up 'branch(branchortag)'
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ hg parents
+  changeset:   2:10519b3f489a
+  branch:      branchortag
+  tag:         tip
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     Create a branch with the same name as a tag.
+  
--- a/tests/test-branches.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-branches.t	Sat Jun 18 17:03:01 2011 -0500
@@ -230,7 +230,7 @@
   default                        0:19709c5a4e75 (inactive)
   $ hg branches -c
   a branch name much longer than the default justification used by branches 7:10ff5895aa57
-  b                             12:2da6583810df (closed)
+  b                             12:e3d49c0575d8 (closed)
   c                              6:589736a22561 (inactive)
   a                              5:d8cbc61dbaa6 (inactive)
   default                        0:19709c5a4e75 (inactive)
@@ -240,7 +240,7 @@
   no open branch heads found on branches b
   [1]
   $ hg heads --closed b
-  changeset:   12:2da6583810df
+  changeset:   12:e3d49c0575d8
   branch:      b
   tag:         tip
   parent:      8:eebb944467c9
@@ -248,7 +248,7 @@
   date:        Thu Jan 01 00:00:09 1970 +0000
   summary:     close this part branch too
   
-  changeset:   11:c84627f3c15d
+  changeset:   11:d3f163457ebf
   branch:      b
   user:        test
   date:        Thu Jan 01 00:00:09 1970 +0000
@@ -261,13 +261,13 @@
 --- branch b is back in action
 
   $ hg branches -a
-  b                             13:6ac12926b8c3
+  b                             13:e23b5505d1ad
   a branch name much longer than the default justification used by branches 7:10ff5895aa57
 
 ---- test heads listings
 
   $ hg heads
-  changeset:   13:6ac12926b8c3
+  changeset:   13:e23b5505d1ad
   branch:      b
   tag:         tip
   user:        test
@@ -325,7 +325,7 @@
 branch b
 
   $ hg heads b
-  changeset:   13:6ac12926b8c3
+  changeset:   13:e23b5505d1ad
   branch:      b
   tag:         tip
   user:        test
@@ -333,14 +333,14 @@
   summary:     reopen branch with a change
   
   $ hg heads --closed b
-  changeset:   13:6ac12926b8c3
+  changeset:   13:e23b5505d1ad
   branch:      b
   tag:         tip
   user:        test
   date:        Thu Jan 01 00:00:09 1970 +0000
   summary:     reopen branch with a change
   
-  changeset:   11:c84627f3c15d
+  changeset:   11:d3f163457ebf
   branch:      b
   user:        test
   date:        Thu Jan 01 00:00:09 1970 +0000
@@ -350,6 +350,8 @@
 
   $ echo "[extensions]" >> $HGRCPATH
   $ echo "color =" >> $HGRCPATH
+  $ echo "[color]" >> $HGRCPATH
+  $ echo "mode = ansi" >> $HGRCPATH
 
   $ hg up -C c
   3 files updated, 0 files merged, 2 files removed, 0 files unresolved
@@ -357,7 +359,7 @@
   $ hg up -C b
   2 files updated, 0 files merged, 3 files removed, 0 files unresolved
   $ hg branches --color=always
-  \x1b[0;32mb\x1b[0m \x1b[0;33m                            13:6ac12926b8c3\x1b[0m (esc)
+  \x1b[0;32mb\x1b[0m \x1b[0;33m                            13:e23b5505d1ad\x1b[0m (esc)
   \x1b[0;0ma branch name much longer than the default justification used by branches\x1b[0m \x1b[0;33m7:10ff5895aa57\x1b[0m (esc)
   \x1b[0;0ma\x1b[0m \x1b[0;33m                             5:d8cbc61dbaa6\x1b[0m (inactive) (esc)
   \x1b[0;0mdefault\x1b[0m \x1b[0;33m                       0:19709c5a4e75\x1b[0m (inactive) (esc)
@@ -365,9 +367,9 @@
 default closed branch color:
 
   $ hg branches --color=always --closed
-  \x1b[0;32mb\x1b[0m \x1b[0;33m                            13:6ac12926b8c3\x1b[0m (esc)
+  \x1b[0;32mb\x1b[0m \x1b[0;33m                            13:e23b5505d1ad\x1b[0m (esc)
   \x1b[0;0ma branch name much longer than the default justification used by branches\x1b[0m \x1b[0;33m7:10ff5895aa57\x1b[0m (esc)
-  \x1b[0;30;1mc\x1b[0m \x1b[0;33m                            14:717d2e6fabe1\x1b[0m (closed) (esc)
+  \x1b[0;30;1mc\x1b[0m \x1b[0;33m                            14:f894c25619d3\x1b[0m (closed) (esc)
   \x1b[0;0ma\x1b[0m \x1b[0;33m                             5:d8cbc61dbaa6\x1b[0m (inactive) (esc)
   \x1b[0;0mdefault\x1b[0m \x1b[0;33m                       0:19709c5a4e75\x1b[0m (inactive) (esc)
 
@@ -383,7 +385,7 @@
 custom branch colors:
 
   $ hg branches --color=always
-  \x1b[0;31mb\x1b[0m \x1b[0;36m                            13:6ac12926b8c3\x1b[0m (esc)
+  \x1b[0;31mb\x1b[0m \x1b[0;36m                            13:e23b5505d1ad\x1b[0m (esc)
   \x1b[0;32ma branch name much longer than the default justification used by branches\x1b[0m \x1b[0;36m7:10ff5895aa57\x1b[0m (esc)
   \x1b[0;35ma\x1b[0m \x1b[0;36m                             5:d8cbc61dbaa6\x1b[0m (inactive) (esc)
   \x1b[0;35mdefault\x1b[0m \x1b[0;36m                       0:19709c5a4e75\x1b[0m (inactive) (esc)
@@ -391,8 +393,8 @@
 custom closed branch color:
 
   $ hg branches --color=always --closed
-  \x1b[0;31mb\x1b[0m \x1b[0;36m                            13:6ac12926b8c3\x1b[0m (esc)
+  \x1b[0;31mb\x1b[0m \x1b[0;36m                            13:e23b5505d1ad\x1b[0m (esc)
   \x1b[0;32ma branch name much longer than the default justification used by branches\x1b[0m \x1b[0;36m7:10ff5895aa57\x1b[0m (esc)
-  \x1b[0;34mc\x1b[0m \x1b[0;36m                            14:717d2e6fabe1\x1b[0m (closed) (esc)
+  \x1b[0;34mc\x1b[0m \x1b[0;36m                            14:f894c25619d3\x1b[0m (closed) (esc)
   \x1b[0;35ma\x1b[0m \x1b[0;36m                             5:d8cbc61dbaa6\x1b[0m (inactive) (esc)
   \x1b[0;35mdefault\x1b[0m \x1b[0;36m                       0:19709c5a4e75\x1b[0m (inactive) (esc)
--- a/tests/test-bundle-r.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-bundle-r.t	Sat Jun 18 17:03:01 2011 -0500
@@ -1,62 +1,15 @@
   $ hg init test
   $ cd test
-  $ echo "0" >> afile
-  $ hg add afile
-  $ hg commit -m "0.0"
-  $ echo "1" >> afile
-  $ hg commit -m "0.1"
-  $ echo "2" >> afile
-  $ hg commit -m "0.2"
-  $ echo "3" >> afile
-  $ hg commit -m "0.3"
-  $ hg update -C 0
+  $ hg unbundle $TESTDIR/bundles/remote.hg
+  adding changesets
+  adding manifests
+  adding file changes
+  added 9 changesets with 7 changes to 4 files (+1 heads)
+  (run 'hg heads' to see heads, 'hg merge' to merge)
+  $ hg up tip
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
-  $ echo "1" >> afile
-  $ hg commit -m "1.1"
-  created new head
-  $ echo "2" >> afile
-  $ hg commit -m "1.2"
-  $ echo "a line" > fred
-  $ echo "3" >> afile
-  $ hg add fred
-  $ hg commit -m "1.3"
-  $ hg mv afile adifferentfile
-  $ hg commit -m "1.3m"
-  $ hg update -C 3
-  1 files updated, 0 files merged, 2 files removed, 0 files unresolved
-  $ hg mv afile anotherfile
-  $ hg commit -m "0.3m"
-  $ hg debugindex .hg/store/data/afile.i
-     rev    offset  length   base linkrev nodeid       p1           p2
-       0         0       3      0       0 362fef284ce2 000000000000 000000000000
-       1         3       5      1       1 125144f7e028 362fef284ce2 000000000000
-       2         8       7      2       2 4c982badb186 125144f7e028 000000000000
-       3        15       9      3       3 19b1fc555737 4c982badb186 000000000000
-  $ hg debugindex .hg/store/data/adifferentfile.i
-     rev    offset  length   base linkrev nodeid       p1           p2
-       0         0      75      0       7 2565f3199a74 000000000000 000000000000
-  $ hg debugindex .hg/store/data/anotherfile.i
-     rev    offset  length   base linkrev nodeid       p1           p2
-       0         0      75      0       8 2565f3199a74 000000000000 000000000000
-  $ hg debugindex .hg/store/data/fred.i
-     rev    offset  length   base linkrev nodeid       p1           p2
-       0         0       8      0       6 12ab3bcc5ea4 000000000000 000000000000
-  $ hg debugindex .hg/store/00manifest.i
-     rev    offset  length   base linkrev nodeid       p1           p2
-       0         0      48      0       0 43eadb1d2d06 000000000000 000000000000
-       1        48      48      1       1 8b89697eba2c 43eadb1d2d06 000000000000
-       2        96      48      2       2 626a32663c2f 8b89697eba2c 000000000000
-       3       144      48      3       3 f54c32f13478 626a32663c2f 000000000000
-       4       192      58      3       6 de68e904d169 626a32663c2f 000000000000
-       5       250      68      3       7 09bb521d218d de68e904d169 000000000000
-       6       318      54      6       8 1fde233dfb0f f54c32f13478 000000000000
-  $ hg verify
-  checking changesets
-  checking manifests
-  crosschecking files in changesets and manifests
-  checking files
-  4 files, 9 changesets, 7 total revisions
   $ cd ..
+
   $ for i in 0 1 2 3 4 5 6 7 8; do
   >    mkdir test-"$i"
   >    hg --cwd test-"$i" init
@@ -79,7 +32,7 @@
   crosschecking files in changesets and manifests
   checking files
   1 files, 1 changesets, 1 total revisions
-  0:f9ee2f85a263
+  0:bfaf4b5cbf01
   searching for changes
   2 changesets found
   adding changesets
@@ -92,7 +45,7 @@
   crosschecking files in changesets and manifests
   checking files
   1 files, 2 changesets, 2 total revisions
-  1:34c2bf6b0626
+  1:21f32785131f
   searching for changes
   3 changesets found
   adding changesets
@@ -105,7 +58,7 @@
   crosschecking files in changesets and manifests
   checking files
   1 files, 3 changesets, 3 total revisions
-  2:e38ba6f5b7e0
+  2:4ce51a113780
   searching for changes
   4 changesets found
   adding changesets
@@ -118,7 +71,7 @@
   crosschecking files in changesets and manifests
   checking files
   1 files, 4 changesets, 4 total revisions
-  3:eebf5a27f8ca
+  3:93ee6ab32777
   searching for changes
   2 changesets found
   adding changesets
@@ -131,7 +84,7 @@
   crosschecking files in changesets and manifests
   checking files
   1 files, 2 changesets, 2 total revisions
-  1:095197eb4973
+  1:c70afb1ee985
   searching for changes
   3 changesets found
   adding changesets
@@ -144,7 +97,7 @@
   crosschecking files in changesets and manifests
   checking files
   1 files, 3 changesets, 3 total revisions
-  2:1bb50a9436a7
+  2:f03ae5a9b979
   searching for changes
   4 changesets found
   adding changesets
@@ -157,7 +110,7 @@
   crosschecking files in changesets and manifests
   checking files
   2 files, 4 changesets, 5 total revisions
-  3:7373c1169842
+  3:095cb14b1b4d
   searching for changes
   5 changesets found
   adding changesets
@@ -170,7 +123,7 @@
   crosschecking files in changesets and manifests
   checking files
   3 files, 5 changesets, 6 total revisions
-  4:a6a34bfa0076
+  4:faa2e4234c7a
   searching for changes
   5 changesets found
   adding changesets
@@ -183,7 +136,7 @@
   crosschecking files in changesets and manifests
   checking files
   2 files, 5 changesets, 5 total revisions
-  4:aa35859c02ea
+  4:916f1afdef90
   $ cd test-8
   $ hg pull ../test-7
   pulling from ../test-7
@@ -231,7 +184,8 @@
 issue76 msg2163
 
   $ hg -R test bundle --base 3 -r 3 -r 3 test-bundle-cset-3.hg
-  1 changesets found
+  no changes found
+  [1]
 
 Issue1910: 'hg bundle --base $head' does not exclude $head from
 result
@@ -247,18 +201,18 @@
 revision 2
 
   $ hg tip -q
-  2:e38ba6f5b7e0
+  2:4ce51a113780
   $ hg unbundle ../test-bundle-should-fail.hg
   adding changesets
   transaction abort!
   rollback completed
-  abort: 00changelog.i@eebf5a27f8ca: unknown parent!
+  abort: 00changelog.i@93ee6ab32777: unknown parent!
   [255]
 
 revision 2
 
   $ hg tip -q
-  2:e38ba6f5b7e0
+  2:4ce51a113780
   $ hg unbundle ../test-bundle-all.hg
   adding changesets
   adding manifests
@@ -269,7 +223,7 @@
 revision 8
 
   $ hg tip -q
-  8:aa35859c02ea
+  8:916f1afdef90
   $ hg verify
   checking changesets
   checking manifests
@@ -283,7 +237,7 @@
 revision 2
 
   $ hg tip -q
-  2:e38ba6f5b7e0
+  2:4ce51a113780
   $ hg unbundle ../test-bundle-branch1.hg
   adding changesets
   adding manifests
@@ -294,7 +248,7 @@
 revision 4
 
   $ hg tip -q
-  4:aa35859c02ea
+  4:916f1afdef90
   $ hg verify
   checking changesets
   checking manifests
@@ -314,7 +268,7 @@
 revision 6
 
   $ hg tip -q
-  6:a6a34bfa0076
+  6:faa2e4234c7a
   $ hg verify
   checking changesets
   checking manifests
@@ -334,7 +288,7 @@
 revision 4
 
   $ hg tip -q
-  4:aa35859c02ea
+  4:916f1afdef90
   $ hg verify
   checking changesets
   checking manifests
@@ -367,7 +321,7 @@
 revision 9
 
   $ hg tip -q
-  9:905597b0d5d4
+  9:03fc0b0e347c
   $ hg verify
   checking changesets
   checking manifests
--- a/tests/test-bundle.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-bundle.t	Sat Jun 18 17:03:01 2011 -0500
@@ -206,7 +206,7 @@
 hg -R bundle://../full.hg verify
 
   $ hg pull bundle://../full.hg
-  pulling from bundle://../full.hg
+  pulling from bundle:../full.hg
   requesting all changes
   adding changesets
   adding manifests
@@ -310,7 +310,7 @@
 Incoming full.hg in partial
 
   $ hg incoming bundle://../full.hg
-  comparing with bundle://../full.hg
+  comparing with bundle:../full.hg
   searching for changes
   changeset:   4:095197eb4973
   parent:      0:f9ee2f85a263
@@ -470,6 +470,22 @@
   
   $ cd ..
 
+test bundle with # in the filename (issue2154):
+
+  $ cp bundle.hg 'test#bundle.hg'
+  $ cd orig
+  $ hg incoming '../test#bundle.hg'
+  comparing with ../test
+  abort: unknown revision 'bundle.hg'!
+  [255]
+
+note that percent encoding is not handled:
+
+  $ hg incoming ../test%23bundle.hg
+  abort: repository ../test%23bundle.hg not found!
+  [255]
+  $ cd ..
+
 test for http://mercurial.selenic.com/bts/issue1144
 
 test that verify bundle does not traceback
@@ -545,32 +561,17 @@
 == bundling
 
   $ hg bundle bundle.hg part --debug
+  query 1; heads
   searching for changes
-  common changesets up to c0025332f9ed
+  all remote heads known locally
   2 changesets found
   list of changesets:
   d2ae7f538514cd87c17547b0de4cea71fe1af9fb
   5ece8e77363e2b5269e27c66828b72da29e4341a
-  bundling: 0 changesets
-  bundling: 0 changesets
-  bundling: 0 changesets
-  bundling: 1 changesets
-  bundling: 1 changesets
-  bundling: 1 changesets
-  bundling: 2 changesets
-  bundling: 0/2 manifests (0.00%)
-  bundling: 0/2 manifests (0.00%)
-  bundling: 0/2 manifests (0.00%)
-  bundling: 1/2 manifests (50.00%)
-  bundling: 1/2 manifests (50.00%)
+  bundling: 1/2 changesets (50.00%)
+  bundling: 2/2 changesets (100.00%)
   bundling: 1/2 manifests (50.00%)
   bundling: 2/2 manifests (100.00%)
-  bundling: b 0/2 files (0.00%)
-  bundling: b 0/2 files (0.00%)
-  bundling: b 0/2 files (0.00%)
-  bundling: b 0/2 files (0.00%)
-  bundling: b1 1/2 files (50.00%)
-  bundling: b1 1/2 files (50.00%)
-  bundling: b1 1/2 files (50.00%)
-  bundling: b1 1/2 files (50.00%)
+  bundling: b 1/2 files (50.00%)
+  bundling: b1 2/2 files (100.00%)
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-casecollision.t	Sat Jun 18 17:03:01 2011 -0500
@@ -0,0 +1,40 @@
+run only on case-sensitive filesystems
+
+  $ "$TESTDIR/hghave" no-icasefs || exit 80
+
+test file addition with colliding case
+
+  $ hg init repo1
+  $ cd repo1
+  $ echo a > a
+  $ echo A > A
+  $ hg add a
+  $ hg st
+  A a
+  ? A
+  $ hg add --config ui.portablefilenames=abort A
+  abort: possible case-folding collision for A
+  [255]
+  $ hg st
+  A a
+  ? A
+  $ hg add A
+  warning: possible case-folding collision for A
+  $ hg st
+  A A
+  A a
+  $ hg forget A
+  $ hg st
+  A a
+  ? A
+  $ hg add --config ui.portablefilenames=no A
+  $ hg st
+  A A
+  A a
+
+case changing rename must not warn or abort
+
+  $ echo c > c
+  $ hg ci -qAmx
+  $ hg mv c C
+  $ cd ..
--- a/tests/test-changelog-exec.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-changelog-exec.t	Sat Jun 18 17:03:01 2011 -0500
@@ -48,6 +48,6 @@
   
   
 
-  $ hg debugindex .hg/store/data/bar.i
+  $ hg debugindex bar
      rev    offset  length   base linkrev nodeid       p1           p2
        0         0       5      0       1 b004912a8510 000000000000 000000000000
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-check-pyflakes.t	Sat Jun 18 17:03:01 2011 -0500
@@ -0,0 +1,14 @@
+  $ "$TESTDIR/hghave" pyflakes || exit 80
+  $ cd $(dirname $TESTDIR)
+  $ pyflakes mercurial hgext 2>&1 | $TESTDIR/filterpyflakes.py
+  mercurial/hgweb/server.py:*: 'activeCount' imported but unused (glob)
+  mercurial/commands.py:*: 'base85' imported but unused (glob)
+  mercurial/commands.py:*: 'bdiff' imported but unused (glob)
+  mercurial/commands.py:*: 'mpatch' imported but unused (glob)
+  mercurial/commands.py:*: 'osutil' imported but unused (glob)
+  hgext/inotify/linux/__init__.py:*: 'from _inotify import *' used; unable to detect undefined names (glob)
+  mercurial/util.py:*: 'from posix import *' used; unable to detect undefined names (glob)
+  mercurial/windows.py:*: 'from win32 import *' used; unable to detect undefined names (glob)
+  mercurial/util.py:*: 'from windows import *' used; unable to detect undefined names (glob)
+  
+
--- a/tests/test-clone-failure.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-clone-failure.t	Sat Jun 18 17:03:01 2011 -0500
@@ -21,9 +21,8 @@
 
 Inaccessible destination
 
-  $ mkdir b
+  $ hg init b
   $ cd b
-  $ hg init
   $ hg clone . ../a
   abort: Permission denied: ../a
   [255]
@@ -44,10 +43,7 @@
 
 Default destination, same directory
 
-  $ mkdir q
-  $ cd q
-  $ hg init
-  $ cd ..
+  $ hg init q
   $ hg clone q
   destination directory: q
   abort: destination 'q' is not empty
--- a/tests/test-clone-r.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-clone-r.t	Sat Jun 18 17:03:01 2011 -0500
@@ -37,26 +37,26 @@
   $ hg mv afile anotherfile
   $ hg commit -m "0.3m"
 
-  $ hg debugindex -f 1 .hg/store/data/afile.i
+  $ hg debugindex -f 1 afile
      rev flag   offset   length     size   base   link     p1     p2       nodeid
        0 0000        0        3        2      0      0     -1     -1 362fef284ce2
        1 0000        3        5        4      1      1      0     -1 125144f7e028
        2 0000        8        7        6      2      2      1     -1 4c982badb186
        3 0000       15        9        8      3      3      2     -1 19b1fc555737
 
-  $ hg debugindex .hg/store/data/adifferentfile.i
+  $ hg debugindex adifferentfile
      rev    offset  length   base linkrev nodeid       p1           p2
        0         0      75      0       7 2565f3199a74 000000000000 000000000000
 
-  $ hg debugindex .hg/store/data/anotherfile.i
+  $ hg debugindex anotherfile
      rev    offset  length   base linkrev nodeid       p1           p2
        0         0      75      0       8 2565f3199a74 000000000000 000000000000
 
-  $ hg debugindex .hg/store/data/fred.i
+  $ hg debugindex fred
      rev    offset  length   base linkrev nodeid       p1           p2
        0         0       8      0       6 12ab3bcc5ea4 000000000000 000000000000
 
-  $ hg debugindex .hg/store/00manifest.i
+  $ hg debugindex --manifest
      rev    offset  length   base linkrev nodeid       p1           p2
        0         0      48      0       0 43eadb1d2d06 000000000000 000000000000
        1        48      48      1       1 8b89697eba2c 43eadb1d2d06 000000000000
--- a/tests/test-clone.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-clone.t	Sat Jun 18 17:03:01 2011 -0500
@@ -1,8 +1,7 @@
 Prepare repo a:
 
-  $ mkdir a
+  $ hg init a
   $ cd a
-  $ hg init
   $ echo a > a
   $ hg add a
   $ hg commit -m test
@@ -434,7 +433,7 @@
   > from mercurial import ui, hg
   > myui = ui.ui()
   > repo = hg.repository(myui, 'a')
-  > hg.clone(myui, repo, dest="ua")
+  > hg.clone(myui, {}, repo, dest="ua")
   > EOF
 
   $ python simpleclone.py
@@ -447,7 +446,7 @@
   > from mercurial import ui, hg
   > myui = ui.ui()
   > repo = hg.repository(myui, 'a')
-  > hg.clone(myui, repo, dest="ua", branch=["stable",])
+  > hg.clone(myui, {}, repo, dest="ua", branch=["stable",])
   > EOF
 
   $ python branchclone.py
--- a/tests/test-command-template.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-command-template.t	Sat Jun 18 17:03:01 2011 -0500
@@ -77,13 +77,13 @@
   7:-1   29114dbae42b   1970-01-12 13:46 +0000   user
     second
   
-  6:5,4   c7b487c6c50e   1970-01-18 08:40 +0000   person
+  6:5,4   d41e714fe50d   1970-01-18 08:40 +0000   person
     merge
   
   5:3   13207e5a10d9   1970-01-18 08:40 +0000   person
     new head
   
-  4   32a18f097fcc   1970-01-17 04:53 +0000   person
+  4   bbe44766e73d   1970-01-17 04:53 +0000   person
     new branch
   
   3   10e46f2dcbf4   1970-01-16 01:06 +0000   person
@@ -106,13 +106,13 @@
   7:-1   29114dbae42b   1970-01-12 13:46 +0000   User Name <user@hostname>
     second
   
-  6:5,4   c7b487c6c50e   1970-01-18 08:40 +0000   person
+  6:5,4   d41e714fe50d   1970-01-18 08:40 +0000   person
     merge
   
   5:3   13207e5a10d9   1970-01-18 08:40 +0000   person
     new head
   
-  4   32a18f097fcc   1970-01-17 04:53 +0000   person
+  4   bbe44766e73d   1970-01-17 04:53 +0000   person
     new branch
   
   3   10e46f2dcbf4   1970-01-16 01:06 +0000   person
@@ -139,13 +139,13 @@
   7:-1,-1   29114dbae42b   1970-01-12 13:46 +0000   User Name <user@hostname>
     second
   
-  6:5,4   c7b487c6c50e   1970-01-18 08:40 +0000   person
+  6:5,4   d41e714fe50d   1970-01-18 08:40 +0000   person
     merge
   
   5:3,-1   13207e5a10d9   1970-01-18 08:40 +0000   person
     new head
   
-  4:3,-1   32a18f097fcc   1970-01-17 04:53 +0000   person
+  4:3,-1   bbe44766e73d   1970-01-17 04:53 +0000   person
     new branch
   
   3:2,-1   10e46f2dcbf4   1970-01-16 01:06 +0000   person
@@ -182,9 +182,9 @@
   <date>1970-01-12T13:46:40+00:00</date>
   <msg xml:space="preserve">second</msg>
   </logentry>
-  <logentry revision="6" node="c7b487c6c50ef1cf464cafdc4f4f5e615fc5999f">
+  <logentry revision="6" node="d41e714fe50d9e4a5f11b4d595d543481b5f980b">
   <parent revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f" />
-  <parent revision="4" node="32a18f097fcccf76ef282f62f8a85b3adf8d13c4" />
+  <parent revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74" />
   <author email="person">person</author>
   <date>1970-01-18T08:40:01+00:00</date>
   <msg xml:space="preserve">merge</msg>
@@ -195,7 +195,7 @@
   <date>1970-01-18T08:40:00+00:00</date>
   <msg xml:space="preserve">new head</msg>
   </logentry>
-  <logentry revision="4" node="32a18f097fcccf76ef282f62f8a85b3adf8d13c4">
+  <logentry revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74">
   <branch>foo</branch>
   <author email="person">person</author>
   <date>1970-01-17T04:53:20+00:00</date>
@@ -253,9 +253,9 @@
   <path action="A">second</path>
   </paths>
   </logentry>
-  <logentry revision="6" node="c7b487c6c50ef1cf464cafdc4f4f5e615fc5999f">
+  <logentry revision="6" node="d41e714fe50d9e4a5f11b4d595d543481b5f980b">
   <parent revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f" />
-  <parent revision="4" node="32a18f097fcccf76ef282f62f8a85b3adf8d13c4" />
+  <parent revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74" />
   <author email="person">person</author>
   <date>1970-01-18T08:40:01+00:00</date>
   <msg xml:space="preserve">merge</msg>
@@ -271,7 +271,7 @@
   <path action="A">d</path>
   </paths>
   </logentry>
-  <logentry revision="4" node="32a18f097fcccf76ef282f62f8a85b3adf8d13c4">
+  <logentry revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74">
   <branch>foo</branch>
   <author email="person">person</author>
   <date>1970-01-17T04:53:20+00:00</date>
@@ -348,9 +348,9 @@
   </paths>
   <extra key="branch">default</extra>
   </logentry>
-  <logentry revision="6" node="c7b487c6c50ef1cf464cafdc4f4f5e615fc5999f">
+  <logentry revision="6" node="d41e714fe50d9e4a5f11b4d595d543481b5f980b">
   <parent revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f" />
-  <parent revision="4" node="32a18f097fcccf76ef282f62f8a85b3adf8d13c4" />
+  <parent revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74" />
   <author email="person">person</author>
   <date>1970-01-18T08:40:01+00:00</date>
   <msg xml:space="preserve">merge</msg>
@@ -369,7 +369,7 @@
   </paths>
   <extra key="branch">default</extra>
   </logentry>
-  <logentry revision="4" node="32a18f097fcccf76ef282f62f8a85b3adf8d13c4">
+  <logentry revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74">
   <branch>foo</branch>
   <parent revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47" />
   <parent revision="-1" node="0000000000000000000000000000000000000000" />
@@ -510,7 +510,7 @@
   1970-01-18  person  <person>
   
   	* merge
-  	[c7b487c6c50e]
+  	[d41e714fe50d]
   
   	* d:
   	new head
@@ -519,7 +519,7 @@
   1970-01-17  person  <person>
   
   	* new branch
-  	[32a18f097fcc] <foo>
+  	[bbe44766e73d] <foo>
   
   1970-01-16  person  <person>
   
@@ -560,12 +560,12 @@
   1970-01-18  person  <person>
   
   	* merge
-  	[c7b487c6c50e]
+  	[d41e714fe50d]
   
   1970-01-17  person  <person>
   
   	* new branch
-  	[32a18f097fcc] <foo>
+  	[bbe44766e73d] <foo>
   
 
 Keys work:
@@ -886,63 +886,63 @@
   files--debug: c
   files--debug: b
   files--debug: a
-  manifest: 8:94961b75a2da
-  manifest: 7:f2dbc354b94e
-  manifest: 6:91015e9dbdd7
-  manifest: 5:4dc3def4f9b4
-  manifest: 4:90ae8dda64e1
+  manifest: 6:94961b75a2da
+  manifest: 5:f2dbc354b94e
+  manifest: 4:4dc3def4f9b4
+  manifest: 4:4dc3def4f9b4
+  manifest: 3:cb5a1327723b
   manifest: 3:cb5a1327723b
   manifest: 2:6e0e82995c35
   manifest: 1:4e8d705b1e53
   manifest: 0:a0c8bcbbb45c
-  manifest--verbose: 8:94961b75a2da
-  manifest--verbose: 7:f2dbc354b94e
-  manifest--verbose: 6:91015e9dbdd7
-  manifest--verbose: 5:4dc3def4f9b4
-  manifest--verbose: 4:90ae8dda64e1
+  manifest--verbose: 6:94961b75a2da
+  manifest--verbose: 5:f2dbc354b94e
+  manifest--verbose: 4:4dc3def4f9b4
+  manifest--verbose: 4:4dc3def4f9b4
+  manifest--verbose: 3:cb5a1327723b
   manifest--verbose: 3:cb5a1327723b
   manifest--verbose: 2:6e0e82995c35
   manifest--verbose: 1:4e8d705b1e53
   manifest--verbose: 0:a0c8bcbbb45c
-  manifest--debug: 8:94961b75a2da554b4df6fb599e5bfc7d48de0c64
-  manifest--debug: 7:f2dbc354b94e5ec0b4f10680ee0cee816101d0bf
-  manifest--debug: 6:91015e9dbdd76a6791085d12b0a0ec7fcd22ffbf
-  manifest--debug: 5:4dc3def4f9b4c6e8de820f6ee74737f91e96a216
-  manifest--debug: 4:90ae8dda64e1a876c792bccb9af66284f6018363
+  manifest--debug: 6:94961b75a2da554b4df6fb599e5bfc7d48de0c64
+  manifest--debug: 5:f2dbc354b94e5ec0b4f10680ee0cee816101d0bf
+  manifest--debug: 4:4dc3def4f9b4c6e8de820f6ee74737f91e96a216
+  manifest--debug: 4:4dc3def4f9b4c6e8de820f6ee74737f91e96a216
+  manifest--debug: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc
   manifest--debug: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc
   manifest--debug: 2:6e0e82995c35d0d57a52aca8da4e56139e06b4b1
   manifest--debug: 1:4e8d705b1e53e3f9375e0e60dc7b525d8211fe55
   manifest--debug: 0:a0c8bcbbb45c63b90b70ad007bf38961f64f2af0
   node: 95c24699272ef57d062b8bccc32c878bf841784a
   node: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
-  node: c7b487c6c50ef1cf464cafdc4f4f5e615fc5999f
+  node: d41e714fe50d9e4a5f11b4d595d543481b5f980b
   node: 13207e5a10d9fd28ec424934298e176197f2c67f
-  node: 32a18f097fcccf76ef282f62f8a85b3adf8d13c4
+  node: bbe44766e73d5f11ed2177f1838de10c53ef3e74
   node: 10e46f2dcbf4823578cf180f33ecf0b957964c47
   node: 97054abb4ab824450e9164180baf491ae0078465
   node: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
   node: 1e4e1b8f71e05681d422154f5421e385fec3454f
   node--verbose: 95c24699272ef57d062b8bccc32c878bf841784a
   node--verbose: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
-  node--verbose: c7b487c6c50ef1cf464cafdc4f4f5e615fc5999f
+  node--verbose: d41e714fe50d9e4a5f11b4d595d543481b5f980b
   node--verbose: 13207e5a10d9fd28ec424934298e176197f2c67f
-  node--verbose: 32a18f097fcccf76ef282f62f8a85b3adf8d13c4
+  node--verbose: bbe44766e73d5f11ed2177f1838de10c53ef3e74
   node--verbose: 10e46f2dcbf4823578cf180f33ecf0b957964c47
   node--verbose: 97054abb4ab824450e9164180baf491ae0078465
   node--verbose: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
   node--verbose: 1e4e1b8f71e05681d422154f5421e385fec3454f
   node--debug: 95c24699272ef57d062b8bccc32c878bf841784a
   node--debug: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
-  node--debug: c7b487c6c50ef1cf464cafdc4f4f5e615fc5999f
+  node--debug: d41e714fe50d9e4a5f11b4d595d543481b5f980b
   node--debug: 13207e5a10d9fd28ec424934298e176197f2c67f
-  node--debug: 32a18f097fcccf76ef282f62f8a85b3adf8d13c4
+  node--debug: bbe44766e73d5f11ed2177f1838de10c53ef3e74
   node--debug: 10e46f2dcbf4823578cf180f33ecf0b957964c47
   node--debug: 97054abb4ab824450e9164180baf491ae0078465
   node--debug: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
   node--debug: 1e4e1b8f71e05681d422154f5421e385fec3454f
   parents: 
   parents: -1:000000000000 
-  parents: 5:13207e5a10d9 4:32a18f097fcc 
+  parents: 5:13207e5a10d9 4:bbe44766e73d 
   parents: 3:10e46f2dcbf4 
   parents: 
   parents: 
@@ -951,7 +951,7 @@
   parents: 
   parents--verbose: 
   parents--verbose: -1:000000000000 
-  parents--verbose: 5:13207e5a10d9 4:32a18f097fcc 
+  parents--verbose: 5:13207e5a10d9 4:bbe44766e73d 
   parents--verbose: 3:10e46f2dcbf4 
   parents--verbose: 
   parents--verbose: 
@@ -960,7 +960,7 @@
   parents--verbose: 
   parents--debug: 7:29114dbae42b9f078cf2714dbe3a86bba8ec7453 -1:0000000000000000000000000000000000000000 
   parents--debug: -1:0000000000000000000000000000000000000000 -1:0000000000000000000000000000000000000000 
-  parents--debug: 5:13207e5a10d9fd28ec424934298e176197f2c67f 4:32a18f097fcccf76ef282f62f8a85b3adf8d13c4 
+  parents--debug: 5:13207e5a10d9fd28ec424934298e176197f2c67f 4:bbe44766e73d5f11ed2177f1838de10c53ef3e74 
   parents--debug: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47 -1:0000000000000000000000000000000000000000 
   parents--debug: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47 -1:0000000000000000000000000000000000000000 
   parents--debug: 2:97054abb4ab824450e9164180baf491ae0078465 -1:0000000000000000000000000000000000000000 
@@ -1115,7 +1115,7 @@
   $ hg log --template '{date|age}\n' > /dev/null || exit 1
 
   $ hg log -l1 --template '{date|age}\n' 
-  in the future
+  8 years from now
   $ hg log --template '{date|date}\n'
   Wed Jan 01 10:01:00 2020 +0000
   Mon Jan 12 13:46:40 1970 +0000
@@ -1174,9 +1174,9 @@
   $ hg log --template '{node|short}\n'
   95c24699272e
   29114dbae42b
-  c7b487c6c50e
+  d41e714fe50d
   13207e5a10d9
-  32a18f097fcc
+  bbe44766e73d
   10e46f2dcbf4
   97054abb4ab8
   b608e9d1a3f0
@@ -1197,9 +1197,9 @@
   8: 
   7: 8:95c24699272e
   6: 
-  5: 6:c7b487c6c50e
-  4: 6:c7b487c6c50e
-  3: 4:32a18f097fcc 5:13207e5a10d9
+  5: 6:d41e714fe50d
+  4: 6:d41e714fe50d
+  3: 4:bbe44766e73d 5:13207e5a10d9
   2: 3:10e46f2dcbf4
   1: 2:97054abb4ab8
   0: 1:b608e9d1a3f0
--- a/tests/test-commit-copy.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-commit-copy.t	Sat Jun 18 17:03:01 2011 -0500
@@ -10,7 +10,7 @@
 
   $ hg debugrename foo
   foo renamed from bar:26d3ca0dfd18e44d796b564e38dd173c9668d3a9
-  $ hg debugindex .hg/store/data/bar.i
+  $ hg debugindex bar
      rev    offset  length   base linkrev nodeid       p1           p2
        0         0       6      0       0 26d3ca0dfd18 000000000000 000000000000
        1         6       7      1       1 d267bddd54f7 26d3ca0dfd18 000000000000
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-commit-multiple.t	Sat Jun 18 17:03:01 2011 -0500
@@ -0,0 +1,129 @@
+# reproduce issue2264, issue2516
+
+create test repo
+  $ cat <<EOF >> $HGRCPATH
+  > [extensions]
+  > transplant =
+  > graphlog =
+  > EOF
+  $ hg init repo
+  $ cd repo
+  $ template="{rev}  {desc|firstline}  [{branch}]\n"
+
+# we need to start out with two changesets on the default branch
+# in order to avoid the cute little optimization where transplant
+# pulls rather than transplants
+add initial changesets
+  $ echo feature1 > file1
+  $ hg ci -Am"feature 1"
+  adding file1
+  $ echo feature2 >> file2
+  $ hg ci -Am"feature 2"
+  adding file2
+
+# The changes to 'bugfix' are enough to show the bug: in fact, with only
+# those changes, it's a very noisy crash ("RuntimeError: nothing
+# committed after transplant").  But if we modify a second file in the
+# transplanted changesets, the bug is much more subtle: transplant
+# silently drops the second change to 'bugfix' on the floor, and we only
+# see it when we run 'hg status' after transplanting.  Subtle data loss
+# bugs are worse than crashes, so reproduce the subtle case here.
+commit bug fixes on bug fix branch
+  $ hg branch fixes
+  marked working directory as branch fixes
+  $ echo fix1 > bugfix
+  $ echo fix1 >> file1
+  $ hg ci -Am"fix 1"
+  adding bugfix
+  $ echo fix2 > bugfix
+  $ echo fix2 >> file1
+  $ hg ci -Am"fix 2"
+  $ hg glog --template="$template"
+  @  3  fix 2  [fixes]
+  |
+  o  2  fix 1  [fixes]
+  |
+  o  1  feature 2  [default]
+  |
+  o  0  feature 1  [default]
+  
+transplant bug fixes onto release branch
+  $ hg update 0
+  1 files updated, 0 files merged, 2 files removed, 0 files unresolved
+  $ hg branch release
+  marked working directory as branch release
+  $ hg transplant 2 3
+  applying [0-9a-f]{12} (re)
+  [0-9a-f]{12} transplanted to [0-9a-f]{12} (re)
+  applying [0-9a-f]{12} (re)
+  [0-9a-f]{12} transplanted to [0-9a-f]{12} (re)
+  $ hg glog --template="$template"
+  @  5  fix 2  [release]
+  |
+  o  4  fix 1  [release]
+  |
+  | o  3  fix 2  [fixes]
+  | |
+  | o  2  fix 1  [fixes]
+  | |
+  | o  1  feature 2  [default]
+  |/
+  o  0  feature 1  [default]
+  
+  $ hg status
+  $ hg status --rev 0:4
+  M file1
+  A bugfix
+  $ hg status --rev 4:5
+  M bugfix
+  M file1
+
+now test that we fixed the bug for all scripts/extensions
+  $ cat > $TESTTMP/committwice.py <<__EOF__
+  > from mercurial import ui, hg, match, node
+  > from time import sleep
+  > 
+  > def replacebyte(fn, b):
+  >     f = open(fn, "rb+")
+  >     f.seek(0, 0)
+  >     f.write(b)
+  >     f.close()
+  > 
+  > def printfiles(repo, rev):
+  >     print "revision %s files: %s" % (rev, repo[rev].files())
+  > 
+  > repo = hg.repository(ui.ui(), '.')
+  > assert len(repo) == 6, \
+  >        "initial: len(repo): %d, expected: 6" % len(repo)
+  > 
+  > replacebyte("bugfix", "u")
+  > sleep(2)
+  > try:
+  >     print "PRE: len(repo): %d" % len(repo)
+  >     wlock = repo.wlock()
+  >     lock = repo.lock()
+  >     replacebyte("file1", "x")
+  >     repo.commit(text="x", user="test", date=(0, 0))
+  >     replacebyte("file1", "y")
+  >     repo.commit(text="y", user="test", date=(0, 0))
+  >     print "POST: len(repo): %d" % len(repo)
+  > finally:
+  >     lock.release()
+  >     wlock.release()
+  > printfiles(repo, 6)
+  > printfiles(repo, 7)
+  > __EOF__
+  $ $PYTHON $TESTTMP/committwice.py
+  PRE: len(repo): 6
+  POST: len(repo): 8
+  revision 6 files: ['bugfix', 'file1']
+  revision 7 files: ['file1']
+
+Do a size-preserving modification outside of that process
+  $ echo abcd > bugfix
+  $ hg status
+  M bugfix
+  $ hg log --template "{rev}  {desc}  {files}\n" -r5:
+  5  fix 2  bugfix file1
+  6  x  bugfix file1
+  7  y  file1
--- a/tests/test-commit.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-commit.t	Sat Jun 18 17:03:01 2011 -0500
@@ -32,7 +32,7 @@
   $ hg add bar
   $ rm bar
   $ hg commit -m commit-8
-  nothing changed
+  nothing changed (1 missing files, see 'hg status')
   [1]
   $ hg commit -m commit-8-2 bar
   abort: bar: file not found!
@@ -98,7 +98,7 @@
   $ echo foo >> foo
   $ echo fake >> .hg/requires
   $ hg commit -m bla
-  abort: requirement 'fake' not supported!
+  abort: unknown repository format: requires feature 'fake' (upgrade Mercurial)!
   [255]
 
   $ cd ..
--- a/tests/test-confused-revert.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-confused-revert.t	Sat Jun 18 17:03:01 2011 -0500
@@ -59,7 +59,8 @@
 Revert should fail:
 
   $ hg revert
-  abort: uncommitted merge - use "hg update", see "hg help revert"
+  abort: no files or directories specified
+  (use --all to revert all files)
   [255]
 
 Revert should be ok now:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-contrib.t	Sat Jun 18 17:03:01 2011 -0500
@@ -0,0 +1,302 @@
+Set vars:
+
+  $ CONTRIBDIR=$TESTDIR/../contrib
+
+Prepare repo-a:
+
+  $ hg init repo-a
+  $ cd repo-a
+
+  $ echo this is file a > a
+  $ hg add a
+  $ hg commit -m first
+
+  $ echo adding to file a >> a
+  $ hg commit -m second
+
+  $ echo adding more to file a >> a
+  $ hg commit -m third
+
+  $ hg verify
+  checking changesets
+  checking manifests
+  crosschecking files in changesets and manifests
+  checking files
+  1 files, 3 changesets, 3 total revisions
+
+Dumping revlog of file a to stdout:
+
+  $ python $CONTRIBDIR/dumprevlog .hg/store/data/a.i
+  file: .hg/store/data/a.i
+  node: 183d2312b35066fb6b3b449b84efc370d50993d0
+  linkrev: 0
+  parents: 0000000000000000000000000000000000000000 0000000000000000000000000000000000000000
+  length: 15
+  -start-
+  this is file a
+  
+  -end-
+  node: b1047953b6e6b633c0d8197eaa5116fbdfd3095b
+  linkrev: 1
+  parents: 183d2312b35066fb6b3b449b84efc370d50993d0 0000000000000000000000000000000000000000
+  length: 32
+  -start-
+  this is file a
+  adding to file a
+  
+  -end-
+  node: 8c4fd1f7129b8cdec6c7f58bf48fb5237a4030c1
+  linkrev: 2
+  parents: b1047953b6e6b633c0d8197eaa5116fbdfd3095b 0000000000000000000000000000000000000000
+  length: 54
+  -start-
+  this is file a
+  adding to file a
+  adding more to file a
+  
+  -end-
+
+Dump all revlogs to file repo.dump:
+
+  $ find .hg/store -name "*.i" | sort | xargs python $CONTRIBDIR/dumprevlog > ../repo.dump
+  $ cd ..
+
+Undumping into repo-b:
+
+  $ hg init repo-b
+  $ cd repo-b
+  $ python $CONTRIBDIR/undumprevlog < ../repo.dump
+  .hg/store/00changelog.i
+  .hg/store/00manifest.i
+  .hg/store/data/a.i
+  $ cd ..
+
+Rebuild fncache with clone --pull:
+
+  $ hg clone --pull -U repo-b repo-c
+  requesting all changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 3 changesets with 3 changes to 1 files
+
+Verify:
+
+  $ hg -R repo-c verify
+  checking changesets
+  checking manifests
+  crosschecking files in changesets and manifests
+  checking files
+  1 files, 3 changesets, 3 total revisions
+
+Compare repos:
+
+  $ hg -R repo-c incoming repo-a
+  comparing with repo-a
+  searching for changes
+  no changes found
+  [1]
+
+  $ hg -R repo-a incoming repo-c
+  comparing with repo-c
+  searching for changes
+  no changes found
+  [1]
+
+
+Test shrink-revlog:
+  $ cd repo-a
+  $ hg --config extensions.shrink=$CONTRIBDIR/shrink-revlog.py shrink
+  shrinking $TESTTMP/repo-a/.hg/store/00manifest.i
+  reading revs
+  sorting revs
+  writing revs
+  old file size:          324 bytes (   0.0 MiB)
+  new file size:          324 bytes (   0.0 MiB)
+  shrinkage: 0.0% (1.0x)
+  note: old revlog saved in:
+    $TESTTMP/repo-a/.hg/store/00manifest.i.old
+    $TESTTMP/repo-a/.hg/store/00manifest.d.old
+  (You can delete those files when you are satisfied that your
+  repository is still sane.  Running 'hg verify' is strongly recommended.)
+  $ hg verify
+  checking changesets
+  checking manifests
+  crosschecking files in changesets and manifests
+  checking files
+  1 files, 3 changesets, 3 total revisions
+  $ cd ..
+
+Test simplemerge command:
+
+  $ cp "$CONTRIBDIR/simplemerge" .
+  $ echo base > base
+  $ echo local > local
+  $ cat base >> local
+  $ cp local orig
+  $ cat base > other
+  $ echo other >> other
+
+changing local directly
+
+  $ python simplemerge local base other && echo "merge succeeded"
+  merge succeeded
+  $ cat local
+  local
+  base
+  other
+  $ cp orig local
+
+printing to stdout
+
+  $ python simplemerge -p local base other
+  local
+  base
+  other
+
+local:
+
+  $ cat local
+  local
+  base
+
+conflicts
+
+  $ cp base conflict-local
+  $ cp other conflict-other
+  $ echo not other >> conflict-local
+  $ echo end >> conflict-local
+  $ echo end >> conflict-other
+  $ python simplemerge -p conflict-local base conflict-other
+  base
+  <<<<<<< conflict-local
+  not other
+  =======
+  other
+  >>>>>>> conflict-other
+  end
+  warning: conflicts during merge.
+  [1]
+
+--no-minimal
+
+  $ python simplemerge -p --no-minimal conflict-local base conflict-other
+  base
+  <<<<<<< conflict-local
+  not other
+  end
+  =======
+  other
+  end
+  >>>>>>> conflict-other
+  warning: conflicts during merge.
+  [1]
+
+1 label
+
+  $ python simplemerge -p -L foo conflict-local base conflict-other
+  base
+  <<<<<<< foo
+  not other
+  =======
+  other
+  >>>>>>> conflict-other
+  end
+  warning: conflicts during merge.
+  [1]
+
+2 labels
+
+  $ python simplemerge -p -L foo -L bar conflict-local base conflict-other
+  base
+  <<<<<<< foo
+  not other
+  =======
+  other
+  >>>>>>> bar
+  end
+  warning: conflicts during merge.
+  [1]
+
+too many labels
+
+  $ python simplemerge -p -L foo -L bar -L baz conflict-local base conflict-other
+  abort: can only specify two labels.
+  [255]
+
+binary file
+
+  $ python -c "f = file('binary-local', 'w'); f.write('\x00'); f.close()"
+  $ cat orig >> binary-local
+  $ python simplemerge -p binary-local base other
+  warning: binary-local looks like a binary file.
+  [1]
+
+binary file --text
+
+  $ python simplemerge -a -p binary-local base other 2>&1
+  warning: binary-local looks like a binary file.
+  \x00local (esc)
+  base
+  other
+
+help
+
+  $ python simplemerge --help
+  simplemerge [OPTS] LOCAL BASE OTHER
+  
+      Simple three-way file merge utility with a minimal feature set.
+  
+      Apply to LOCAL the changes necessary to go from BASE to OTHER.
+  
+      By default, LOCAL is overwritten with the results of this operation.
+  
+  options:
+   -L --label       labels to use on conflict markers
+   -a --text        treat all files as text
+   -p --print       print results instead of overwriting LOCAL
+      --no-minimal  do not try to minimize conflict regions
+   -h --help        display help and exit
+   -q --quiet       suppress output
+
+wrong number of arguments
+
+  $ python simplemerge
+  simplemerge: wrong number of arguments
+  simplemerge [OPTS] LOCAL BASE OTHER
+  
+      Simple three-way file merge utility with a minimal feature set.
+  
+      Apply to LOCAL the changes necessary to go from BASE to OTHER.
+  
+      By default, LOCAL is overwritten with the results of this operation.
+  
+  options:
+   -L --label       labels to use on conflict markers
+   -a --text        treat all files as text
+   -p --print       print results instead of overwriting LOCAL
+      --no-minimal  do not try to minimize conflict regions
+   -h --help        display help and exit
+   -q --quiet       suppress output
+  [1]
+
+bad option
+
+  $ python simplemerge --foo -p local base other
+  simplemerge: option --foo not recognized
+  simplemerge [OPTS] LOCAL BASE OTHER
+  
+      Simple three-way file merge utility with a minimal feature set.
+  
+      Apply to LOCAL the changes necessary to go from BASE to OTHER.
+  
+      By default, LOCAL is overwritten with the results of this operation.
+  
+  options:
+   -L --label       labels to use on conflict markers
+   -a --text        treat all files as text
+   -p --print       print results instead of overwriting LOCAL
+      --no-minimal  do not try to minimize conflict regions
+   -h --help        display help and exit
+   -q --quiet       suppress output
+  [1]
--- a/tests/test-convert-baz	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-convert-baz	Sat Jun 18 17:03:01 2011 -0500
@@ -2,10 +2,6 @@
 
 "$TESTDIR/hghave" baz || exit 80
 
-mkdir do_not_use_HOME_baz
-cd do_not_use_HOME_baz
-HOME=`pwd`; export HOME
-cd ..
 baz my-id "mercurial <mercurial@selenic.com>"
 
 echo "[extensions]" >> $HGRCPATH
--- a/tests/test-convert-cvs-detectmerge.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-convert-cvs-detectmerge.t	Sat Jun 18 17:03:01 2011 -0500
@@ -16,6 +16,7 @@
 
   $ cvsci()
   > {
+  >     sleep 1
   >     cvs -f ci "$@" > /dev/null
   > }
 
@@ -53,7 +54,6 @@
 modify file1 on branch v1_0
 
   $ cvscall -Q update -rv1_0
-  $ sleep 1
   $ echo "change" >> file1
   $ cvsci -m"add text"
   cvs commit: Examining .
@@ -96,7 +96,6 @@
 this will create rev 1.3
 change on trunk to backport
 
-  $ sleep 1
   $ echo "backport me" >> file1
   $ cvsci -m"add other text" file1
   $ cvscall log file1
@@ -150,7 +149,6 @@
 fix bug on v1_1, merge to trunk with error
 
   $ cvscall -Q update -rv1_1
-  $ sleep 1
   $ echo "merge forward" >> file1
   $ cvscall -Q tag unmerged
   $ cvsci -m"fix file1"
--- a/tests/test-convert-cvs-synthetic.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-convert-cvs-synthetic.t	Sat Jun 18 17:03:01 2011 -0500
@@ -23,6 +23,7 @@
 
   $ cvsci()
   > {
+  >     sleep 1
   >     cvs -f ci "$@" >/dev/null
   > }
   $ cvscall -d "$CVSROOT" init
--- a/tests/test-convert-darcs.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-convert-darcs.t	Sat Jun 18 17:03:01 2011 -0500
@@ -4,7 +4,6 @@
   $ echo "convert=" >> $HGRCPATH
   $ echo 'graphlog =' >> $HGRCPATH
   $ DARCS_EMAIL='test@example.org'; export DARCS_EMAIL
-  $ HOME=`pwd`/do_not_use_HOME_darcs; export HOME
 
 skip if we can't import elementtree
 
@@ -17,7 +16,7 @@
 
 try converting darcs1 repository
 
-  $ hg clone -q "$TESTDIR/darcs1.hg" darcs
+  $ hg clone -q "$TESTDIR/bundles/darcs1.hg" darcs
   $ hg convert -s darcs darcs/darcs1 2>&1 | grep darcs-1.0
   darcs-1.0 repository format is unsupported, please upgrade
 
--- a/tests/test-convert-filemap.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-convert-filemap.t	Sat Jun 18 17:03:01 2011 -0500
@@ -14,11 +14,13 @@
   $ mkdir -p dir/subdir
   $ echo dir/file >> dir/file
   $ echo dir/file2 >> dir/file2
+  $ echo dir/file3 >> dir/file3 # to be corrupted in rev 0
   $ echo dir/subdir/file3 >> dir/subdir/file3
   $ echo dir/subdir/file4 >> dir/subdir/file4
   $ hg ci -d '0 0' -qAm '0: add foo baz dir/'
   $ echo bar > bar
   $ echo quux > quux
+  $ echo dir/file4 >> dir/file4 # to be corrupted in rev 1
   $ hg copy foo copied
   $ hg ci -d '1 0' -qAm '1: add bar quux; copy foo to copied'
   $ echo >> foo
@@ -63,9 +65,9 @@
   | |
   o |  2 "2: change foo" files: foo
   |/
-  o  1 "1: add bar quux; copy foo to copied" files: bar copied quux
+  o  1 "1: add bar quux; copy foo to copied" files: bar copied dir/file4 quux
   |
-  o  0 "0: add foo baz dir/" files: baz dir/file dir/file2 dir/subdir/file3 dir/subdir/file4 foo
+  o  0 "0: add foo baz dir/" files: baz dir/file dir/file2 dir/file3 dir/subdir/file3 dir/subdir/file4 foo
   
 
 final file versions in this repo:
@@ -76,6 +78,8 @@
   7711d36246cc83e61fb29cd6d4ef394c63f1ceaf 644   copied
   3e20847584beff41d7cd16136b7331ab3d754be0 644   dir/file
   75e6d3f8328f5f6ace6bf10b98df793416a09dca 644   dir/file2
+  e96dce0bc6a217656a3a410e5e6bec2c4f42bf7c 644   dir/file3
+  6edd55f559cdce67132b12ca09e09cee08b60442 644   dir/file4
   5fe139720576e18e34bcc9f79174db8897c8afe9 644   dir/subdir/file3
   57a1c1511590f3de52874adfa04effe8a77d64af 644   dir/subdir/file4
   9a7b52012991e4873687192c3e17e61ba3e837a3 644   foo
@@ -234,7 +238,14 @@
   > exclude dir/subdir
   > include dir/subdir/file3
   > EOF
-  $ hg -q convert --filemap renames.fmap --datesort source renames.repo
+  $ rm source/.hg/store/data/dir/file3.i
+  $ rm source/.hg/store/data/dir/file4.i
+  $ hg -q convert --filemap renames.fmap --datesort source dummydest
+  abort: data/dir/file3.i@e96dce0bc6a2: no match found!
+  [255]
+  $ hg -q convert --filemap renames.fmap --datesort --config convert.hg.ignoreerrors=1 source renames.repo
+  ignoring: data/dir/file3.i@e96dce0bc6a2: no match found
+  ignoring: data/dir/file4.i@6edd55f559cd: no match found
   $ hg up -q -R renames.repo
   $ glog -R renames.repo
   @  4 "8: change foo" files: foo2
--- a/tests/test-convert-git.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-convert-git.t	Sat Jun 18 17:03:01 2011 -0500
@@ -57,9 +57,11 @@
   2 t4.1
   1 t4.2
   0 Merge branch other
+  updating bookmarks
   $ hg up -q -R git-repo-hg
   $ hg -R git-repo-hg tip -v
   changeset:   5:c78094926be2
+  bookmark:    master
   tag:         tip
   parent:      3:f5f5cb45432b
   parent:      4:4e174f80c67c
@@ -217,6 +219,7 @@
   sorting...
   converting...
   0 addbinary
+  updating bookmarks
   $ cd git-repo3-hg
   $ hg up -C
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
@@ -248,8 +251,10 @@
   converting...
   1 addfoo
   0 addfoo2
+  updating bookmarks
   $ hg -R git-repo4-hg log -v
   changeset:   1:d63e967f93da
+  bookmark:    master
   tag:         tip
   user:        nottest <test@example.org>
   date:        Mon Jan 01 00:00:21 2007 +0000
--- a/tests/test-convert-hg-source.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-convert-hg-source.t	Sat Jun 18 17:03:01 2011 -0500
@@ -17,6 +17,7 @@
   $ hg copy foo baz
   $ hg ci -m 'make bar and baz copies of foo' -d '2 0'
   created new head
+  $ hg bookmark premerge1
   $ hg merge
   merging baz and foo to baz
   1 files updated, 1 files merged, 0 files removed, 0 files unresolved
@@ -24,6 +25,7 @@
   $ hg ci -m 'merge local copy' -d '3 0'
   $ hg up -C 1
   1 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ hg bookmark premerge2
   $ hg merge 2
   merging foo and baz to baz
   1 files updated, 1 files merged, 0 files removed, 0 files unresolved
@@ -44,12 +46,16 @@
   2 merge local copy
   1 merge remote copy
   0 mark baz executable
+  updating bookmarks
   $ cd new
   $ hg out ../orig
   comparing with ../orig
   searching for changes
   no changes found
   [1]
+  $ hg bookmarks
+     premerge1                 3:973ef48a98a4
+     premerge2                 5:13d9b87cf8f8
   $ cd ..
 
 check shamap LF and CRLF handling
@@ -76,6 +82,7 @@
   converting...
   1 change foo again again
   0 change foo again
+  updating bookmarks
 
 init broken repository
 
--- a/tests/test-convert-hg-startrev.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-convert-hg-startrev.t	Sat Jun 18 17:03:01 2011 -0500
@@ -1,5 +1,5 @@
 
-  $ cat > $HGRCPATH <<EOF
+  $ cat >> $HGRCPATH <<EOF
   > [extensions]
   > graphlog =
   > convert =
--- a/tests/test-convert-mtn.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-convert-mtn.t	Sat Jun 18 17:03:01 2011 -0500
@@ -8,7 +8,6 @@
   $ echo "[extensions]" >> $HGRCPATH
   $ echo "convert=" >> $HGRCPATH
   $ echo 'graphlog =' >> $HGRCPATH
-  $ HOME=`pwd`/do_not_use_HOME_mtn; export HOME
 
 Windows version of monotone home
 
@@ -40,12 +39,12 @@
   $ python -c 'file("bin", "wb").write("a\\x00b")'
   $ echo c > c
   $ mtn add a dir/b dir/d c bin
-  mtn: adding a to workspace manifest
-  mtn: adding bin to workspace manifest
-  mtn: adding c to workspace manifest
-  mtn: adding dir to workspace manifest
-  mtn: adding dir/b to workspace manifest
-  mtn: adding dir/d to workspace manifest
+  mtn: adding 'a' to workspace manifest
+  mtn: adding 'bin' to workspace manifest
+  mtn: adding 'c' to workspace manifest
+  mtn: adding 'dir' to workspace manifest
+  mtn: adding 'dir/b' to workspace manifest
+  mtn: adding 'dir/d' to workspace manifest
   $ mtn ci -m initialize
   mtn: beginning commit on branch 'com.selenic.test'
   mtn: committed revision 0f6e5e4f2e7d2a8ef312408f57618abf026afd90
@@ -53,12 +52,12 @@
 update monotone working directory
 
   $ mtn mv a dir/a
-  mtn: skipping dir, already accounted for in workspace
-  mtn: renaming a to dir/a in workspace manifest
+  mtn: skipping 'dir', already accounted for in workspace
+  mtn: renaming 'a' to 'dir/a' in workspace manifest
   $ echo a >> dir/a
   $ echo b >> dir/b
   $ mtn drop c
-  mtn: dropping c from workspace manifest
+  mtn: dropping 'c' from workspace manifest
   $ python -c 'file("bin", "wb").write("b\\x00c")'
   $ mtn ci -m update1
   mtn: beginning commit on branch 'com.selenic.test'
@@ -78,11 +77,11 @@
   $ cd workingdir
   $ echo e > e
   $ mtn add e
-  mtn: adding e to workspace manifest
+  mtn: adding 'e' to workspace manifest
   $ mtn drop dir/b
-  mtn: dropping dir/b from workspace manifest
+  mtn: dropping 'dir/b' from workspace manifest
   $ mtn mv bin bin2
-  mtn: renaming bin to bin2 in workspace manifest
+  mtn: renaming 'bin' to 'bin2' in workspace manifest
   $ mtn ci -m 'update2 "with" quotes'
   mtn: beginning commit on branch 'com.selenic.test'
   mtn: committed revision ebe58335d85d8cb176b6d0a12be04f5314b998da
@@ -94,17 +93,17 @@
   $ echo file1 > dir1/subdir1/file1
   $ echo file2 > dir1/subdir2_other/file1
   $ mtn add dir1/subdir1/file1 dir1/subdir2_other/file1
-  mtn: adding dir1 to workspace manifest
-  mtn: adding dir1/subdir1 to workspace manifest
-  mtn: adding dir1/subdir1/file1 to workspace manifest
-  mtn: adding dir1/subdir2_other to workspace manifest
-  mtn: adding dir1/subdir2_other/file1 to workspace manifest
+  mtn: adding 'dir1' to workspace manifest
+  mtn: adding 'dir1/subdir1' to workspace manifest
+  mtn: adding 'dir1/subdir1/file1' to workspace manifest
+  mtn: adding 'dir1/subdir2_other' to workspace manifest
+  mtn: adding 'dir1/subdir2_other/file1' to workspace manifest
   $ mtn ci -m createdir1
   mtn: beginning commit on branch 'com.selenic.test'
   mtn: committed revision a8d62bc04fee4d2936d28e98bbcc81686dd74306
   $ mtn rename dir1/subdir1 dir1/subdir2
-  mtn: skipping dir1, already accounted for in workspace
-  mtn: renaming dir1/subdir1 to dir1/subdir2 in workspace manifest
+  mtn: skipping 'dir1', already accounted for in workspace
+  mtn: renaming 'dir1/subdir1' to 'dir1/subdir2' in workspace manifest
   $ mtn ci -m movedir1
   mtn: beginning commit on branch 'com.selenic.test'
   mtn: committed revision 2c3d241bbbfe538b1b51d910f5676407e3f4d3a6
@@ -112,12 +111,12 @@
 test subdirectory move
 
   $ mtn mv dir dir2
-  mtn: renaming dir to dir2 in workspace manifest
+  mtn: renaming 'dir' to 'dir2' in workspace manifest
   $ echo newfile > dir2/newfile
   $ mtn drop dir2/d
-  mtn: dropping dir2/d from workspace manifest
+  mtn: dropping 'dir2/d' from workspace manifest
   $ mtn add dir2/newfile
-  mtn: adding dir2/newfile to workspace manifest
+  mtn: adding 'dir2/newfile' to workspace manifest
   $ mtn ci -m movedir
   mtn: beginning commit on branch 'com.selenic.test'
   mtn: committed revision fdb5a02dae8bfce3a79b3393680af471016e1b4c
@@ -133,10 +132,10 @@
   mtn: beginning commit on branch 'com.selenic.test'
   mtn: committed revision 8bbf76d717001d24964e4604739fdcd0f539fc88
   $ mtn drop -R dir2/dir
-  mtn: dropping dir2/dir/subdir/f from workspace manifest
-  mtn: dropping dir2/dir/subdir from workspace manifest
-  mtn: dropping dir2/dir/emptydir from workspace manifest
-  mtn: dropping dir2/dir from workspace manifest
+  mtn: dropping 'dir2/dir/subdir/f' from workspace manifest
+  mtn: dropping 'dir2/dir/subdir' from workspace manifest
+  mtn: dropping 'dir2/dir/emptydir' from workspace manifest
+  mtn: dropping 'dir2/dir' from workspace manifest
   $ mtn ci -m dropdirectory
   mtn: beginning commit on branch 'com.selenic.test'
   mtn: committed revision 2323d4bc324e6c82628dc04d47a9fd32ad24e322
@@ -146,18 +145,18 @@
   $ mkdir -p dir3/d1
   $ echo a > dir3/a
   $ mtn add dir3/a dir3/d1
-  mtn: adding dir3 to workspace manifest
-  mtn: adding dir3/a to workspace manifest
-  mtn: adding dir3/d1 to workspace manifest
+  mtn: adding 'dir3' to workspace manifest
+  mtn: adding 'dir3/a' to workspace manifest
+  mtn: adding 'dir3/d1' to workspace manifest
   $ mtn ci -m dirfilemove
   mtn: beginning commit on branch 'com.selenic.test'
   mtn: committed revision 47b192f720faa622f48c68d1eb075b26d405aa8b
   $ mtn mv dir3/a dir3/d1/a
-  mtn: skipping dir3/d1, already accounted for in workspace
-  mtn: renaming dir3/a to dir3/d1/a in workspace manifest
+  mtn: skipping 'dir3/d1', already accounted for in workspace
+  mtn: renaming 'dir3/a' to 'dir3/d1/a' in workspace manifest
   $ mtn mv dir3/d1 dir3/d2
-  mtn: skipping dir3, already accounted for in workspace
-  mtn: renaming dir3/d1 to dir3/d2 in workspace manifest
+  mtn: skipping 'dir3', already accounted for in workspace
+  mtn: renaming 'dir3/d1' to 'dir3/d2' in workspace manifest
   $ mtn ci -m dirfilemove2
   mtn: beginning commit on branch 'com.selenic.test'
   mtn: committed revision 8b543a400d3ee7f6d4bb1835b9b9e3747c8cb632
@@ -168,17 +167,17 @@
   $ mkdir dir5
   $ echo a > dir4/a
   $ mtn add dir4/a dir5
-  mtn: adding dir4 to workspace manifest
-  mtn: adding dir4/a to workspace manifest
-  mtn: adding dir5 to workspace manifest
+  mtn: adding 'dir4' to workspace manifest
+  mtn: adding 'dir4/a' to workspace manifest
+  mtn: adding 'dir5' to workspace manifest
   $ mtn ci -m dirdirmove
   mtn: beginning commit on branch 'com.selenic.test'
   mtn: committed revision 466e0b2afc7a55aa2b4ab2f57cb240bb6cd66fc7
   $ mtn mv dir5 dir6
-  mtn: renaming dir5 to dir6 in workspace manifest
+  mtn: renaming 'dir5' to 'dir6' in workspace manifest
   $ mtn mv dir4 dir6/dir4
-  mtn: skipping dir6, already accounted for in workspace
-  mtn: renaming dir4 to dir6/dir4 in workspace manifest
+  mtn: skipping 'dir6', already accounted for in workspace
+  mtn: renaming 'dir4' to 'dir6/dir4' in workspace manifest
   $ mtn ci -m dirdirmove2
   mtn: beginning commit on branch 'com.selenic.test'
   mtn: committed revision 3d1f77ebad0c23a5d14911be3b670f990991b749
@@ -190,24 +189,39 @@
   $ echo b > dir7/dir9/b
   $ echo c > dir7/c
   $ mtn add -R dir7
-  mtn: adding dir7 to workspace manifest
-  mtn: adding dir7/c to workspace manifest
-  mtn: adding dir7/dir9 to workspace manifest
-  mtn: adding dir7/dir9/b to workspace manifest
-  mtn: adding dir7/dir9/dir8 to workspace manifest
-  mtn: adding dir7/dir9/dir8/a to workspace manifest
+  mtn: adding 'dir7' to workspace manifest
+  mtn: adding 'dir7/c' to workspace manifest
+  mtn: adding 'dir7/dir9' to workspace manifest
+  mtn: adding 'dir7/dir9/b' to workspace manifest
+  mtn: adding 'dir7/dir9/dir8' to workspace manifest
+  mtn: adding 'dir7/dir9/dir8/a' to workspace manifest
   $ mtn ci -m divergentdirmove
   mtn: beginning commit on branch 'com.selenic.test'
   mtn: committed revision 08a08511f18b428d840199b062de90d0396bc2ed
   $ mtn mv dir7 dir7-2
-  mtn: renaming dir7 to dir7-2 in workspace manifest
+  mtn: renaming 'dir7' to 'dir7-2' in workspace manifest
   $ mtn mv dir7-2/dir9 dir9-2
-  mtn: renaming dir7-2/dir9 to dir9-2 in workspace manifest
+  mtn: renaming 'dir7-2/dir9' to 'dir9-2' in workspace manifest
   $ mtn mv dir9-2/dir8 dir8-2
-  mtn: renaming dir9-2/dir8 to dir8-2 in workspace manifest
+  mtn: renaming 'dir9-2/dir8' to 'dir8-2' in workspace manifest
   $ mtn ci -m divergentdirmove2
   mtn: beginning commit on branch 'com.selenic.test'
   mtn: committed revision 4a736634505795f17786fffdf2c9cbf5b11df6f6
+
+test large file support (> 32kB)
+
+  $ python -c 'for x in range(10000): print x' > large-file
+  $ $TESTDIR/md5sum.py large-file
+  5d6de8a95c3b6bf9e0ffb808ba5299c1  large-file
+  $ mtn add large-file
+  mtn: adding 'large-file' to workspace manifest
+  $ mtn ci -m largefile
+  mtn: beginning commit on branch 'com.selenic.test'
+  mtn: committed revision f0a20fecd10dc4392d18fe69a03f1f4919d3387b
+
+test suspending (closing a branch)
+
+  $ mtn suspend f0a20fecd10dc4392d18fe69a03f1f4919d3387b 2> /dev/null
   $ cd ..
 
 convert incrementally
@@ -217,27 +231,30 @@
   scanning source...
   sorting...
   converting...
-  11 update2 "with" quotes
-  10 createdir1
-  9 movedir1
-  8 movedir
-  7 emptydir
-  6 dropdirectory
-  5 dirfilemove
-  4 dirfilemove2
-  3 dirdirmove
-  2 dirdirmove2
-  1 divergentdirmove
-  0 divergentdirmove2
+  12 update2 "with" quotes
+  11 createdir1
+  10 movedir1
+  9 movedir
+  8 emptydir
+  7 dropdirectory
+  6 dirfilemove
+  5 dirfilemove2
+  4 dirdirmove
+  3 dirdirmove2
+  2 divergentdirmove
+  1 divergentdirmove2
+  0 largefile
   $ glog()
   > {
   >     hg glog --template '{rev} "{desc|firstline}" files: {files}\n' "$@"
   > }
   $ cd repo.mtn-hg
   $ hg up -C
-  11 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  12 files updated, 0 files merged, 0 files removed, 0 files unresolved
   $ glog
-  @  13 "divergentdirmove2" files: dir7-2/c dir7/c dir7/dir9/b dir7/dir9/dir8/a dir8-2/a dir9-2/b
+  @  14 "largefile" files: large-file
+  |
+  o  13 "divergentdirmove2" files: dir7-2/c dir7/c dir7/dir9/b dir7/dir9/dir8/a dir8-2/a dir9-2/b
   |
   o  12 "divergentdirmove" files: dir7/c dir7/dir9/b dir7/dir9/dir8/a
   |
@@ -280,6 +297,7 @@
   dir8-2/a
   dir9-2/b
   e
+  large-file
 
 contents
 
@@ -356,3 +374,15 @@
   dir8-2/a
   dir9-2/b
   e
+
+test large file support (> 32kB)
+
+  $ $TESTDIR/md5sum.py large-file
+  5d6de8a95c3b6bf9e0ffb808ba5299c1  large-file
+
+check branch closing
+
+  $ hg branches -a
+  $ hg branches -c
+  com.selenic.test              14:* (closed) (glob)
+
--- a/tests/test-convert-svn-branches.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-convert-svn-branches.t	Sat Jun 18 17:03:01 2011 -0500
@@ -1,7 +1,7 @@
 
   $ "$TESTDIR/hghave" svn svn-bindings || exit 80
 
-  $ cat > $HGRCPATH <<EOF
+  $ cat >> $HGRCPATH <<EOF
   > [extensions]
   > convert = 
   > graphlog =
@@ -32,6 +32,21 @@
   1 move back to old
   0 last change to a
 
+Test template keywords
+
+  $ hg -R A-hg log --template '{rev} {svnuuid}{svnpath}@{svnrev}\n'
+  10 644ede6c-2b81-4367-9dc8-d786514f2cde/trunk@10
+  9 644ede6c-2b81-4367-9dc8-d786514f2cde/branches/old@9
+  8 644ede6c-2b81-4367-9dc8-d786514f2cde/branches/old2@8
+  7 644ede6c-2b81-4367-9dc8-d786514f2cde/branches/old@7
+  6 644ede6c-2b81-4367-9dc8-d786514f2cde/trunk@6
+  5 644ede6c-2b81-4367-9dc8-d786514f2cde/branches/old@6
+  4 644ede6c-2b81-4367-9dc8-d786514f2cde/branches/old@5
+  3 644ede6c-2b81-4367-9dc8-d786514f2cde/trunk@4
+  2 644ede6c-2b81-4367-9dc8-d786514f2cde/branches/old@3
+  1 644ede6c-2b81-4367-9dc8-d786514f2cde/trunk@2
+  0 644ede6c-2b81-4367-9dc8-d786514f2cde/trunk@1
+
 Convert again
 
   $ hg convert --branchmap=branchmap --datesort svn-repo A-hg
@@ -68,10 +83,10 @@
   
 
   $ hg branches
-  newbranch                     11:08fca3ff8634
-  default                       10:098988aa63ba
-  old                            9:b308f345079b
-  old2                           8:49f2336c7b8b (inactive)
+  newbranch                     11:a6d7cc050ad1
+  default                       10:6e2b33404495
+  old                            9:93c4b0f99529
+  old2                           8:b52884d7bead (inactive)
   $ hg tags -q
   tip
   $ cd ..
--- a/tests/test-convert-svn-encoding.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-convert-svn-encoding.t	Sat Jun 18 17:03:01 2011 -0500
@@ -1,7 +1,7 @@
 
   $ "$TESTDIR/hghave" svn svn-bindings || exit 80
 
-  $ cat > $HGRCPATH <<EOF
+  $ cat >> $HGRCPATH <<EOF
   > [extensions]
   > convert = 
   > graphlog =
@@ -129,7 +129,7 @@
 Check tags are in UTF-8
 
   $ cat .hgtags
-  221c3fdaf24df5f14c0a64c597581e2eacfb47bb branch\xc3\xa9e (esc)
-  7a40952c2db29cf00d9e31df3749e98d8a4bdcbf branch\xc3\xa9 (esc)
+  e94e4422020e715add80525e8f0f46c9968689f1 branch\xc3\xa9e (esc)
+  f7e66f98380ed1e53a797c5c7a7a2616a7ab377d branch\xc3\xa9 (esc)
 
   $ cd ..
--- a/tests/test-convert-svn-move.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-convert-svn-move.t	Sat Jun 18 17:03:01 2011 -0500
@@ -5,7 +5,7 @@
   > {
   >     tr '\\' /
   > }
-  $ cat > $HGRCPATH <<EOF
+  $ cat >> $HGRCPATH <<EOF
   > [extensions]
   > convert = 
   > graphlog =
--- a/tests/test-convert-svn-sink.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-convert-svn-sink.t	Sat Jun 18 17:03:01 2011 -0500
@@ -1,5 +1,5 @@
 
-  $ "$TESTDIR/hghave" svn svn-bindings no-outer-repo || exit 80
+  $ "$TESTDIR/hghave" svn no-outer-repo || exit 80
 
   $ fixpath()
   > {
@@ -22,7 +22,7 @@
   >     )
   > }
 
-  $ cat > $HGRCPATH <<EOF
+  $ cat >> $HGRCPATH <<EOF
   > [extensions]
   > convert = 
   > graphlog =
--- a/tests/test-convert-svn-source.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-convert-svn-source.t	Sat Jun 18 17:03:01 2011 -0500
@@ -5,7 +5,7 @@
   > {
   >     tr '\\' /
   > }
-  $ cat > $HGRCPATH <<EOF
+  $ cat >> $HGRCPATH <<EOF
   > [extensions]
   > convert = 
   > graphlog =
@@ -107,6 +107,11 @@
   Committed revision 8.
   $ cd ..
 
+  $ hg convert -s svn "$svnurl/non-existent-path" dest
+  initializing destination dest repository
+  abort: no revision found in module /proj B/non-existent-path
+  [255]
+
 ########################################
 
 Test incremental conversion
--- a/tests/test-convert-svn-startrev.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-convert-svn-startrev.t	Sat Jun 18 17:03:01 2011 -0500
@@ -1,7 +1,7 @@
 
   $ "$TESTDIR/hghave" svn svn-bindings || exit 80
 
-  $ cat > $HGRCPATH <<EOF
+  $ cat >> $HGRCPATH <<EOF
   > [extensions]
   > convert = 
   > graphlog =
--- a/tests/test-convert-svn-tags.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-convert-svn-tags.t	Sat Jun 18 17:03:01 2011 -0500
@@ -1,7 +1,7 @@
 
   $ "$TESTDIR/hghave" svn svn-bindings || exit 80
 
-  $ cat > $HGRCPATH <<EOF
+  $ cat >> $HGRCPATH <<EOF
   > [extensions]
   > convert = 
   > graphlog =
--- a/tests/test-convert-tagsbranch-topology.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-convert-tagsbranch-topology.t	Sat Jun 18 17:03:01 2011 -0500
@@ -49,6 +49,7 @@
   converting...
   0 rev1
   updating tags
+  updating bookmarks
 
 Simulate upstream  updates after first conversion
 
@@ -67,6 +68,7 @@
   converting...
   0 rev2
   updating tags
+  updating bookmarks
 
 Print the log
 
--- a/tests/test-convert-tla.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-convert-tla.t	Sat Jun 18 17:03:01 2011 -0500
@@ -1,9 +1,5 @@
 
   $ "$TESTDIR/hghave" tla || exit 80
-  $ mkdir do_not_use_HOME_tla
-  $ cd do_not_use_HOME_tla
-  $ HOME=`pwd`; export HOME
-  $ cd ..
   $ tla my-id "mercurial <mercurial@selenic.com>"
   $ echo "[extensions]" >> $HGRCPATH
   $ echo "convert=" >> $HGRCPATH
--- a/tests/test-copy-move-merge.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-copy-move-merge.t	Sat Jun 18 17:03:01 2011 -0500
@@ -1,6 +1,5 @@
-  $ mkdir t
+  $ hg init t
   $ cd t
-  $ hg init
 
   $ echo 1 > a
   $ hg ci -qAm "first"
--- a/tests/test-copy.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-copy.t	Sat Jun 18 17:03:01 2011 -0500
@@ -4,6 +4,9 @@
   $ hg commit -m "1"
   $ hg status
   $ hg copy a b
+  $ hg --config ui.portablefilenames=abort copy a con.xml
+  abort: filename contains 'con', which is reserved on Windows: 'con.xml'
+  [255]
   $ hg status
   A b
   $ hg sum
@@ -49,7 +52,7 @@
 
 this should show a revision linked to changeset 0
 
-  $ hg debugindex .hg/store/data/a.i
+  $ hg debugindex a
      rev    offset  length   base linkrev nodeid       p1           p2
        0         0       3      0       0 b789fdd96dc2 000000000000 000000000000
 
@@ -65,13 +68,13 @@
 
 this should show a revision linked to changeset 1
 
-  $ hg debugindex .hg/store/data/b.i
+  $ hg debugindex b
      rev    offset  length   base linkrev nodeid       p1           p2
        0         0      65      0       1 37d9b5d994ea 000000000000 000000000000
 
 this should show the rename information in the metadata
 
-  $ hg debugdata .hg/store/data/b.d 0 | head -3 | tail -2
+  $ hg debugdata b 0 | head -3 | tail -2
   copy: a
   copyrev: b789fdd96dc2f3bd229c1dd8eedf0fc60e2b68e3
 
--- a/tests/test-copy2.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-copy2.t	Sat Jun 18 17:03:01 2011 -0500
@@ -27,6 +27,13 @@
   A foo
   $ hg commit -m1
 
+moving a missing file
+  $ rm foo
+  $ hg mv foo foo3
+  foo: deleted in working copy
+  foo3 does not exist!
+  $ hg up -qC .
+
 copy --after to a nonexistant target filename
   $ hg cp -A foo dummy
   foo: not recording copy - dummy does not exist
@@ -46,7 +53,7 @@
   $ hg st -C
 
 should match
-  $ hg debugindex .hg/store/data/foo.i
+  $ hg debugindex foo
      rev    offset  length   base linkrev nodeid       p1           p2
        0         0       5      0       0 2ed2a3912a0b 000000000000 000000000000
   $ hg debugrename bar
@@ -68,13 +75,13 @@
   $ hg commit -m3
 
 should show no parents for tip
-  $ hg debugindex .hg/store/data/bar.i
+  $ hg debugindex bar
      rev    offset  length   base linkrev nodeid       p1           p2
        0         0      69      0       1 7711d36246cc 000000000000 000000000000
        1        69       6      1       2 bdf70a2b8d03 7711d36246cc 000000000000
        2        75      81      1       3 b2558327ea8d 000000000000 000000000000
 should match
-  $ hg debugindex .hg/store/data/foo.i
+  $ hg debugindex foo
      rev    offset  length   base linkrev nodeid       p1           p2
        0         0       5      0       0 2ed2a3912a0b 000000000000 000000000000
        1         5       7      1       2 dd12c926cf16 2ed2a3912a0b 000000000000
--- a/tests/test-debugbuilddag.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-debugbuilddag.t	Sat Jun 18 17:03:01 2011 -0500
@@ -1,12 +1,55 @@
   $ echo "[extensions]" >> $HGRCPATH
   $ echo "graphlog=" >> $HGRCPATH
 
-overwritten and appended files
+plain
 
-  $ rm -rf repo
-  $ hg init repo
-  $ cd repo
-  $ hg debugbuilddag '+2:f +3:p2 @temp <f+4 @default /p2 +2' -q -oa
+  $ hg init
+  $ hg debugbuilddag '+2:f +3:p2 @temp <f+4 @default /p2 +2' \
+  > --config extensions.progress= --config progress.assume-tty=1 \
+  > --config progress.delay=0 --config progress.refresh=0 \
+  > --config progress.width=60 2>&1 | \
+  > python $TESTDIR/filtercr.py
+  
+  building [                                          ]  0/12
+  building [                                          ]  0/12
+  building [                                          ]  0/12
+  building [                                          ]  0/12
+  building [==>                                       ]  1/12
+  building [==>                                       ]  1/12
+  building [==>                                       ]  1/12
+  building [==>                                       ]  1/12
+  building [======>                                   ]  2/12
+  building [======>                                   ]  2/12
+  building [=========>                                ]  3/12
+  building [=========>                                ]  3/12
+  building [=============>                            ]  4/12
+  building [=============>                            ]  4/12
+  building [=============>                            ]  4/12
+  building [=============>                            ]  4/12
+  building [=============>                            ]  4/12
+  building [=============>                            ]  4/12
+  building [================>                         ]  5/12
+  building [================>                         ]  5/12
+  building [====================>                     ]  6/12
+  building [====================>                     ]  6/12
+  building [=======================>                  ]  7/12
+  building [=======================>                  ]  7/12
+  building [===========================>              ]  8/12
+  building [===========================>              ]  8/12
+  building [===========================>              ]  8/12
+  building [===========================>              ]  8/12
+  building [==============================>           ]  9/12
+  building [==============================>           ]  9/12
+  building [==================================>       ] 10/12
+  building [==================================>       ] 10/12
+  building [=====================================>    ] 11/12
+  building [=====================================>    ] 11/12
+                                                              \r (esc)
+
+tags
+  $ cat .hg/localtags
+  66f7d451a68b85ed82ff5fcc254daf50c74144bd f
+  bebd167eb94d257ace0e814aeb98e6972ed2970d p2
 dag
   $ hg debugdag -t -b
   +2:f
@@ -15,10 +58,55 @@
   @default*/p2+2:tip
 tip
   $ hg id
-  f96e381c614c tip
+  000000000000
 glog
   $ hg glog --template '{rev}: {desc} [{branches}] @ {date}\n'
-  @  11: r11 [] @ 11.00
+  o  11: r11 [] @ 11.00
+  |
+  o  10: r10 [] @ 10.00
+  |
+  o    9: r9 [] @ 9.00
+  |\
+  | o  8: r8 [temp] @ 8.00
+  | |
+  | o  7: r7 [temp] @ 7.00
+  | |
+  | o  6: r6 [temp] @ 6.00
+  | |
+  | o  5: r5 [temp] @ 5.00
+  | |
+  o |  4: r4 [] @ 4.00
+  | |
+  o |  3: r3 [] @ 3.00
+  | |
+  o |  2: r2 [] @ 2.00
+  |/
+  o  1: r1 [] @ 1.00
+  |
+  o  0: r0 [] @ 0.00
+  
+
+overwritten files
+
+  $ rm -r .hg
+  $ hg init
+  $ hg debugbuilddag '+2:f +3:p2 @temp <f+4 @default /p2 +2' -q -o
+tags
+  $ cat .hg/localtags
+  2a8ed67d317e370eac733dccc501b12d7b9c441a f
+  4226a30965b7af58f94d0cda7e6c2c9c63e6bf90 p2
+dag
+  $ hg debugdag -t -b
+  +2:f
+  +3:p2
+  @temp*f+3
+  @default*/p2+2:tip
+tip
+  $ hg id
+  000000000000
+glog
+  $ hg glog --template '{rev}: {desc} [{branches}] @ {date}\n'
+  o  11: r11 [] @ 11.00
   |
   o  10: r10 [] @ 10.00
   |
@@ -44,33 +132,7 @@
   
 glog of
   $ hg glog --template '{rev}: {desc} [{branches}]\n' of
-  @  11: r11 []
-  |
-  o  10: r10 []
-  |
-  o    9: r9 []
-  |\
-  | o  8: r8 [temp]
-  | |
-  | o  7: r7 [temp]
-  | |
-  | o  6: r6 [temp]
-  | |
-  | o  5: r5 [temp]
-  | |
-  o |  4: r4 []
-  | |
-  o |  3: r3 []
-  | |
-  o |  2: r2 []
-  |/
-  o  1: r1 []
-  |
-  o  0: r0 []
-  
-glog af
-  $ hg glog --template '{rev}: {desc} [{branches}]\n' af
-  @  11: r11 []
+  o  11: r11 []
   |
   o  10: r10 []
   |
@@ -96,30 +158,18 @@
   
 tags
   $ hg tags -v
-  tip                               11:f96e381c614c
-  p2                                 4:d9d6db981b55 local
-  f                                  1:73253def624e local
+  tip                               11:58a51e5eb988
+  p2                                 4:4226a30965b7 local
+  f                                  1:2a8ed67d317e local
 cat of
-  $ hg cat of
+  $ hg cat of --rev tip
   r11
-cat af
-  $ hg cat af
-  r0
-  r1
-  r5
-  r6
-  r7
-  r8
-  r9
-  r10
-  r11
-  $ cd ..
+
 
 new and mergeable files
 
-  $ rm -rf repo
-  $ hg init repo
-  $ cd repo
+  $ rm -r .hg
+  $ hg init
   $ hg debugbuilddag '+2:f +3:p2 @temp <f+4 @default /p2 +2' -q -mn
 dag
   $ hg debugdag -t -b
@@ -129,10 +179,10 @@
   @default*/p2+2:tip
 tip
   $ hg id
-  9c5ce9b70771 tip
+  000000000000
 glog
   $ hg glog --template '{rev}: {desc} [{branches}] @ {date}\n'
-  @  11: r11 [] @ 11.00
+  o  11: r11 [] @ 11.00
   |
   o  10: r10 [] @ 10.00
   |
@@ -158,7 +208,7 @@
   
 glog mf
   $ hg glog --template '{rev}: {desc} [{branches}]\n' mf
-  @  11: r11 []
+  o  11: r11 []
   |
   o  10: r10 []
   |
@@ -253,7 +303,7 @@
   22
   23
 man
-  $ hg manifest
+  $ hg manifest --rev tip
   mf
   nf0
   nf1
@@ -268,7 +318,7 @@
   nf8
   nf9
 cat mf
-  $ hg cat mf
+  $ hg cat mf --rev tip
   0 r0
   1
   2 r1
@@ -293,29 +343,6 @@
   21
   22 r11
   23
-  $ cd ..
 
-command
 
-  $ rm -rf repo
-  $ hg init repo
-  $ cd repo
-  $ hg debugbuilddag '+2 !"touch X" +2' -q -o
-dag
-  $ hg debugdag -t -b
-  +4:tip
-glog
-  $ hg glog --template '{rev}: {desc} [{branches}]\n'
-  @  3: r3 []
-  |
-  o  2: r2 []
-  |
-  o  1: r1 []
-  |
-  o  0: r0 []
-  
-glog X
-  $ hg glog --template '{rev}: {desc} [{branches}]\n' X
-  o  2: r2 []
-  
-  $ cd ..
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-debugbundle.t	Sat Jun 18 17:03:01 2011 -0500
@@ -0,0 +1,36 @@
+
+Create a test repository:
+
+  $ hg init repo
+  $ cd repo
+  $ touch a ; hg add a ; hg ci -ma
+  $ touch b ; hg add b ; hg ci -mb
+  $ touch c ; hg add c ; hg ci -mc
+  $ hg bundle --base 0 --rev tip bundle.hg
+  2 changesets found
+
+Terse output:
+
+  $ hg debugbundle bundle.hg
+  0e067c57feba1a5694ca4844f05588bb1bf82342
+  991a3460af53952d10ec8a295d3d2cc2e5fa9690
+
+Verbose output:
+
+  $ hg debugbundle --all bundle.hg
+  format: id, p1, p2, cset, delta base, len(delta)
+  
+  changelog
+  0e067c57feba1a5694ca4844f05588bb1bf82342 3903775176ed42b1458a6281db4a0ccf4d9f287a 0000000000000000000000000000000000000000 0e067c57feba1a5694ca4844f05588bb1bf82342 3903775176ed42b1458a6281db4a0ccf4d9f287a 80
+  991a3460af53952d10ec8a295d3d2cc2e5fa9690 0e067c57feba1a5694ca4844f05588bb1bf82342 0000000000000000000000000000000000000000 991a3460af53952d10ec8a295d3d2cc2e5fa9690 0e067c57feba1a5694ca4844f05588bb1bf82342 80
+  
+  manifest
+  686dbf0aeca417636fa26a9121c681eabbb15a20 8515d4bfda768e04af4c13a69a72e28c7effbea7 0000000000000000000000000000000000000000 0e067c57feba1a5694ca4844f05588bb1bf82342 8515d4bfda768e04af4c13a69a72e28c7effbea7 55
+  ae25a31b30b3490a981e7b96a3238cc69583fda1 686dbf0aeca417636fa26a9121c681eabbb15a20 0000000000000000000000000000000000000000 991a3460af53952d10ec8a295d3d2cc2e5fa9690 686dbf0aeca417636fa26a9121c681eabbb15a20 55
+  
+  b
+  b80de5d138758541c5f05265ad144ab9fa86d1db 0000000000000000000000000000000000000000 0000000000000000000000000000000000000000 0e067c57feba1a5694ca4844f05588bb1bf82342 0000000000000000000000000000000000000000 12
+  
+  c
+  b80de5d138758541c5f05265ad144ab9fa86d1db 0000000000000000000000000000000000000000 0000000000000000000000000000000000000000 991a3460af53952d10ec8a295d3d2cc2e5fa9690 0000000000000000000000000000000000000000 12
+
--- a/tests/test-debugcomplete.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-debugcomplete.t	Sat Jun 18 17:03:01 2011 -0500
@@ -67,6 +67,7 @@
   $ hg debugcomplete debug
   debugancestor
   debugbuilddag
+  debugbundle
   debugcheckstate
   debugcommands
   debugcomplete
@@ -74,19 +75,25 @@
   debugdag
   debugdata
   debugdate
+  debugdiscovery
+  debugfileset
   debugfsinfo
+  debuggetbundle
   debugignore
   debugindex
   debugindexdot
   debuginstall
+  debugknown
   debugpushkey
   debugrebuildstate
   debugrename
+  debugrevlog
   debugrevspec
   debugsetparents
   debugstate
   debugsub
   debugwalk
+  debugwireargs
 
 Do not show the alias of a debug command if there are other candidates
 (this should hide rawcommit)
@@ -130,6 +137,7 @@
   --accesslog
   --address
   --certificate
+  --cmdserver
   --config
   --cwd
   --daemon
@@ -187,54 +195,61 @@
   export: output, switch-parent, rev, text, git, nodates
   forget: include, exclude
   init: ssh, remotecmd, insecure
-  log: follow, follow-first, date, copies, keyword, rev, removed, only-merges, user, only-branch, branch, prune, patch, git, limit, no-merges, stat, style, template, include, exclude
+  log: follow, follow-first, date, copies, keyword, rev, removed, only-merges, user, only-branch, branch, prune, hidden, patch, git, limit, no-merges, stat, style, template, include, exclude
   merge: force, tool, rev, preview
   pull: update, force, rev, bookmark, branch, ssh, remotecmd, insecure
   push: force, rev, bookmark, branch, new-branch, ssh, remotecmd, insecure
   remove: after, force, include, exclude
-  serve: accesslog, daemon, daemon-pipefds, errorlog, port, address, prefix, name, web-conf, webdir-conf, pid-file, stdio, templates, style, ipv6, certificate
+  serve: accesslog, daemon, daemon-pipefds, errorlog, port, address, prefix, name, web-conf, webdir-conf, pid-file, stdio, cmdserver, templates, style, ipv6, certificate
   status: all, modified, added, removed, deleted, clean, unknown, ignored, no-status, copies, print0, rev, change, include, exclude, subrepos
   summary: remote
   update: clean, check, date, rev
   addremove: similarity, include, exclude, dry-run
   archive: no-decode, prefix, rev, type, subrepos, include, exclude
   backout: merge, parent, tool, rev, include, exclude, message, logfile, date, user
-  bisect: reset, good, bad, skip, command, noupdate
-  bookmarks: force, rev, delete, rename
+  bisect: reset, good, bad, skip, extend, command, noupdate
+  bookmarks: force, rev, delete, rename, inactive
   branch: force, clean
   branches: active, closed
   bundle: force, rev, branch, base, all, type, ssh, remotecmd, insecure
   cat: output, rev, decode, include, exclude
   copy: after, force, include, exclude, dry-run
   debugancestor: 
-  debugbuilddag: mergeable-file, appended-file, overwritten-file, new-file
+  debugbuilddag: mergeable-file, overwritten-file, new-file
+  debugbundle: all
   debugcheckstate: 
   debugcommands: 
   debugcomplete: options
   debugdag: tags, branches, dots, spaces
-  debugdata: 
+  debugdata: changelog, manifest
   debugdate: extended
+  debugdiscovery: old, nonheads, ssh, remotecmd, insecure
+  debugfileset: 
   debugfsinfo: 
+  debuggetbundle: head, common, type
   debugignore: 
-  debugindex: format
+  debugindex: changelog, manifest, format
   debugindexdot: 
   debuginstall: 
+  debugknown: 
   debugpushkey: 
   debugrebuildstate: rev
   debugrename: rev
+  debugrevlog: changelog, manifest, dump
   debugrevspec: 
   debugsetparents: 
-  debugstate: nodates
+  debugstate: nodates, datesort
   debugsub: rev
   debugwalk: include, exclude
-  grep: print0, all, follow, ignore-case, files-with-matches, line-number, rev, user, date, include, exclude
+  debugwireargs: three, four, five, ssh, remotecmd, insecure
+  grep: print0, all, text, follow, ignore-case, files-with-matches, line-number, rev, user, date, include, exclude
   heads: rev, topo, active, closed, style, template
-  help: 
+  help: extension, command
   identify: rev, num, id, branch, tags, bookmarks
-  import: strip, base, force, no-commit, exact, import-branch, message, logfile, date, user, similarity
+  import: strip, base, force, no-commit, bypass, exact, import-branch, message, logfile, date, user, similarity
   incoming: force, newest-first, bundle, rev, bookmarks, branch, patch, git, limit, no-merges, stat, style, template, ssh, remotecmd, insecure, subrepos
   locate: rev, print0, fullpath, include, exclude
-  manifest: rev
+  manifest: rev, all
   outgoing: force, rev, newest-first, bookmarks, branch, patch, git, limit, no-merges, stat, style, template, ssh, remotecmd, insecure, subrepos
   parents: rev, style, template
   paths: 
--- a/tests/test-diff-color.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-diff-color.t	Sat Jun 18 17:03:01 2011 -0500
@@ -1,5 +1,7 @@
 Setup
 
+  $ echo "[color]" >> $HGRCPATH
+  $ echo "mode = ansi" >> $HGRCPATH
   $ echo "[extensions]" >> $HGRCPATH
   $ echo "color=" >> $HGRCPATH
   $ hg init repo
@@ -81,7 +83,7 @@
   \x1b[0;36;1mold mode 100644\x1b[0m (esc)
   \x1b[0;36;1mnew mode 100755\x1b[0m (esc)
   1 hunks, 1 lines changed
-  examine changes to 'a'? [Ynsfdaq?] 
+  \x1b[0;33mexamine changes to 'a'? [Ynsfdaq?]\x1b[0m  (esc)
   \x1b[0;35m@@ -2,7 +2,7 @@\x1b[0m (esc)
    c
    a
@@ -91,7 +93,7 @@
    a
    a
    c
-  record this change to 'a'? [Ynsfdaq?] 
+  \x1b[0;33mrecord this change to 'a'? [Ynsfdaq?]\x1b[0m  (esc)
   $ echo
   
   $ echo "[extensions]" >> $HGRCPATH
@@ -110,7 +112,7 @@
   \x1b[0;36;1mold mode 100644\x1b[0m (esc)
   \x1b[0;36;1mnew mode 100755\x1b[0m (esc)
   1 hunks, 1 lines changed
-  examine changes to 'a'? [Ynsfdaq?] 
+  \x1b[0;33mexamine changes to 'a'? [Ynsfdaq?]\x1b[0m  (esc)
   \x1b[0;35m@@ -2,7 +2,7 @@\x1b[0m (esc)
    c
    a
@@ -120,6 +122,6 @@
    a
    a
    c
-  record this change to 'a'? [Ynsfdaq?] 
+  \x1b[0;33mrecord this change to 'a'? [Ynsfdaq?]\x1b[0m  (esc)
   $ echo
   
--- a/tests/test-diffstat.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-diffstat.t	Sat Jun 18 17:03:01 2011 -0500
@@ -2,18 +2,22 @@
   $ cd repo
   $ i=0; while [ "$i" -lt 213 ]; do echo a >> a; i=`expr $i + 1`; done
   $ hg add a
+  $ cp a b
+  $ hg add b
 
 Wide diffstat:
 
   $ hg diff --stat
    a |  213 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-   1 files changed, 213 insertions(+), 0 deletions(-)
+   b |  213 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+   2 files changed, 426 insertions(+), 0 deletions(-)
 
 diffstat width:
 
   $ COLUMNS=24 hg diff --config ui.interactive=true --stat
    a |  213 ++++++++++++++
-   1 files changed, 213 insertions(+), 0 deletions(-)
+   b |  213 ++++++++++++++
+   2 files changed, 426 insertions(+), 0 deletions(-)
 
   $ hg ci -m adda
 
@@ -31,19 +35,19 @@
 
   $ hg ci -m appenda
 
-  $ printf '\0' > b
-  $ hg add b
+  $ printf '\0' > c
+  $ hg add c
 
 Binary diffstat:
 
   $ hg diff --stat
-   b |    0 
+   c |    0 
    1 files changed, 0 insertions(+), 0 deletions(-)
 
 Binary git diffstat:
 
   $ hg diff --stat --git
-   b |  Bin 
+   c |  Bin 
    1 files changed, 0 insertions(+), 0 deletions(-)
 
   $ hg ci -m createb
--- a/tests/test-dispatch.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-dispatch.py	Sat Jun 18 17:03:01 2011 -0500
@@ -7,7 +7,8 @@
     Prints command and result value, but does not handle quoting.
     """
     print "running: %s" % (cmd,)
-    result = dispatch.dispatch(cmd.split())
+    req = dispatch.request(cmd.split())
+    result = dispatch.dispatch(req)
     print "result: %r" % (result,)
 
 
--- a/tests/test-dispatch.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-dispatch.t	Sat Jun 18 17:03:01 2011 -0500
@@ -6,6 +6,11 @@
 
   $ hg init a
   $ cd a
+
+Redundant options used to crash (issue436):
+  $ hg -v log -v
+  $ hg -v log -v x
+
   $ echo a > a
   $ hg ci -Ama
   adding a
@@ -18,20 +23,6 @@
   
   output the current or given revision of files
   
-      Print the specified files as they were at the given revision. If no
-      revision is given, the parent of the working directory is used, or tip if
-      no revision is checked out.
-  
-      Output may be to a file, in which case the name of the file is given using
-      a format string. The formatting rules are the same as for the export
-      command, with the following additions:
-  
-      "%s"  basename of file being printed
-      "%d"  dirname of file being printed, or '.' if in repository root
-      "%p"  root-relative path name of file being printed
-  
-      Returns 0 on success.
-  
   options:
   
    -o --output FORMAT        print output to file with formatted name
@@ -42,7 +33,7 @@
   
   [+] marked option can be specified multiple times
   
-  use "hg -v help cat" to show global options
+  use "hg help cat" to show the full help text
   [255]
 
 [defaults]
@@ -61,6 +52,6 @@
 
   $ cd $dir
   $ hg cat
-  abort: There is no Mercurial repository here (.hg not found)!
+  abort: no repository found in '$TESTTMP' (.hg not found)!
   [255]
 
--- a/tests/test-doctest.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-doctest.py	Sat Jun 18 17:03:01 2011 -0500
@@ -13,6 +13,12 @@
 import mercurial.match
 doctest.testmod(mercurial.match)
 
+import mercurial.store
+doctest.testmod(mercurial.store)
+
+import mercurial.ui
+doctest.testmod(mercurial.ui)
+
 import mercurial.url
 doctest.testmod(mercurial.url)
 
--- a/tests/test-dumprevlog.t	Wed Jun 01 16:32:48 2011 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,107 +0,0 @@
-Set vars:
-
-  $ CONTRIBDIR=$TESTDIR/../contrib
-
-Prepare repo-a:
-
-  $ mkdir repo-a
-  $ cd repo-a
-  $ hg init
-
-  $ echo this is file a > a
-  $ hg add a
-  $ hg commit -m first
-
-  $ echo adding to file a >> a
-  $ hg commit -m second
-
-  $ echo adding more to file a >> a
-  $ hg commit -m third
-
-  $ hg verify
-  checking changesets
-  checking manifests
-  crosschecking files in changesets and manifests
-  checking files
-  1 files, 3 changesets, 3 total revisions
-
-Dumping revlog of file a to stdout:
-
-  $ python $CONTRIBDIR/dumprevlog .hg/store/data/a.i
-  file: .hg/store/data/a.i
-  node: 183d2312b35066fb6b3b449b84efc370d50993d0
-  linkrev: 0
-  parents: 0000000000000000000000000000000000000000 0000000000000000000000000000000000000000
-  length: 15
-  -start-
-  this is file a
-  
-  -end-
-  node: b1047953b6e6b633c0d8197eaa5116fbdfd3095b
-  linkrev: 1
-  parents: 183d2312b35066fb6b3b449b84efc370d50993d0 0000000000000000000000000000000000000000
-  length: 32
-  -start-
-  this is file a
-  adding to file a
-  
-  -end-
-  node: 8c4fd1f7129b8cdec6c7f58bf48fb5237a4030c1
-  linkrev: 2
-  parents: b1047953b6e6b633c0d8197eaa5116fbdfd3095b 0000000000000000000000000000000000000000
-  length: 54
-  -start-
-  this is file a
-  adding to file a
-  adding more to file a
-  
-  -end-
-
-Dump all revlogs to file repo.dump:
-
-  $ find .hg/store -name "*.i" | sort | xargs python $CONTRIBDIR/dumprevlog > ../repo.dump
-  $ cd ..
-
-Undumping into repo-b:
-
-  $ mkdir repo-b
-  $ cd repo-b
-  $ hg init
-  $ python $CONTRIBDIR/undumprevlog < ../repo.dump
-  .hg/store/00changelog.i
-  .hg/store/00manifest.i
-  .hg/store/data/a.i
-  $ cd ..
-
-Rebuild fncache with clone --pull:
-
-  $ hg clone --pull -U repo-b repo-c
-  requesting all changes
-  adding changesets
-  adding manifests
-  adding file changes
-  added 3 changesets with 3 changes to 1 files
-
-Verify:
-
-  $ hg -R repo-c verify
-  checking changesets
-  checking manifests
-  crosschecking files in changesets and manifests
-  checking files
-  1 files, 3 changesets, 3 total revisions
-
-Compare repos:
-
-  $ hg -R repo-c incoming repo-a
-  comparing with repo-a
-  searching for changes
-  no changes found
-  [1]
-
-  $ hg -R repo-a incoming repo-c
-  comparing with repo-c
-  searching for changes
-  no changes found
-  [1]
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-duplicateoptions.py	Sat Jun 18 17:03:01 2011 -0500
@@ -0,0 +1,30 @@
+import os
+from mercurial import ui, commands, extensions
+
+ignore = set(['highlight', 'win32text'])
+
+if os.name != 'nt':
+    ignore.add('win32mbcs')
+
+disabled = [ext for ext in extensions.disabled().keys() if ext not in ignore]
+
+hgrc = open(os.environ["HGRCPATH"], 'w')
+hgrc.write('[extensions]\n')
+
+for ext in disabled:
+    hgrc.write(ext + '=\n')
+
+hgrc.close()
+
+u = ui.ui()
+extensions.loadall(u)
+
+for cmd, entry in commands.table.iteritems():
+    seenshort = set()
+    seenlong = set()
+    for option in entry[1]:
+        if (option[0] and option[0] in seenshort) or \
+           (option[1] and option[1] in seenlong):
+            print "command '" + cmd + "' has duplicate option " + str(option)
+        seenshort.add(option[0])
+        seenlong.add(option[1])
--- a/tests/test-empty-group.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-empty-group.t	Sat Jun 18 17:03:01 2011 -0500
@@ -67,7 +67,7 @@
   $ hg -R a outgoing b
   comparing with b
   searching for changes
-  changeset:   4:119caaef4ed1
+  changeset:   4:1ec3c74fc0e0
   tag:         tip
   parent:      1:79f9e10cd04e
   parent:      2:8e1bb01c1a24
@@ -78,7 +78,7 @@
   $ hg -R a outgoing c
   comparing with c
   searching for changes
-  changeset:   3:cbb48b367d1b
+  changeset:   3:d15a0c284984
   parent:      2:8e1bb01c1a24
   parent:      1:79f9e10cd04e
   user:        test
@@ -88,7 +88,7 @@
   $ hg -R b outgoing c
   comparing with c
   searching for changes
-  changeset:   3:cbb48b367d1b
+  changeset:   3:d15a0c284984
   tag:         tip
   parent:      2:8e1bb01c1a24
   parent:      1:79f9e10cd04e
@@ -99,7 +99,7 @@
   $ hg -R c outgoing b
   comparing with b
   searching for changes
-  changeset:   3:119caaef4ed1
+  changeset:   3:1ec3c74fc0e0
   tag:         tip
   parent:      1:79f9e10cd04e
   parent:      2:8e1bb01c1a24
--- a/tests/test-encode.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-encode.t	Sat Jun 18 17:03:01 2011 -0500
@@ -25,9 +25,9 @@
 
 check contents in repo are encoded
 
-  $ hg debugdata .hg/store/data/a.gz.d 0
+  $ hg debugdata a.gz 0
   this is a test
-  $ hg debugdata .hg/store/data/not.gz.d 0
+  $ hg debugdata not.gz 0
   THIS IS A TEST
 
 check committed content was decoded
--- a/tests/test-encoding.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-encoding.t	Sat Jun 18 17:03:01 2011 -0500
@@ -5,7 +5,7 @@
 
 we need a repo with some legacy latin-1 changesets
 
-  $ hg unbundle $TESTDIR/legacy-encoding.hg
+  $ hg unbundle $TESTDIR/bundles/legacy-encoding.hg
   adding changesets
   adding manifests
   adding file changes
@@ -48,7 +48,7 @@
 hg log (ascii)
 
   $ hg --encoding ascii log
-  changeset:   5:093c6077d1c8
+  changeset:   5:a52c0692f24a
   branch:      ?
   tag:         tip
   user:        test
@@ -85,7 +85,7 @@
 hg log (latin-1)
 
   $ hg --encoding latin-1 log
-  changeset:   5:093c6077d1c8
+  changeset:   5:a52c0692f24a
   branch:      \xe9 (esc)
   tag:         tip
   user:        test
@@ -122,7 +122,7 @@
 hg log (utf-8)
 
   $ hg --encoding utf-8 log
-  changeset:   5:093c6077d1c8
+  changeset:   5:a52c0692f24a
   branch:      \xc3\xa9 (esc)
   tag:         tip
   user:        test
@@ -159,37 +159,37 @@
 hg tags (ascii)
 
   $ HGENCODING=ascii hg tags
-  tip                                5:093c6077d1c8
+  tip                                5:a52c0692f24a
   ?                                  3:ca661e7520de
 
 hg tags (latin-1)
 
   $ HGENCODING=latin-1 hg tags
-  tip                                5:093c6077d1c8
+  tip                                5:a52c0692f24a
   \xe9                                  3:ca661e7520de (esc)
 
 hg tags (utf-8)
 
   $ HGENCODING=utf-8 hg tags
-  tip                                5:093c6077d1c8
+  tip                                5:a52c0692f24a
   \xc3\xa9                                  3:ca661e7520de (esc)
 
 hg branches (ascii)
 
   $ HGENCODING=ascii hg branches
-  ?                              5:093c6077d1c8
+  ?                              5:a52c0692f24a
   default                        4:94db611b4196 (inactive)
 
 hg branches (latin-1)
 
   $ HGENCODING=latin-1 hg branches
-  \xe9                              5:093c6077d1c8 (esc)
+  \xe9                              5:a52c0692f24a (esc)
   default                        4:94db611b4196 (inactive)
 
 hg branches (utf-8)
 
   $ HGENCODING=utf-8 hg branches
-  \xc3\xa9                              5:093c6077d1c8 (esc)
+  \xc3\xa9                              5:a52c0692f24a (esc)
   default                        4:94db611b4196 (inactive)
   $ echo '[ui]' >> .hg/hgrc
   $ echo 'fallbackencoding = koi8-r' >> .hg/hgrc
@@ -197,7 +197,7 @@
 hg log (utf-8)
 
   $ HGENCODING=utf-8 hg log
-  changeset:   5:093c6077d1c8
+  changeset:   5:a52c0692f24a
   branch:      \xc3\xa9 (esc)
   tag:         tip
   user:        test
--- a/tests/test-eol-add.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-eol-add.t	Sat Jun 18 17:03:01 2011 -0500
@@ -1,6 +1,6 @@
 Test adding .hgeol
 
-  $ cat > $HGRCPATH <<EOF
+  $ cat >> $HGRCPATH <<EOF
   > [diff]
   > git = 1
   > EOF
--- a/tests/test-eol-clone.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-eol-clone.t	Sat Jun 18 17:03:01 2011 -0500
@@ -1,9 +1,6 @@
 Testing cloning with the EOL extension
 
-  $ cat > $HGRCPATH <<EOF
-  > [diff]
-  > git = True
-  > 
+  $ cat >> $HGRCPATH <<EOF
   > [extensions]
   > eol =
   > 
--- a/tests/test-eol-hook.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-eol-hook.t	Sat Jun 18 17:03:01 2011 -0500
@@ -1,14 +1,7 @@
 Test the EOL hook
 
-  $ cat > $HGRCPATH <<EOF
-  > [diff]
-  > git = True
-  > EOF
   $ hg init main
   $ cat > main/.hg/hgrc <<EOF
-  > [extensions]
-  > eol =
-  > 
   > [hooks]
   > pretxnchangegroup = python:hgext.eol.hook
   > EOF
@@ -47,10 +40,12 @@
   adding manifests
   adding file changes
   added 1 changesets with 1 changes to 1 files
-  error: pretxnchangegroup hook failed: a.txt should not have CRLF line endings
+  error: pretxnchangegroup hook failed: end-of-line check failed:
+    a.txt in a8ee6548cd86 should not have CRLF line endings
   transaction abort!
   rollback completed
-  abort: a.txt should not have CRLF line endings
+  abort: end-of-line check failed:
+    a.txt in a8ee6548cd86 should not have CRLF line endings
   [255]
 
   $ printf "first\nsecond\nthird\n" > a.txt
@@ -73,10 +68,12 @@
   adding manifests
   adding file changes
   added 1 changesets with 1 changes to 1 files
-  error: pretxnchangegroup hook failed: crlf.txt should not have LF line endings
+  error: pretxnchangegroup hook failed: end-of-line check failed:
+    crlf.txt in 004ba2132725 should not have LF line endings
   transaction abort!
   rollback completed
-  abort: crlf.txt should not have LF line endings
+  abort: end-of-line check failed:
+    crlf.txt in 004ba2132725 should not have LF line endings
   [255]
 
   $ printf "first\r\nsecond\r\nthird\r\n" > crlf.txt
@@ -88,3 +85,133 @@
   adding manifests
   adding file changes
   added 2 changesets with 2 changes to 1 files
+
+  $ printf "first\r\nsecond" > b.txt
+  $ hg add b.txt
+  $ hg commit -m 'CRLF b.txt'
+  $ hg push ../main
+  pushing to ../main
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 1 changes to 1 files
+  error: pretxnchangegroup hook failed: end-of-line check failed:
+    b.txt in fbcf9b1025f5 should not have CRLF line endings
+  transaction abort!
+  rollback completed
+  abort: end-of-line check failed:
+    b.txt in fbcf9b1025f5 should not have CRLF line endings
+  [255]
+
+  $ hg up -r -2
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ printf "some\nother\nfile" > c.txt
+  $ hg add c.txt
+  $ hg commit -m "LF c.txt, b.txt doesn't exist here"
+  created new head
+  $ hg push -f ../main
+  pushing to ../main
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 2 changesets with 2 changes to 2 files (+1 heads)
+  error: pretxnchangegroup hook failed: end-of-line check failed:
+    b.txt in fbcf9b1025f5 should not have CRLF line endings
+  transaction abort!
+  rollback completed
+  abort: end-of-line check failed:
+    b.txt in fbcf9b1025f5 should not have CRLF line endings
+  [255]
+
+Test checkheadshook alias
+
+  $ cat > ../main/.hg/hgrc <<EOF
+  > [hooks]
+  > pretxnchangegroup = python:hgext.eol.checkheadshook
+  > EOF
+  $ hg push -f ../main
+  pushing to ../main
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 2 changesets with 2 changes to 2 files (+1 heads)
+  error: pretxnchangegroup hook failed: end-of-line check failed:
+    b.txt in fbcf9b1025f5 should not have CRLF line endings
+  transaction abort!
+  rollback completed
+  abort: end-of-line check failed:
+    b.txt in fbcf9b1025f5 should not have CRLF line endings
+  [255]
+
+We can fix the head and push again
+
+  $ hg up 6
+  1 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ printf "first\nsecond" > b.txt
+  $ hg ci -m "remove CRLF from b.txt"
+  $ hg push -f ../main
+  pushing to ../main
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 3 changesets with 3 changes to 2 files (+1 heads)
+  $ hg -R ../main rollback
+  repository tip rolled back to revision 5 (undo push)
+  working directory now based on revision -1
+
+Test it still fails with checkallhook
+
+  $ cat > ../main/.hg/hgrc <<EOF
+  > [hooks]
+  > pretxnchangegroup = python:hgext.eol.checkallhook
+  > EOF
+  $ hg push -f ../main
+  pushing to ../main
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 3 changesets with 3 changes to 2 files (+1 heads)
+  error: pretxnchangegroup hook failed: end-of-line check failed:
+    b.txt in fbcf9b1025f5 should not have CRLF line endings
+  transaction abort!
+  rollback completed
+  abort: end-of-line check failed:
+    b.txt in fbcf9b1025f5 should not have CRLF line endings
+  [255]
+
+But we can push the clean head
+
+  $ hg push -r7 -f ../main
+  pushing to ../main
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 1 changes to 1 files
+
+Test multiple files/revisions output
+
+  $ printf "another\r\nbad\r\none" > d.txt
+  $ hg add d.txt
+  $ hg ci -m "add d.txt"
+  $ hg push -f ../main
+  pushing to ../main
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 3 changesets with 3 changes to 2 files (+1 heads)
+  error: pretxnchangegroup hook failed: end-of-line check failed:
+    d.txt in a7040e68714f should not have CRLF line endings
+    b.txt in fbcf9b1025f5 should not have CRLF line endings
+  transaction abort!
+  rollback completed
+  abort: end-of-line check failed:
+    d.txt in a7040e68714f should not have CRLF line endings
+    b.txt in fbcf9b1025f5 should not have CRLF line endings
+  [255]
--- a/tests/test-eol-patch.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-eol-patch.t	Sat Jun 18 17:03:01 2011 -0500
@@ -1,6 +1,6 @@
 Test EOL patching
 
-  $ cat > $HGRCPATH <<EOF
+  $ cat >> $HGRCPATH <<EOF
   > [diff]
   > git = 1
   > EOF
--- a/tests/test-eol-tag.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-eol-tag.t	Sat Jun 18 17:03:01 2011 -0500
@@ -2,10 +2,7 @@
 
 Testing tagging with the EOL extension
 
-  $ cat > $HGRCPATH <<EOF
-  > [diff]
-  > git = True
-  > 
+  $ cat >> $HGRCPATH <<EOF
   > [extensions]
   > eol =
   > 
--- a/tests/test-eol-update.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-eol-update.t	Sat Jun 18 17:03:01 2011 -0500
@@ -1,6 +1,6 @@
 Test EOL update
 
-  $ cat > $HGRCPATH <<EOF
+  $ cat >> $HGRCPATH <<EOF
   > [diff]
   > git = 1
   > EOF
--- a/tests/test-eol.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-eol.t	Sat Jun 18 17:03:01 2011 -0500
@@ -1,6 +1,6 @@
 Test EOL extension
 
-  $ cat > $HGRCPATH <<EOF
+  $ cat >> $HGRCPATH <<EOF
   > [diff]
   > git = True
   > EOF
--- a/tests/test-eolfilename.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-eolfilename.t	Sat Jun 18 17:03:01 2011 -0500
@@ -36,6 +36,17 @@
   o  hell
   o
 
+  $ echo bla > quickfox
+  $ hg add quickfox
+  $ hg ci -m 2
+  $ A=`printf 'quick\rfox'`
+  $ hg cp quickfox "$A"
+  abort: '\n' and '\r' disallowed in filenames: 'quick\rfox'
+  [255]
+  $ hg mv quickfox "$A"
+  abort: '\n' and '\r' disallowed in filenames: 'quick\rfox'
+  [255]
+
 http://mercurial.selenic.com/bts/issue2036
 
   $ cd ..
@@ -46,6 +57,8 @@
   $ cd bar
   $ echo "[extensions]" >> $HGRCPATH
   $ echo "color=" >> $HGRCPATH
+  $ echo "[color]" >> $HGRCPATH
+  $ echo "mode = ansi" >> $HGRCPATH
   $ A=`printf 'foo\nbar'`
   $ B=`printf 'foo\nbar.baz'`
   $ touch "$A"
--- a/tests/test-excessive-merge.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-excessive-merge.t	Sat Jun 18 17:03:01 2011 -0500
@@ -63,7 +63,7 @@
   date:        Thu Jan 01 00:00:00 1970 +0000
   summary:     test
   
-  $ hg debugindex .hg/store/00changelog.i
+  $ hg debugindex --changelog
      rev    offset  length   base linkrev nodeid       p1           p2
        0         0      60      0       0 5e0375449e74 000000000000 000000000000
        1        60      62      1       1 96155394af80 5e0375449e74 000000000000
@@ -88,7 +88,7 @@
   79d7492df40aa0fa093ec4209be78043c181f094 644   a
   79d7492df40aa0fa093ec4209be78043c181f094 644   b
 
-  $ hg debugindex .hg/store/data/a.i
+  $ hg debugindex a
      rev    offset  length   base linkrev nodeid       p1           p2
        0         0       5      0       0 2ed2a3912a0b 000000000000 000000000000
        1         5       6      1       1 79d7492df40a 2ed2a3912a0b 000000000000
--- a/tests/test-extdiff.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-extdiff.t	Sat Jun 18 17:03:01 2011 -0500
@@ -57,7 +57,7 @@
 Should diff cloned files directly:
 
   $ hg falabala -r 0:1
-  diffing a.8a5febb7f867/a a.34eed99112ab/a
+  diffing */extdiff.*/a.8a5febb7f867/a a.34eed99112ab/a (glob)
   [1]
 
 Test diff during merge:
@@ -75,7 +75,7 @@
 Should diff cloned file against wc file:
 
   $ hg falabala
-  diffing a.2a13a4d2da36/a $TESTTMP/a/a
+  diffing */extdiff.*/a.2a13a4d2da36/a */a/a (glob)
   [1]
 
 
@@ -83,13 +83,13 @@
 
   $ hg ci -d '2 0' -mtest3
   $ hg falabala -c 1
-  diffing a.8a5febb7f867/a a.34eed99112ab/a
+  diffing */extdiff.*/a.8a5febb7f867/a a.34eed99112ab/a (glob)
   [1]
 
 Check diff are made from the first parent:
 
   $ hg falabala -c 3 || echo "diff-like tools yield a non-zero exit code"
-  diffing a.2a13a4d2da36/a a.46c0e4daeb72/a
+  diffing */extdiff.*/a.2a13a4d2da36/a a.46c0e4daeb72/a (glob)
   diff-like tools yield a non-zero exit code
 
 Test extdiff of multiple files in tmp dir:
@@ -161,14 +161,27 @@
 Test extdiff with --option:
 
   $ hg extdiff -p echo -o this -c 1
-  this a.8a5febb7f867/a a.34eed99112ab/a
+  this */extdiff.*/a.8a5febb7f867/a a.34eed99112ab/a (glob)
   [1]
 
   $ hg falabala -o this -c 1
-  diffing this a.8a5febb7f867/a a.34eed99112ab/a
+  diffing this */extdiff.*/a.8a5febb7f867/a a.34eed99112ab/a (glob)
+  [1]
+
+Test with revsets:
+
+  $ hg extdif -p echo -c "rev(1)"
+  */extdiff.*/a.8a5febb7f867/a a.34eed99112ab/a (glob)
   [1]
+
+  $ hg extdif -p echo -r "0::1"
+  */extdiff.*/a.8a5febb7f867/a a.34eed99112ab/a (glob)
+  [1]
+
   $ cd ..
 
+Test symlinks handling (issue1909)
+
   $ hg init testsymlinks
   $ cd testsymlinks
   $ echo a > a
@@ -181,4 +194,3 @@
   diffing testsymlinks.07f494440405 testsymlinks
   [1]
   $ cd ..
-
--- a/tests/test-extension.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-extension.t	Sat Jun 18 17:03:01 2011 -0500
@@ -232,6 +232,156 @@
   [+] marked option can be specified multiple times
   $ echo 'debugextension = !' >> $HGRCPATH
 
+Extension module help vs command help:
+
+  $ echo 'extdiff =' >> $HGRCPATH
+  $ hg help extdiff
+  hg extdiff [OPT]... [FILE]...
+  
+  use external program to diff repository (or selected files)
+  
+      Show differences between revisions for the specified files, using an
+      external program. The default program used is diff, with default options
+      "-Npru".
+  
+      To select a different program, use the -p/--program option. The program
+      will be passed the names of two directories to compare. To pass additional
+      options to the program, use -o/--option. These will be passed before the
+      names of the directories to compare.
+  
+      When two revision arguments are given, then changes are shown between
+      those revisions. If only one revision is specified then that revision is
+      compared to the working directory, and, when no revisions are specified,
+      the working directory files are compared to its parent.
+  
+  use "hg help -e extdiff" to show help for the extdiff extension
+  
+  options:
+  
+   -p --program CMD          comparison program to run
+   -o --option OPT [+]       pass option to comparison program
+   -r --rev REV [+]          revision
+   -c --change REV           change made by revision
+   -I --include PATTERN [+]  include names matching the given patterns
+   -X --exclude PATTERN [+]  exclude names matching the given patterns
+  
+  [+] marked option can be specified multiple times
+  
+  use "hg -v help extdiff" to show global options
+
+  $ hg help --extension extdiff
+  extdiff extension - command to allow external programs to compare revisions
+  
+  The extdiff Mercurial extension allows you to use external programs to compare
+  revisions, or revision with working directory. The external diff programs are
+  called with a configurable set of options and two non-option arguments: paths
+  to directories containing snapshots of files to compare.
+  
+  The extdiff extension also allows you to configure new diff commands, so you
+  do not need to type "hg extdiff -p kdiff3" always.
+  
+    [extdiff]
+    # add new command that runs GNU diff(1) in 'context diff' mode
+    cdiff = gdiff -Nprc5
+    ## or the old way:
+    #cmd.cdiff = gdiff
+    #opts.cdiff = -Nprc5
+  
+    # add new command called vdiff, runs kdiff3
+    vdiff = kdiff3
+  
+    # add new command called meld, runs meld (no need to name twice)
+    meld =
+  
+    # add new command called vimdiff, runs gvimdiff with DirDiff plugin
+    # (see http://www.vim.org/scripts/script.php?script_id=102) Non
+    # English user, be sure to put "let g:DirDiffDynamicDiffText = 1" in
+    # your .vimrc
+    vimdiff = gvim -f '+next' '+execute "DirDiff" argv(0) argv(1)'
+  
+  Tool arguments can include variables that are expanded at runtime:
+  
+    $parent1, $plabel1 - filename, descriptive label of first parent
+    $child,   $clabel  - filename, descriptive label of child revision
+    $parent2, $plabel2 - filename, descriptive label of second parent
+    $root              - repository root
+    $parent is an alias for $parent1.
+  
+  The extdiff extension will look in your [diff-tools] and [merge-tools]
+  sections for diff tool arguments, when none are specified in [extdiff].
+  
+    [extdiff]
+    kdiff3 =
+  
+    [diff-tools]
+    kdiff3.diffargs=--L1 '$plabel1' --L2 '$clabel' $parent $child
+  
+  You can use -I/-X and list of file or directory names like normal "hg diff"
+  command. The extdiff extension makes snapshots of only needed files, so
+  running the external diff program will actually be pretty fast (at least
+  faster than having to compare the entire tree).
+  
+  list of commands:
+  
+   extdiff   use external program to diff repository (or selected files)
+  
+  use "hg -v help extdiff" to show builtin aliases and global options
+
+  $ echo 'extdiff = !' >> $HGRCPATH
+
+Test help topic with same name as extension
+
+  $ cat > multirevs.py <<EOF
+  > from mercurial import commands
+  > """multirevs extension
+  > Big multi-line module docstring."""
+  > def multirevs(ui, repo, arg, *args, **opts):
+  >     """multirevs command"""
+  >     pass
+  > cmdtable = {
+  >    "multirevs": (multirevs, [], 'ARG')
+  > }
+  > commands.norepo += ' multirevs'
+  > EOF
+  $ echo "multirevs = multirevs.py" >> $HGRCPATH
+
+  $ hg help multirevs
+  Specifying Multiple Revisions
+  
+      When Mercurial accepts more than one revision, they may be specified
+      individually, or provided as a topologically continuous range, separated
+      by the ":" character.
+  
+      The syntax of range notation is [BEGIN]:[END], where BEGIN and END are
+      revision identifiers. Both BEGIN and END are optional. If BEGIN is not
+      specified, it defaults to revision number 0. If END is not specified, it
+      defaults to the tip. The range ":" thus means "all revisions".
+  
+      If BEGIN is greater than END, revisions are treated in reverse order.
+  
+      A range acts as a closed interval. This means that a range of 3:5 gives 3,
+      4 and 5. Similarly, a range of 9:6 gives 9, 8, 7, and 6.
+  
+  use "hg help -c multirevs" to see help for the multirevs command
+
+  $ hg help -c multirevs
+  hg multirevs ARG
+  
+  multirevs command
+  
+  use "hg -v help multirevs" to show global options
+
+  $ hg multirevs
+  hg multirevs: invalid arguments
+  hg multirevs ARG
+  
+  multirevs command
+  
+  use "hg help multirevs" to show the full help text
+  [255]
+
+  $ echo "multirevs = !" >> $HGRCPATH
+
 Issue811: Problem loading extensions twice (by site and by user)
 
   $ debugpath=`pwd`/debugissue811.py
--- a/tests/test-extra-filelog-entry.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-extra-filelog-entry.t	Sat Jun 18 17:03:01 2011 -0500
@@ -15,7 +15,7 @@
   $ echo b > b
   $ hg qrefresh
 
-  $ hg debugindex .hg/store/data/b.i
+  $ hg debugindex b
      rev    offset  length   base linkrev nodeid       p1           p2
        0         0       3      0       0 1e88685f5dde 000000000000 000000000000
 
--- a/tests/test-filebranch.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-filebranch.t	Sat Jun 18 17:03:01 2011 -0500
@@ -75,7 +75,7 @@
 
 main: we should have a merge here:
 
-  $ hg debugindex .hg/store/00changelog.i
+  $ hg debugindex --changelog
      rev    offset  length   base linkrev nodeid       p1           p2
        0         0      73      0       0 cdca01651b96 000000000000 000000000000
        1        73      68      1       1 f6718a9cb7f3 cdca01651b96 000000000000
@@ -99,7 +99,7 @@
 
 foo: we should have a merge here:
 
-  $ hg debugindex .hg/store/data/foo.i
+  $ hg debugindex foo
      rev    offset  length   base linkrev nodeid       p1           p2
        0         0       3      0       0 b8e02f643373 000000000000 000000000000
        1         3       4      1       1 2ffeddde1b65 b8e02f643373 000000000000
@@ -108,21 +108,21 @@
 
 bar: we should not have a merge here:
 
-  $ hg debugindex .hg/store/data/bar.i
+  $ hg debugindex bar
      rev    offset  length   base linkrev nodeid       p1           p2
        0         0       3      0       0 b8e02f643373 000000000000 000000000000
        1         3       4      1       2 33d1fb69067a b8e02f643373 000000000000
 
 baz: we should not have a merge here:
 
-  $ hg debugindex .hg/store/data/baz.i
+  $ hg debugindex baz
      rev    offset  length   base linkrev nodeid       p1           p2
        0         0       3      0       0 b8e02f643373 000000000000 000000000000
        1         3       4      1       1 2ffeddde1b65 b8e02f643373 000000000000
 
 quux: we should not have a merge here:
 
-  $ hg debugindex .hg/store/data/quux.i
+  $ hg debugindex quux
      rev    offset  length   base linkrev nodeid       p1           p2
        0         0       3      0       0 b8e02f643373 000000000000 000000000000
        1         3       5      1       3 6128c0f33108 b8e02f643373 000000000000
--- a/tests/test-flags.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-flags.t	Sat Jun 18 17:03:01 2011 -0500
@@ -1,8 +1,7 @@
   $ umask 027
-  $ mkdir test1
+
+  $ hg init test1
   $ cd test1
-
-  $ hg init
   $ touch a b
   $ hg add a b
   $ hg ci -m "added a b"
@@ -11,10 +10,9 @@
   $ hg clone test1 test3
   updating to branch default
   2 files updated, 0 files merged, 0 files removed, 0 files unresolved
-  $ mkdir test2
+
+  $ hg init test2
   $ cd test2
-
-  $ hg init
   $ hg pull ../test1
   pulling from ../test1
   requesting all changes
@@ -137,13 +135,13 @@
   -rwxr-x---
   -rwxr-x---
 
-  $ hg debugindex .hg/store/data/a.i
+  $ hg debugindex a
      rev    offset  length   base linkrev nodeid       p1           p2
        0         0       0      0       0 b80de5d13875 000000000000 000000000000
-  $ hg debugindex ../test2/.hg/store/data/a.i
+  $ hg debugindex -R ../test2 a
      rev    offset  length   base linkrev nodeid       p1           p2
        0         0       0      0       0 b80de5d13875 000000000000 000000000000
-  $ hg debugindex ../test1/.hg/store/data/a.i
+  $ hg debugindex -R ../test1 a
      rev    offset  length   base linkrev nodeid       p1           p2
        0         0       0      0       0 b80de5d13875 000000000000 000000000000
        1         0       5      1       1 7fe919cc0336 b80de5d13875 000000000000
--- a/tests/test-gendoc.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-gendoc.t	Sat Jun 18 17:03:01 2011 -0500
@@ -44,6 +44,9 @@
   % extracting documentation from ro
   checking for parse errors
   
+  % extracting documentation from ru
+  checking for parse errors
+  
   % extracting documentation from sv
   checking for parse errors
   
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-getbundle.t	Sat Jun 18 17:03:01 2011 -0500
@@ -0,0 +1,253 @@
+
+= Test the getbundle() protocol function =
+
+Enable graphlog extension:
+
+  $ echo "[extensions]" >> $HGRCPATH
+  $ echo "graphlog=" >> $HGRCPATH
+
+Create a test repository:
+
+  $ hg init repo
+  $ cd repo
+  $ hg debugbuilddag -n -m '+2 :fork +5 :p1 *fork +6 :p2 /p1 :m1 +3' > /dev/null
+  $ hg glog --template '{node}\n'
+  o  10c14a2cc935e1d8c31f9e98587dcf27fb08a6da
+  |
+  o  4801a72e5d88cb515b0c7e40fae34180f3f837f2
+  |
+  o  0b2f73f04880d9cb6a5cd8a757f0db0ad01e32c3
+  |
+  o    8365676dbab05860ce0d9110f2af51368b961bbd
+  |\
+  | o  5686dbbd9fc46cb806599c878d02fe1cb56b83d3
+  | |
+  | o  13c0170174366b441dc68e8e33757232fa744458
+  | |
+  | o  63476832d8ec6558cf9bbe3cbe0c757e5cf18043
+  | |
+  | o  700b7e19db54103633c4bf4a6a6b6d55f4d50c03
+  | |
+  | o  928b5f94cdb278bb536eba552de348a4e92ef24d
+  | |
+  | o  f34414c64173e0ecb61b25dc55e116dbbcc89bee
+  | |
+  | o  8931463777131cd73923e560b760061f2aa8a4bc
+  | |
+  o |  6621d79f61b23ec74cf4b69464343d9e0980ec8b
+  | |
+  o |  bac16991d12ff45f9dc43c52da1946dfadb83e80
+  | |
+  o |  ff42371d57168345fdf1a3aac66a51f6a45d41d2
+  | |
+  o |  d5f6e1ea452285324836a49d7d3c2a63cfed1d31
+  | |
+  o |  713346a995c363120712aed1aee7e04afd867638
+  |/
+  o  29a4d1f17bd3f0779ca0525bebb1cfb51067c738
+  |
+  o  7704483d56b2a7b5db54dcee7c62378ac629b348
+  
+  $ cd ..
+
+
+= Test locally =
+
+Get everything:
+
+  $ hg debuggetbundle repo bundle
+  $ hg debugbundle bundle
+  7704483d56b2a7b5db54dcee7c62378ac629b348
+  29a4d1f17bd3f0779ca0525bebb1cfb51067c738
+  713346a995c363120712aed1aee7e04afd867638
+  d5f6e1ea452285324836a49d7d3c2a63cfed1d31
+  ff42371d57168345fdf1a3aac66a51f6a45d41d2
+  bac16991d12ff45f9dc43c52da1946dfadb83e80
+  6621d79f61b23ec74cf4b69464343d9e0980ec8b
+  8931463777131cd73923e560b760061f2aa8a4bc
+  f34414c64173e0ecb61b25dc55e116dbbcc89bee
+  928b5f94cdb278bb536eba552de348a4e92ef24d
+  700b7e19db54103633c4bf4a6a6b6d55f4d50c03
+  63476832d8ec6558cf9bbe3cbe0c757e5cf18043
+  13c0170174366b441dc68e8e33757232fa744458
+  5686dbbd9fc46cb806599c878d02fe1cb56b83d3
+  8365676dbab05860ce0d9110f2af51368b961bbd
+  0b2f73f04880d9cb6a5cd8a757f0db0ad01e32c3
+  4801a72e5d88cb515b0c7e40fae34180f3f837f2
+  10c14a2cc935e1d8c31f9e98587dcf27fb08a6da
+
+Get part of linear run:
+
+  $ hg debuggetbundle repo bundle -H 4801a72e5d88cb515b0c7e40fae34180f3f837f2 -C 8365676dbab05860ce0d9110f2af51368b961bbd
+  $ hg debugbundle bundle
+  0b2f73f04880d9cb6a5cd8a757f0db0ad01e32c3
+  4801a72e5d88cb515b0c7e40fae34180f3f837f2
+
+Get missing branch and merge:
+
+  $ hg debuggetbundle repo bundle -H 4801a72e5d88cb515b0c7e40fae34180f3f837f2 -C 13c0170174366b441dc68e8e33757232fa744458
+  $ hg debugbundle bundle
+  713346a995c363120712aed1aee7e04afd867638
+  d5f6e1ea452285324836a49d7d3c2a63cfed1d31
+  ff42371d57168345fdf1a3aac66a51f6a45d41d2
+  bac16991d12ff45f9dc43c52da1946dfadb83e80
+  6621d79f61b23ec74cf4b69464343d9e0980ec8b
+  5686dbbd9fc46cb806599c878d02fe1cb56b83d3
+  8365676dbab05860ce0d9110f2af51368b961bbd
+  0b2f73f04880d9cb6a5cd8a757f0db0ad01e32c3
+  4801a72e5d88cb515b0c7e40fae34180f3f837f2
+
+Get from only one head:
+
+  $ hg debuggetbundle repo bundle -H 928b5f94cdb278bb536eba552de348a4e92ef24d -C 29a4d1f17bd3f0779ca0525bebb1cfb51067c738
+  $ hg debugbundle bundle
+  8931463777131cd73923e560b760061f2aa8a4bc
+  f34414c64173e0ecb61b25dc55e116dbbcc89bee
+  928b5f94cdb278bb536eba552de348a4e92ef24d
+
+Get parts of two branches:
+
+  $ hg debuggetbundle repo bundle -H 13c0170174366b441dc68e8e33757232fa744458 -C 700b7e19db54103633c4bf4a6a6b6d55f4d50c03 -H bac16991d12ff45f9dc43c52da1946dfadb83e80 -C d5f6e1ea452285324836a49d7d3c2a63cfed1d31
+  $ hg debugbundle bundle
+  ff42371d57168345fdf1a3aac66a51f6a45d41d2
+  bac16991d12ff45f9dc43c52da1946dfadb83e80
+  63476832d8ec6558cf9bbe3cbe0c757e5cf18043
+  13c0170174366b441dc68e8e33757232fa744458
+
+Check that we get all needed file changes:
+
+  $ hg debugbundle bundle --all
+  format: id, p1, p2, cset, delta base, len(delta)
+  
+  changelog
+  ff42371d57168345fdf1a3aac66a51f6a45d41d2 d5f6e1ea452285324836a49d7d3c2a63cfed1d31 0000000000000000000000000000000000000000 ff42371d57168345fdf1a3aac66a51f6a45d41d2 d5f6e1ea452285324836a49d7d3c2a63cfed1d31 99
+  bac16991d12ff45f9dc43c52da1946dfadb83e80 ff42371d57168345fdf1a3aac66a51f6a45d41d2 0000000000000000000000000000000000000000 bac16991d12ff45f9dc43c52da1946dfadb83e80 ff42371d57168345fdf1a3aac66a51f6a45d41d2 99
+  63476832d8ec6558cf9bbe3cbe0c757e5cf18043 700b7e19db54103633c4bf4a6a6b6d55f4d50c03 0000000000000000000000000000000000000000 63476832d8ec6558cf9bbe3cbe0c757e5cf18043 bac16991d12ff45f9dc43c52da1946dfadb83e80 102
+  13c0170174366b441dc68e8e33757232fa744458 63476832d8ec6558cf9bbe3cbe0c757e5cf18043 0000000000000000000000000000000000000000 13c0170174366b441dc68e8e33757232fa744458 63476832d8ec6558cf9bbe3cbe0c757e5cf18043 102
+  
+  manifest
+  dac7984588fc4eea7acbf39693a9c1b06f5b175d 591f732a3faf1fb903815273f3c199a514a61ccb 0000000000000000000000000000000000000000 ff42371d57168345fdf1a3aac66a51f6a45d41d2 591f732a3faf1fb903815273f3c199a514a61ccb 113
+  0772616e6b48a76afb6c1458e193cbb3dae2e4ff dac7984588fc4eea7acbf39693a9c1b06f5b175d 0000000000000000000000000000000000000000 bac16991d12ff45f9dc43c52da1946dfadb83e80 dac7984588fc4eea7acbf39693a9c1b06f5b175d 113
+  eb498cd9af6c44108e43041e951ce829e29f6c80 bff2f4817ced57b386caf7c4e3e36a4bc9af7e93 0000000000000000000000000000000000000000 63476832d8ec6558cf9bbe3cbe0c757e5cf18043 0772616e6b48a76afb6c1458e193cbb3dae2e4ff 295
+  b15709c071ddd2d93188508ba156196ab4f19620 eb498cd9af6c44108e43041e951ce829e29f6c80 0000000000000000000000000000000000000000 13c0170174366b441dc68e8e33757232fa744458 eb498cd9af6c44108e43041e951ce829e29f6c80 114
+  
+  mf
+  4f73f97080266ab8e0c0561ca8d0da3eaf65b695 301ca08d026bb72cb4258a9d211bdf7ca0bcd810 0000000000000000000000000000000000000000 ff42371d57168345fdf1a3aac66a51f6a45d41d2 301ca08d026bb72cb4258a9d211bdf7ca0bcd810 17
+  c7b583de053293870e145f45bd2d61643563fd06 4f73f97080266ab8e0c0561ca8d0da3eaf65b695 0000000000000000000000000000000000000000 bac16991d12ff45f9dc43c52da1946dfadb83e80 4f73f97080266ab8e0c0561ca8d0da3eaf65b695 18
+  266ee3c0302a5a18f1cf96817ac79a51836179e9 edc0f6b8db80d68ae6aff2b19f7e5347ab68fa63 0000000000000000000000000000000000000000 63476832d8ec6558cf9bbe3cbe0c757e5cf18043 c7b583de053293870e145f45bd2d61643563fd06 149
+  698c6a36220548cd3903ca7dada27c59aa500c52 266ee3c0302a5a18f1cf96817ac79a51836179e9 0000000000000000000000000000000000000000 13c0170174366b441dc68e8e33757232fa744458 266ee3c0302a5a18f1cf96817ac79a51836179e9 19
+  
+  nf11
+  33fbc651630ffa7ccbebfe4eb91320a873e7291c 0000000000000000000000000000000000000000 0000000000000000000000000000000000000000 63476832d8ec6558cf9bbe3cbe0c757e5cf18043 0000000000000000000000000000000000000000 16
+  
+  nf12
+  ddce0544363f037e9fb889faca058f52dc01c0a5 0000000000000000000000000000000000000000 0000000000000000000000000000000000000000 13c0170174366b441dc68e8e33757232fa744458 0000000000000000000000000000000000000000 16
+  
+  nf4
+  3c1407305701051cbed9f9cb9a68bdfb5997c235 0000000000000000000000000000000000000000 0000000000000000000000000000000000000000 ff42371d57168345fdf1a3aac66a51f6a45d41d2 0000000000000000000000000000000000000000 15
+  
+  nf5
+  0dbd89c185f53a1727c54cd1ce256482fa23968e 0000000000000000000000000000000000000000 0000000000000000000000000000000000000000 bac16991d12ff45f9dc43c52da1946dfadb83e80 0000000000000000000000000000000000000000 15
+
+Get branch and merge:
+
+  $ hg debuggetbundle repo bundle -C 7704483d56b2a7b5db54dcee7c62378ac629b348 -H 0b2f73f04880d9cb6a5cd8a757f0db0ad01e32c3
+  $ hg debugbundle bundle
+  29a4d1f17bd3f0779ca0525bebb1cfb51067c738
+  713346a995c363120712aed1aee7e04afd867638
+  d5f6e1ea452285324836a49d7d3c2a63cfed1d31
+  ff42371d57168345fdf1a3aac66a51f6a45d41d2
+  bac16991d12ff45f9dc43c52da1946dfadb83e80
+  6621d79f61b23ec74cf4b69464343d9e0980ec8b
+  8931463777131cd73923e560b760061f2aa8a4bc
+  f34414c64173e0ecb61b25dc55e116dbbcc89bee
+  928b5f94cdb278bb536eba552de348a4e92ef24d
+  700b7e19db54103633c4bf4a6a6b6d55f4d50c03
+  63476832d8ec6558cf9bbe3cbe0c757e5cf18043
+  13c0170174366b441dc68e8e33757232fa744458
+  5686dbbd9fc46cb806599c878d02fe1cb56b83d3
+  8365676dbab05860ce0d9110f2af51368b961bbd
+  0b2f73f04880d9cb6a5cd8a757f0db0ad01e32c3
+
+
+= Test via HTTP =
+
+Get everything:
+
+  $ hg serve -R repo -p $HGPORT -d --pid-file=hg.pid -E error.log -A access.log
+  $ cat hg.pid >> $DAEMON_PIDS
+  $ hg debuggetbundle http://localhost:$HGPORT/ bundle
+  $ hg debugbundle bundle
+  7704483d56b2a7b5db54dcee7c62378ac629b348
+  29a4d1f17bd3f0779ca0525bebb1cfb51067c738
+  713346a995c363120712aed1aee7e04afd867638
+  d5f6e1ea452285324836a49d7d3c2a63cfed1d31
+  ff42371d57168345fdf1a3aac66a51f6a45d41d2
+  bac16991d12ff45f9dc43c52da1946dfadb83e80
+  6621d79f61b23ec74cf4b69464343d9e0980ec8b
+  8931463777131cd73923e560b760061f2aa8a4bc
+  f34414c64173e0ecb61b25dc55e116dbbcc89bee
+  928b5f94cdb278bb536eba552de348a4e92ef24d
+  700b7e19db54103633c4bf4a6a6b6d55f4d50c03
+  63476832d8ec6558cf9bbe3cbe0c757e5cf18043
+  13c0170174366b441dc68e8e33757232fa744458
+  5686dbbd9fc46cb806599c878d02fe1cb56b83d3
+  8365676dbab05860ce0d9110f2af51368b961bbd
+  0b2f73f04880d9cb6a5cd8a757f0db0ad01e32c3
+  4801a72e5d88cb515b0c7e40fae34180f3f837f2
+  10c14a2cc935e1d8c31f9e98587dcf27fb08a6da
+
+Get parts of two branches:
+
+  $ hg debuggetbundle http://localhost:$HGPORT/ bundle -H 13c0170174366b441dc68e8e33757232fa744458 -C 700b7e19db54103633c4bf4a6a6b6d55f4d50c03 -H bac16991d12ff45f9dc43c52da1946dfadb83e80 -C d5f6e1ea452285324836a49d7d3c2a63cfed1d31
+  $ hg debugbundle bundle
+  ff42371d57168345fdf1a3aac66a51f6a45d41d2
+  bac16991d12ff45f9dc43c52da1946dfadb83e80
+  63476832d8ec6558cf9bbe3cbe0c757e5cf18043
+  13c0170174366b441dc68e8e33757232fa744458
+
+Check that we get all needed file changes:
+
+  $ hg debugbundle bundle --all
+  format: id, p1, p2, cset, delta base, len(delta)
+  
+  changelog
+  ff42371d57168345fdf1a3aac66a51f6a45d41d2 d5f6e1ea452285324836a49d7d3c2a63cfed1d31 0000000000000000000000000000000000000000 ff42371d57168345fdf1a3aac66a51f6a45d41d2 d5f6e1ea452285324836a49d7d3c2a63cfed1d31 99
+  bac16991d12ff45f9dc43c52da1946dfadb83e80 ff42371d57168345fdf1a3aac66a51f6a45d41d2 0000000000000000000000000000000000000000 bac16991d12ff45f9dc43c52da1946dfadb83e80 ff42371d57168345fdf1a3aac66a51f6a45d41d2 99
+  63476832d8ec6558cf9bbe3cbe0c757e5cf18043 700b7e19db54103633c4bf4a6a6b6d55f4d50c03 0000000000000000000000000000000000000000 63476832d8ec6558cf9bbe3cbe0c757e5cf18043 bac16991d12ff45f9dc43c52da1946dfadb83e80 102
+  13c0170174366b441dc68e8e33757232fa744458 63476832d8ec6558cf9bbe3cbe0c757e5cf18043 0000000000000000000000000000000000000000 13c0170174366b441dc68e8e33757232fa744458 63476832d8ec6558cf9bbe3cbe0c757e5cf18043 102
+  
+  manifest
+  dac7984588fc4eea7acbf39693a9c1b06f5b175d 591f732a3faf1fb903815273f3c199a514a61ccb 0000000000000000000000000000000000000000 ff42371d57168345fdf1a3aac66a51f6a45d41d2 591f732a3faf1fb903815273f3c199a514a61ccb 113
+  0772616e6b48a76afb6c1458e193cbb3dae2e4ff dac7984588fc4eea7acbf39693a9c1b06f5b175d 0000000000000000000000000000000000000000 bac16991d12ff45f9dc43c52da1946dfadb83e80 dac7984588fc4eea7acbf39693a9c1b06f5b175d 113
+  eb498cd9af6c44108e43041e951ce829e29f6c80 bff2f4817ced57b386caf7c4e3e36a4bc9af7e93 0000000000000000000000000000000000000000 63476832d8ec6558cf9bbe3cbe0c757e5cf18043 0772616e6b48a76afb6c1458e193cbb3dae2e4ff 295
+  b15709c071ddd2d93188508ba156196ab4f19620 eb498cd9af6c44108e43041e951ce829e29f6c80 0000000000000000000000000000000000000000 13c0170174366b441dc68e8e33757232fa744458 eb498cd9af6c44108e43041e951ce829e29f6c80 114
+  
+  mf
+  4f73f97080266ab8e0c0561ca8d0da3eaf65b695 301ca08d026bb72cb4258a9d211bdf7ca0bcd810 0000000000000000000000000000000000000000 ff42371d57168345fdf1a3aac66a51f6a45d41d2 301ca08d026bb72cb4258a9d211bdf7ca0bcd810 17
+  c7b583de053293870e145f45bd2d61643563fd06 4f73f97080266ab8e0c0561ca8d0da3eaf65b695 0000000000000000000000000000000000000000 bac16991d12ff45f9dc43c52da1946dfadb83e80 4f73f97080266ab8e0c0561ca8d0da3eaf65b695 18
+  266ee3c0302a5a18f1cf96817ac79a51836179e9 edc0f6b8db80d68ae6aff2b19f7e5347ab68fa63 0000000000000000000000000000000000000000 63476832d8ec6558cf9bbe3cbe0c757e5cf18043 c7b583de053293870e145f45bd2d61643563fd06 149
+  698c6a36220548cd3903ca7dada27c59aa500c52 266ee3c0302a5a18f1cf96817ac79a51836179e9 0000000000000000000000000000000000000000 13c0170174366b441dc68e8e33757232fa744458 266ee3c0302a5a18f1cf96817ac79a51836179e9 19
+  
+  nf11
+  33fbc651630ffa7ccbebfe4eb91320a873e7291c 0000000000000000000000000000000000000000 0000000000000000000000000000000000000000 63476832d8ec6558cf9bbe3cbe0c757e5cf18043 0000000000000000000000000000000000000000 16
+  
+  nf12
+  ddce0544363f037e9fb889faca058f52dc01c0a5 0000000000000000000000000000000000000000 0000000000000000000000000000000000000000 13c0170174366b441dc68e8e33757232fa744458 0000000000000000000000000000000000000000 16
+  
+  nf4
+  3c1407305701051cbed9f9cb9a68bdfb5997c235 0000000000000000000000000000000000000000 0000000000000000000000000000000000000000 ff42371d57168345fdf1a3aac66a51f6a45d41d2 0000000000000000000000000000000000000000 15
+  
+  nf5
+  0dbd89c185f53a1727c54cd1ce256482fa23968e 0000000000000000000000000000000000000000 0000000000000000000000000000000000000000 bac16991d12ff45f9dc43c52da1946dfadb83e80 0000000000000000000000000000000000000000 15
+
+Verify we hit the HTTP server:
+
+  $ cat access.log
+  * - - [*] "GET /?cmd=capabilities HTTP/1.1" 200 - (glob)
+  * - - [*] "GET /?cmd=getbundle HTTP/1.1" 200 - (glob)
+  * - - [*] "GET /?cmd=capabilities HTTP/1.1" 200 - (glob)
+  * - - [*] "GET /?cmd=getbundle HTTP/1.1" 200 - x-hgarg-1:common=700b7e19db54103633c4bf4a6a6b6d55f4d50c03+d5f6e1ea452285324836a49d7d3c2a63cfed1d31&heads=13c0170174366b441dc68e8e33757232fa744458+bac16991d12ff45f9dc43c52da1946dfadb83e80 (glob)
+
+  $ cat error.log
+
--- a/tests/test-git-import.t	Wed Jun 01 16:32:48 2011 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,385 +0,0 @@
-
-  $ hg init
-
-New file:
-
-  $ hg import -d "1000000 0" -mnew - <<EOF
-  > diff --git a/new b/new
-  > new file mode 100644
-  > index 0000000..7898192
-  > --- /dev/null
-  > +++ b/new
-  > @@ -0,0 +1 @@
-  > +a
-  > EOF
-  applying patch from stdin
-
-  $ hg tip -q
-  0:ae3ee40d2079
-
-New empty file:
-
-  $ hg import -d "1000000 0" -mempty - <<EOF
-  > diff --git a/empty b/empty
-  > new file mode 100644
-  > EOF
-  applying patch from stdin
-
-  $ hg tip -q
-  1:ab199dc869b5
-
-  $ hg locate empty
-  empty
-
-chmod +x:
-
-  $ hg import -d "1000000 0" -msetx - <<EOF
-  > diff --git a/new b/new
-  > old mode 100644
-  > new mode 100755
-  > EOF
-  applying patch from stdin
-
-  $ hg tip -q
-  2:3a34410f282e
-
-  $ test -x new
-
-Copy:
-
-  $ hg import -d "1000000 0" -mcopy - <<EOF
-  > diff --git a/new b/copy
-  > old mode 100755
-  > new mode 100644
-  > similarity index 100%
-  > copy from new
-  > copy to copy
-  > diff --git a/new b/copyx
-  > similarity index 100%
-  > copy from new
-  > copy to copyx
-  > EOF
-  applying patch from stdin
-
-  $ hg tip -q
-  3:37bacb7ca14d
-
-  $ if "$TESTDIR/hghave" -q execbit; then
-  >     test -f copy -a ! -x copy || echo bad
-  >     test -x copyx || echo bad
-  > else
-  >     test -f copy || echo bad
-  > fi
-
-  $ cat copy
-  a
-
-  $ hg cat copy
-  a
-
-Rename:
-
-  $ hg import -d "1000000 0" -mrename - <<EOF
-  > diff --git a/copy b/rename
-  > similarity index 100%
-  > rename from copy
-  > rename to rename
-  > EOF
-  applying patch from stdin
-
-  $ hg tip -q
-  4:47b81a94361d
-
-  $ hg locate
-  copyx
-  empty
-  new
-  rename
-
-Delete:
-
-  $ hg import -d "1000000 0" -mdelete - <<EOF
-  > diff --git a/copyx b/copyx
-  > deleted file mode 100755
-  > index 7898192..0000000
-  > --- a/copyx
-  > +++ /dev/null
-  > @@ -1 +0,0 @@
-  > -a
-  > EOF
-  applying patch from stdin
-
-  $ hg tip -q
-  5:d9b001d98336
-
-  $ hg locate
-  empty
-  new
-  rename
-
-  $ test -f copyx
-  [1]
-
-Regular diff:
-
-  $ hg import -d "1000000 0" -mregular - <<EOF
-  > diff --git a/rename b/rename
-  > index 7898192..72e1fe3 100644
-  > --- a/rename
-  > +++ b/rename
-  > @@ -1 +1,5 @@
-  >  a
-  > +a
-  > +a
-  > +a
-  > +a
-  > EOF
-  applying patch from stdin
-
-  $ hg tip -q
-  6:ebe901e7576b
-
-Copy and modify:
-
-  $ hg import -d "1000000 0" -mcopymod - <<EOF
-  > diff --git a/rename b/copy2
-  > similarity index 80%
-  > copy from rename
-  > copy to copy2
-  > index 72e1fe3..b53c148 100644
-  > --- a/rename
-  > +++ b/copy2
-  > @@ -1,5 +1,5 @@
-  >  a
-  >  a
-  > -a
-  > +b
-  >  a
-  >  a
-  > EOF
-  applying patch from stdin
-
-  $ hg tip -q
-  7:18f368958ecd
-
-  $ hg cat copy2
-  a
-  a
-  b
-  a
-  a
-
-Rename and modify:
-
-  $ hg import -d "1000000 0" -mrenamemod - <<EOF
-  > diff --git a/copy2 b/rename2
-  > similarity index 80%
-  > rename from copy2
-  > rename to rename2
-  > index b53c148..8f81e29 100644
-  > --- a/copy2
-  > +++ b/rename2
-  > @@ -1,5 +1,5 @@
-  >  a
-  >  a
-  >  b
-  > -a
-  > +c
-  >  a
-  > EOF
-  applying patch from stdin
-
-  $ hg tip -q
-  8:c32b0d7e6f44
-
-  $ hg locate copy2
-  [1]
-  $ hg cat rename2
-  a
-  a
-  b
-  c
-  a
-
-One file renamed multiple times:
-
-  $ hg import -d "1000000 0" -mmultirenames - <<EOF
-  > diff --git a/rename2 b/rename3
-  > rename from rename2
-  > rename to rename3
-  > diff --git a/rename2 b/rename3-2
-  > rename from rename2
-  > rename to rename3-2
-  > EOF
-  applying patch from stdin
-
-  $ hg tip -q
-  9:034a6bf95330
-
-  $ hg log -vr. --template '{rev} {files} / {file_copies}\n'
-  9 rename2 rename3 rename3-2 / rename3 (rename2)rename3-2 (rename2)
-
-  $ hg locate rename2 rename3 rename3-2
-  rename3
-  rename3-2
-
-  $ hg cat rename3
-  a
-  a
-  b
-  c
-  a
-
-  $ hg cat rename3-2
-  a
-  a
-  b
-  c
-  a
-
-  $ echo foo > foo
-  $ hg add foo
-  $ hg ci -m 'add foo'
-
-Binary files and regular patch hunks:
-
-  $ hg import -d "1000000 0" -m binaryregular - <<EOF
-  > diff --git a/binary b/binary
-  > new file mode 100644
-  > index 0000000000000000000000000000000000000000..593f4708db84ac8fd0f5cc47c634f38c013fe9e4
-  > GIT binary patch
-  > literal 4
-  > Lc\${NkU|;|M00aO5
-  > 
-  > diff --git a/foo b/foo2
-  > rename from foo
-  > rename to foo2
-  > EOF
-  applying patch from stdin
-
-  $ hg tip -q
-  11:c39bce63e786
-
-  $ cat foo2
-  foo
-
-  $ hg manifest --debug | grep binary
-  045c85ba38952325e126c70962cc0f9d9077bc67 644   binary
-
-Multiple binary files:
-
-  $ hg import -d "1000000 0" -m multibinary - <<EOF
-  > diff --git a/mbinary1 b/mbinary1
-  > new file mode 100644
-  > index 0000000000000000000000000000000000000000..593f4708db84ac8fd0f5cc47c634f38c013fe9e4
-  > GIT binary patch
-  > literal 4
-  > Lc\${NkU|;|M00aO5
-  > 
-  > diff --git a/mbinary2 b/mbinary2
-  > new file mode 100644
-  > index 0000000000000000000000000000000000000000..112363ac1917b417ffbd7f376ca786a1e5fa7490
-  > GIT binary patch
-  > literal 5
-  > Mc\${NkU|\`?^000jF3jhEB
-  > 
-  > EOF
-  applying patch from stdin
-
-  $ hg tip -q
-  12:30b530085242
-
-  $ hg manifest --debug | grep mbinary
-  045c85ba38952325e126c70962cc0f9d9077bc67 644   mbinary1
-  a874b471193996e7cb034bb301cac7bdaf3e3f46 644   mbinary2
-
-Filenames with spaces:
-
-  $ hg import -d "1000000 0" -m spaces - <<EOF
-  > diff --git a/foo bar b/foo bar
-  > new file mode 100644
-  > index 0000000..257cc56
-  > --- /dev/null
-  > +++ b/foo bar	
-  > @@ -0,0 +1 @@
-  > +foo
-  > EOF
-  applying patch from stdin
-
-  $ hg tip -q
-  13:04750ef42fb3
-
-  $ cat "foo bar"
-  foo
-
-Copy then modify the original file:
-
-  $ hg import -d "1000000 0" -m copy-mod-orig - <<EOF
-  > diff --git a/foo2 b/foo2
-  > index 257cc56..fe08ec6 100644
-  > --- a/foo2
-  > +++ b/foo2
-  > @@ -1 +1,2 @@
-  >  foo
-  > +new line
-  > diff --git a/foo2 b/foo3
-  > similarity index 100%
-  > copy from foo2
-  > copy to foo3
-  > EOF
-  applying patch from stdin
-
-  $ hg tip -q
-  14:c4cd9cdeaa74
-
-  $ cat foo3
-  foo
-
-Move text file and patch as binary
-
-  $ echo a > text2
-  $ hg ci -Am0
-  adding text2
-  $ hg import -d "1000000 0" -m rename-as-binary - <<"EOF"
-  > diff --git a/text2 b/binary2
-  > rename from text2
-  > rename to binary2
-  > index 78981922613b2afb6025042ff6bd878ac1994e85..10efcb362e9f3b3420fcfbfc0e37f3dc16e29757
-  > GIT binary patch
-  > literal 5
-  > Mc$`b*O5$Pw00T?_*Z=?k
-  > 
-  > EOF
-  applying patch from stdin
-
-  $ cat binary2
-  a
-  b
-  \x00 (no-eol) (esc)
-
-  $ hg st --copies --change . 
-  A binary2
-    text2
-  R text2
-  $ cd ..
-
-Consecutive import with renames (issue2459)
-
-  $ hg init issue2459
-  $ cd issue2459
-  $ hg import --no-commit --force - <<EOF
-  > diff --git a/a b/a
-  > new file mode 100644
-  > EOF
-  applying patch from stdin
-  $ hg import --no-commit --force - <<EOF
-  > diff --git a/a b/b
-  > rename from a
-  > rename to b
-  > EOF
-  applying patch from stdin
-  a has not been committed yet, so no copy data will be stored for b.
-  $ hg debugstate
-  a   0         -1 unset               b
-  $ hg ci -m done
-  $ cd ..
--- a/tests/test-globalopts.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-globalopts.t	Sat Jun 18 17:03:01 2011 -0500
@@ -28,6 +28,7 @@
   pulling from ../b
   searching for changes
   warning: repository is unrelated
+  requesting all changes
   adding changesets
   adding manifests
   adding file changes
@@ -83,13 +84,13 @@
   $ hg ann a/a a/a
   0: a
   $ hg ann a/a b/b
-  abort: There is no Mercurial repository here (.hg not found)!
+  abort: no repository found in '$TESTTMP' (.hg not found)!
   [255]
   $ hg -R b ann a/a
   abort: a/a not under root
   [255]
   $ hg log
-  abort: There is no Mercurial repository here (.hg not found)!
+  abort: no repository found in '$TESTTMP' (.hg not found)!
   [255]
 
 Abbreviation of long option:
@@ -315,7 +316,7 @@
    remove       remove the specified files on the next commit
    rename       rename files; equivalent of copy + remove
    resolve      redo merges or set/view the merge status of files
-   revert       restore individual files or directories to an earlier state
+   revert       restore files to their checkout state
    rollback     roll back the last transaction (dangerous)
    root         print the root (top) of the current working directory
    serve        start stand-alone webserver
@@ -334,22 +335,26 @@
   
    config       Configuration Files
    dates        Date Formats
-   patterns     File Name Patterns
+   diffs        Diff Formats
    environment  Environment Variables
-   revisions    Specifying Single Revisions
+   extensions   Using additional features
+   filesets     Specifying File Sets
+   glossary     Glossary
+   hgignore     syntax for Mercurial ignore files
+   hgweb        Configuring hgweb
+   merge-tools  Merge Tools
    multirevs    Specifying Multiple Revisions
+   patterns     File Name Patterns
+   revisions    Specifying Single Revisions
    revsets      Specifying Revision Sets
-   diffs        Diff Formats
-   merge-tools  Merge Tools
+   subrepos     Subrepositories
    templating   Template Usage
    urls         URL Paths
-   extensions   Using additional features
-   subrepos     Subrepositories
-   hgweb        Configuring hgweb
-   glossary     Glossary
   
   use "hg -v help" to show builtin aliases and global options
 
+
+
   $ hg --help
   Mercurial Distributed SCM
   
@@ -392,7 +397,7 @@
    remove       remove the specified files on the next commit
    rename       rename files; equivalent of copy + remove
    resolve      redo merges or set/view the merge status of files
-   revert       restore individual files or directories to an earlier state
+   revert       restore files to their checkout state
    rollback     roll back the last transaction (dangerous)
    root         print the root (top) of the current working directory
    serve        start stand-alone webserver
@@ -411,19 +416,21 @@
   
    config       Configuration Files
    dates        Date Formats
-   patterns     File Name Patterns
+   diffs        Diff Formats
    environment  Environment Variables
-   revisions    Specifying Single Revisions
+   extensions   Using additional features
+   filesets     Specifying File Sets
+   glossary     Glossary
+   hgignore     syntax for Mercurial ignore files
+   hgweb        Configuring hgweb
+   merge-tools  Merge Tools
    multirevs    Specifying Multiple Revisions
+   patterns     File Name Patterns
+   revisions    Specifying Single Revisions
    revsets      Specifying Revision Sets
-   diffs        Diff Formats
-   merge-tools  Merge Tools
+   subrepos     Subrepositories
    templating   Template Usage
    urls         URL Paths
-   extensions   Using additional features
-   subrepos     Subrepositories
-   hgweb        Configuring hgweb
-   glossary     Glossary
   
   use "hg -v help" to show builtin aliases and global options
 
--- a/tests/test-glog.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-glog.t	Sat Jun 18 17:03:01 2011 -0500
@@ -463,115 +463,115 @@
   | | |  date:        Thu Jan 01 00:00:32 1970 +0000
   | | |  summary:     (32) expand
   | | |
-  | o |  changeset:   31:621d83e11f67
-  | | |  parent:      21:d42a756af44d
-  | | |  parent:      30:6e11cd4b648f
-  | | |  user:        test
-  | | |  date:        Thu Jan 01 00:00:31 1970 +0000
-  | | |  summary:     (31) expand
-  | | |
-  | o |    changeset:   30:6e11cd4b648f
-  | |\ \   parent:      28:44ecd0b9ae99
-  | | | |  parent:      29:cd9bb2be7593
-  | | | |  user:        test
-  | | | |  date:        Thu Jan 01 00:00:30 1970 +0000
-  | | | |  summary:     (30) expand
-  | | | |
-  | | o |  changeset:   29:cd9bb2be7593
-  | | | |  parent:      0:e6eb3150255d
-  | | | |  user:        test
-  | | | |  date:        Thu Jan 01 00:00:29 1970 +0000
-  | | | |  summary:     (29) regular commit
-  | | | |
-  | o | |  changeset:   28:44ecd0b9ae99
-  | | | |  parent:      1:6db2ef61d156
-  | | | |  parent:      26:7f25b6c2f0b9
+  | o |    changeset:   31:621d83e11f67
+  | |\ \   parent:      21:d42a756af44d
+  | | | |  parent:      30:6e11cd4b648f
   | | | |  user:        test
-  | | | |  date:        Thu Jan 01 00:00:28 1970 +0000
-  | | | |  summary:     (28) merge zero known
-  | | | |
-  o | | |  changeset:   27:886ed638191b
-  | | | |  parent:      21:d42a756af44d
-  | | | |  user:        test
-  | | | |  date:        Thu Jan 01 00:00:27 1970 +0000
-  | | | |  summary:     (27) collapse
-  | | | |
-  | o | |  changeset:   26:7f25b6c2f0b9
-  | | | |  parent:      18:1aa84d96232a
-  | | | |  parent:      25:91da8ed57247
-  | | | |  user:        test
-  | | | |  date:        Thu Jan 01 00:00:26 1970 +0000
-  | | | |  summary:     (26) merge one known; far right
-  | | | |
-  | o | |  changeset:   25:91da8ed57247
-  | | | |  parent:      21:d42a756af44d
-  | | | |  parent:      24:a9c19a3d96b7
-  | | | |  user:        test
-  | | | |  date:        Thu Jan 01 00:00:25 1970 +0000
-  | | | |  summary:     (25) merge one known; far left
-  | | | |
-  | o | |  changeset:   24:a9c19a3d96b7
-  | | | |  parent:      0:e6eb3150255d
-  | | | |  parent:      23:a01cddf0766d
-  | | | |  user:        test
-  | | | |  date:        Thu Jan 01 00:00:24 1970 +0000
-  | | | |  summary:     (24) merge one known; immediate right
+  | | | |  date:        Thu Jan 01 00:00:31 1970 +0000
+  | | | |  summary:     (31) expand
   | | | |
-  | o | |  changeset:   23:a01cddf0766d
-  | | | |  parent:      1:6db2ef61d156
-  | | | |  parent:      22:e0d9cccacb5d
-  | | | |  user:        test
-  | | | |  date:        Thu Jan 01 00:00:23 1970 +0000
-  | | | |  summary:     (23) merge one known; immediate left
-  | | | |
-  | o | |  changeset:   22:e0d9cccacb5d
-  |/ / /   parent:      18:1aa84d96232a
-  | | |    parent:      21:d42a756af44d
-  | | |    user:        test
-  | | |    date:        Thu Jan 01 00:00:22 1970 +0000
-  | | |    summary:     (22) merge two known; one far left, one far right
-  | | |
-  o | |    changeset:   21:d42a756af44d
-  |\ \ \   parent:      19:31ddc2c1573b
-  | | | |  parent:      20:d30ed6450e32
-  | | | |  user:        test
-  | | | |  date:        Thu Jan 01 00:00:21 1970 +0000
-  | | | |  summary:     (21) expand
+  | | o |    changeset:   30:6e11cd4b648f
+  | | |\ \   parent:      28:44ecd0b9ae99
+  | | | | |  parent:      29:cd9bb2be7593
+  | | | | |  user:        test
+  | | | | |  date:        Thu Jan 01 00:00:30 1970 +0000
+  | | | | |  summary:     (30) expand
+  | | | | |
+  | | | o |  changeset:   29:cd9bb2be7593
+  | | | | |  parent:      0:e6eb3150255d
+  | | | | |  user:        test
+  | | | | |  date:        Thu Jan 01 00:00:29 1970 +0000
+  | | | | |  summary:     (29) regular commit
+  | | | | |
+  | | o | |    changeset:   28:44ecd0b9ae99
+  | | |\ \ \   parent:      1:6db2ef61d156
+  | | | | | |  parent:      26:7f25b6c2f0b9
+  | | | | | |  user:        test
+  | | | | | |  date:        Thu Jan 01 00:00:28 1970 +0000
+  | | | | | |  summary:     (28) merge zero known
+  | | | | | |
+  o | | | | |  changeset:   27:886ed638191b
+  |/ / / / /   parent:      21:d42a756af44d
+  | | | | |    user:        test
+  | | | | |    date:        Thu Jan 01 00:00:27 1970 +0000
+  | | | | |    summary:     (27) collapse
+  | | | | |
+  | | o---+  changeset:   26:7f25b6c2f0b9
+  | | | | |  parent:      18:1aa84d96232a
+  | | | | |  parent:      25:91da8ed57247
+  | | | | |  user:        test
+  | | | | |  date:        Thu Jan 01 00:00:26 1970 +0000
+  | | | | |  summary:     (26) merge one known; far right
+  | | | | |
+  +---o | |  changeset:   25:91da8ed57247
+  | | | | |  parent:      21:d42a756af44d
+  | | | | |  parent:      24:a9c19a3d96b7
+  | | | | |  user:        test
+  | | | | |  date:        Thu Jan 01 00:00:25 1970 +0000
+  | | | | |  summary:     (25) merge one known; far left
+  | | | | |
+  | | o | |  changeset:   24:a9c19a3d96b7
+  | | |\| |  parent:      0:e6eb3150255d
+  | | | | |  parent:      23:a01cddf0766d
+  | | | | |  user:        test
+  | | | | |  date:        Thu Jan 01 00:00:24 1970 +0000
+  | | | | |  summary:     (24) merge one known; immediate right
+  | | | | |
+  | | o | |  changeset:   23:a01cddf0766d
+  | |/| | |  parent:      1:6db2ef61d156
+  | | | | |  parent:      22:e0d9cccacb5d
+  | | | | |  user:        test
+  | | | | |  date:        Thu Jan 01 00:00:23 1970 +0000
+  | | | | |  summary:     (23) merge one known; immediate left
+  | | | | |
+  +---o---+  changeset:   22:e0d9cccacb5d
+  | |   | |  parent:      18:1aa84d96232a
+  | |  / /   parent:      21:d42a756af44d
+  | | | |    user:        test
+  | | | |    date:        Thu Jan 01 00:00:22 1970 +0000
+  | | | |    summary:     (22) merge two known; one far left, one far right
   | | | |
-  | o---+  changeset:   20:d30ed6450e32
-  |   | |  parent:      0:e6eb3150255d
-  |  / /   parent:      18:1aa84d96232a
-  | | |    user:        test
-  | | |    date:        Thu Jan 01 00:00:20 1970 +0000
-  | | |    summary:     (20) merge two known; two far right
-  | | |
-  o | |    changeset:   19:31ddc2c1573b
-  |\ \ \   parent:      15:1dda3f72782d
-  | | | |  parent:      17:44765d7c06e0
-  | | | |  user:        test
-  | | | |  date:        Thu Jan 01 00:00:19 1970 +0000
-  | | | |  summary:     (19) expand
+  o | | |    changeset:   21:d42a756af44d
+  |\ \ \ \   parent:      19:31ddc2c1573b
+  | | | | |  parent:      20:d30ed6450e32
+  | | | | |  user:        test
+  | | | | |  date:        Thu Jan 01 00:00:21 1970 +0000
+  | | | | |  summary:     (21) expand
+  | | | | |
+  | o---+-+  changeset:   20:d30ed6450e32
+  |   | | |  parent:      0:e6eb3150255d
+  |  / / /   parent:      18:1aa84d96232a
+  | | | |    user:        test
+  | | | |    date:        Thu Jan 01 00:00:20 1970 +0000
+  | | | |    summary:     (20) merge two known; two far right
   | | | |
-  +-----o  changeset:   18:1aa84d96232a
-  | | |    parent:      1:6db2ef61d156
-  | | |    parent:      15:1dda3f72782d
-  | | |    user:        test
-  | | |    date:        Thu Jan 01 00:00:18 1970 +0000
-  | | |    summary:     (18) merge two known; two far left
-  | | |
-  | o |    changeset:   17:44765d7c06e0
-  | |\ \   parent:      12:86b91144a6e9
-  | | | |  parent:      16:3677d192927d
-  | | | |  user:        test
-  | | | |  date:        Thu Jan 01 00:00:17 1970 +0000
-  | | | |  summary:     (17) expand
+  o | | |    changeset:   19:31ddc2c1573b
+  |\ \ \ \   parent:      15:1dda3f72782d
+  | | | | |  parent:      17:44765d7c06e0
+  | | | | |  user:        test
+  | | | | |  date:        Thu Jan 01 00:00:19 1970 +0000
+  | | | | |  summary:     (19) expand
+  | | | | |
+  +---+---o  changeset:   18:1aa84d96232a
+  | | | |    parent:      1:6db2ef61d156
+  | | | |    parent:      15:1dda3f72782d
+  | | | |    user:        test
+  | | | |    date:        Thu Jan 01 00:00:18 1970 +0000
+  | | | |    summary:     (18) merge two known; two far left
   | | | |
-  | | o |  changeset:   16:3677d192927d
-  | | | |  parent:      0:e6eb3150255d
-  | | | |  parent:      1:6db2ef61d156
-  | | | |  user:        test
-  | | | |  date:        Thu Jan 01 00:00:16 1970 +0000
-  | | | |  summary:     (16) merge two known; one immediate right, one near right
+  | o | |    changeset:   17:44765d7c06e0
+  | |\ \ \   parent:      12:86b91144a6e9
+  | | | | |  parent:      16:3677d192927d
+  | | | | |  user:        test
+  | | | | |  date:        Thu Jan 01 00:00:17 1970 +0000
+  | | | | |  summary:     (17) expand
+  | | | | |
+  | | o---+  changeset:   16:3677d192927d
+  | | | | |  parent:      0:e6eb3150255d
+  | | |/ /   parent:      1:6db2ef61d156
+  | | | |    user:        test
+  | | | |    date:        Thu Jan 01 00:00:16 1970 +0000
+  | | | |    summary:     (16) merge two known; one immediate right, one near right
   | | | |
   o | | |    changeset:   15:1dda3f72782d
   |\ \ \ \   parent:      13:22d8966a97e3
@@ -580,9 +580,9 @@
   | | | | |  date:        Thu Jan 01 00:00:15 1970 +0000
   | | | | |  summary:     (15) expand
   | | | | |
-  | o | | |  changeset:   14:8eac370358ef
-  | |/ / /   parent:      0:e6eb3150255d
-  | | | |    parent:      12:86b91144a6e9
+  | o-----+  changeset:   14:8eac370358ef
+  | | | | |  parent:      0:e6eb3150255d
+  | |/ / /   parent:      12:86b91144a6e9
   | | | |    user:        test
   | | | |    date:        Thu Jan 01 00:00:14 1970 +0000
   | | | |    summary:     (14) merge two known; one immediate right, one far right
@@ -595,72 +595,72 @@
   | | | | |  summary:     (13) expand
   | | | | |
   +---o | |  changeset:   12:86b91144a6e9
-  | |  / /   parent:      1:6db2ef61d156
+  | | |/ /   parent:      1:6db2ef61d156
   | | | |    parent:      9:7010c0af0a35
   | | | |    user:        test
   | | | |    date:        Thu Jan 01 00:00:12 1970 +0000
   | | | |    summary:     (12) merge two known; one immediate right, one far left
   | | | |
-  | o | |  changeset:   11:832d76e6bdf2
-  | | | |  parent:      6:b105a072e251
-  | | | |  parent:      10:74c64d036d72
-  | | | |  user:        test
-  | | | |  date:        Thu Jan 01 00:00:11 1970 +0000
-  | | | |  summary:     (11) expand
-  | | | |
-  | o | |  changeset:   10:74c64d036d72
-  | | | |  parent:      0:e6eb3150255d
-  | | | |  parent:      6:b105a072e251
-  | | | |  user:        test
-  | | | |  date:        Thu Jan 01 00:00:10 1970 +0000
-  | | | |  summary:     (10) merge two known; one immediate left, one near right
+  | o | |    changeset:   11:832d76e6bdf2
+  | |\ \ \   parent:      6:b105a072e251
+  | | | | |  parent:      10:74c64d036d72
+  | | | | |  user:        test
+  | | | | |  date:        Thu Jan 01 00:00:11 1970 +0000
+  | | | | |  summary:     (11) expand
+  | | | | |
+  | | o---+  changeset:   10:74c64d036d72
+  | | | | |  parent:      0:e6eb3150255d
+  | |/ / /   parent:      6:b105a072e251
+  | | | |    user:        test
+  | | | |    date:        Thu Jan 01 00:00:10 1970 +0000
+  | | | |    summary:     (10) merge two known; one immediate left, one near right
   | | | |
-  o | | |  changeset:   9:7010c0af0a35
-  | | | |  parent:      7:b632bb1b1224
-  | | | |  parent:      8:7a0b11f71937
-  | | | |  user:        test
-  | | | |  date:        Thu Jan 01 00:00:09 1970 +0000
-  | | | |  summary:     (9) expand
-  | | | |
-  o | | |  changeset:   8:7a0b11f71937
-  | | | |  parent:      0:e6eb3150255d
-  | | | |  parent:      7:b632bb1b1224
-  | | | |  user:        test
-  | | | |  date:        Thu Jan 01 00:00:08 1970 +0000
-  | | | |  summary:     (8) merge two known; one immediate left, one far right
+  o | | |    changeset:   9:7010c0af0a35
+  |\ \ \ \   parent:      7:b632bb1b1224
+  | | | | |  parent:      8:7a0b11f71937
+  | | | | |  user:        test
+  | | | | |  date:        Thu Jan 01 00:00:09 1970 +0000
+  | | | | |  summary:     (9) expand
+  | | | | |
+  | o-----+  changeset:   8:7a0b11f71937
+  | | | | |  parent:      0:e6eb3150255d
+  |/ / / /   parent:      7:b632bb1b1224
+  | | | |    user:        test
+  | | | |    date:        Thu Jan 01 00:00:08 1970 +0000
+  | | | |    summary:     (8) merge two known; one immediate left, one far right
   | | | |
-  o | | |  changeset:   7:b632bb1b1224
-  | | | |  parent:      2:3d9a33b8d1e1
-  | | | |  parent:      5:4409d547b708
-  | | | |  user:        test
-  | | | |  date:        Thu Jan 01 00:00:07 1970 +0000
-  | | | |  summary:     (7) expand
+  o | | |    changeset:   7:b632bb1b1224
+  |\ \ \ \   parent:      2:3d9a33b8d1e1
+  | | | | |  parent:      5:4409d547b708
+  | | | | |  user:        test
+  | | | | |  date:        Thu Jan 01 00:00:07 1970 +0000
+  | | | | |  summary:     (7) expand
+  | | | | |
+  +---o | |  changeset:   6:b105a072e251
+  | |/ / /   parent:      2:3d9a33b8d1e1
+  | | | |    parent:      5:4409d547b708
+  | | | |    user:        test
+  | | | |    date:        Thu Jan 01 00:00:06 1970 +0000
+  | | | |    summary:     (6) merge two known; one immediate left, one far left
   | | | |
-  | o | |  changeset:   6:b105a072e251
-  |/ / /   parent:      2:3d9a33b8d1e1
-  | | |    parent:      5:4409d547b708
-  | | |    user:        test
-  | | |    date:        Thu Jan 01 00:00:06 1970 +0000
-  | | |    summary:     (6) merge two known; one immediate left, one far left
-  | | |
-  o | |  changeset:   5:4409d547b708
-  | | |  parent:      3:27eef8ed80b4
-  | | |  parent:      4:26a8bac39d9f
-  | | |  user:        test
-  | | |  date:        Thu Jan 01 00:00:05 1970 +0000
-  | | |  summary:     (5) expand
-  | | |
-  o | |  changeset:   4:26a8bac39d9f
-  | | |  parent:      1:6db2ef61d156
-  | | |  parent:      3:27eef8ed80b4
-  | | |  user:        test
-  | | |  date:        Thu Jan 01 00:00:04 1970 +0000
-  | | |  summary:     (4) merge two known; one immediate left, one immediate right
-  | | |
-  o | |  changeset:   3:27eef8ed80b4
-  | | |  user:        test
-  | | |  date:        Thu Jan 01 00:00:03 1970 +0000
-  | | |  summary:     (3) collapse
+  | o | |    changeset:   5:4409d547b708
+  | |\ \ \   parent:      3:27eef8ed80b4
+  | | | | |  parent:      4:26a8bac39d9f
+  | | | | |  user:        test
+  | | | | |  date:        Thu Jan 01 00:00:05 1970 +0000
+  | | | | |  summary:     (5) expand
+  | | | | |
+  | | o | |  changeset:   4:26a8bac39d9f
+  | |/|/ /   parent:      1:6db2ef61d156
+  | | | |    parent:      3:27eef8ed80b4
+  | | | |    user:        test
+  | | | |    date:        Thu Jan 01 00:00:04 1970 +0000
+  | | | |    summary:     (4) merge two known; one immediate left, one immediate right
+  | | | |
+  | o | |  changeset:   3:27eef8ed80b4
+  |/ / /   user:        test
+  | | |    date:        Thu Jan 01 00:00:03 1970 +0000
+  | | |    summary:     (3) collapse
   | | |
   o | |  changeset:   2:3d9a33b8d1e1
   |/ /   user:        test
@@ -678,18 +678,438 @@
      summary:     (0) root
   
 
-Unused arguments:
-  $ hg glog -q foo bar
-  hg glog: invalid arguments
-  hg glog [OPTION]... [FILE]
+File glog per revset:
+
+  $ hg glog -r 'file("a")'
+  @  changeset:   34:fea3ac5810e0
+  |  tag:         tip
+  |  parent:      32:d06dffa21a31
+  |  user:        test
+  |  date:        Thu Jan 01 00:00:34 1970 +0000
+  |  summary:     (34) head
+  |
+  | o  changeset:   33:68608f5145f9
+  | |  parent:      18:1aa84d96232a
+  | |  user:        test
+  | |  date:        Thu Jan 01 00:00:33 1970 +0000
+  | |  summary:     (33) head
+  | |
+  o |    changeset:   32:d06dffa21a31
+  |\ \   parent:      27:886ed638191b
+  | | |  parent:      31:621d83e11f67
+  | | |  user:        test
+  | | |  date:        Thu Jan 01 00:00:32 1970 +0000
+  | | |  summary:     (32) expand
+  | | |
+  | o |    changeset:   31:621d83e11f67
+  | |\ \   parent:      21:d42a756af44d
+  | | | |  parent:      30:6e11cd4b648f
+  | | | |  user:        test
+  | | | |  date:        Thu Jan 01 00:00:31 1970 +0000
+  | | | |  summary:     (31) expand
+  | | | |
+  | | o |    changeset:   30:6e11cd4b648f
+  | | |\ \   parent:      28:44ecd0b9ae99
+  | | | | |  parent:      29:cd9bb2be7593
+  | | | | |  user:        test
+  | | | | |  date:        Thu Jan 01 00:00:30 1970 +0000
+  | | | | |  summary:     (30) expand
+  | | | | |
+  | | | o |  changeset:   29:cd9bb2be7593
+  | | | | |  parent:      0:e6eb3150255d
+  | | | | |  user:        test
+  | | | | |  date:        Thu Jan 01 00:00:29 1970 +0000
+  | | | | |  summary:     (29) regular commit
+  | | | | |
+  | | o | |    changeset:   28:44ecd0b9ae99
+  | | |\ \ \   parent:      1:6db2ef61d156
+  | | | | | |  parent:      26:7f25b6c2f0b9
+  | | | | | |  user:        test
+  | | | | | |  date:        Thu Jan 01 00:00:28 1970 +0000
+  | | | | | |  summary:     (28) merge zero known
+  | | | | | |
+  o | | | | |  changeset:   27:886ed638191b
+  |/ / / / /   parent:      21:d42a756af44d
+  | | | | |    user:        test
+  | | | | |    date:        Thu Jan 01 00:00:27 1970 +0000
+  | | | | |    summary:     (27) collapse
+  | | | | |
+  | | o---+  changeset:   26:7f25b6c2f0b9
+  | | | | |  parent:      18:1aa84d96232a
+  | | | | |  parent:      25:91da8ed57247
+  | | | | |  user:        test
+  | | | | |  date:        Thu Jan 01 00:00:26 1970 +0000
+  | | | | |  summary:     (26) merge one known; far right
+  | | | | |
+  +---o | |  changeset:   25:91da8ed57247
+  | | | | |  parent:      21:d42a756af44d
+  | | | | |  parent:      24:a9c19a3d96b7
+  | | | | |  user:        test
+  | | | | |  date:        Thu Jan 01 00:00:25 1970 +0000
+  | | | | |  summary:     (25) merge one known; far left
+  | | | | |
+  | | o | |  changeset:   24:a9c19a3d96b7
+  | | |\| |  parent:      0:e6eb3150255d
+  | | | | |  parent:      23:a01cddf0766d
+  | | | | |  user:        test
+  | | | | |  date:        Thu Jan 01 00:00:24 1970 +0000
+  | | | | |  summary:     (24) merge one known; immediate right
+  | | | | |
+  | | o | |  changeset:   23:a01cddf0766d
+  | |/| | |  parent:      1:6db2ef61d156
+  | | | | |  parent:      22:e0d9cccacb5d
+  | | | | |  user:        test
+  | | | | |  date:        Thu Jan 01 00:00:23 1970 +0000
+  | | | | |  summary:     (23) merge one known; immediate left
+  | | | | |
+  +---o---+  changeset:   22:e0d9cccacb5d
+  | |   | |  parent:      18:1aa84d96232a
+  | |  / /   parent:      21:d42a756af44d
+  | | | |    user:        test
+  | | | |    date:        Thu Jan 01 00:00:22 1970 +0000
+  | | | |    summary:     (22) merge two known; one far left, one far right
+  | | | |
+  o | | |    changeset:   21:d42a756af44d
+  |\ \ \ \   parent:      19:31ddc2c1573b
+  | | | | |  parent:      20:d30ed6450e32
+  | | | | |  user:        test
+  | | | | |  date:        Thu Jan 01 00:00:21 1970 +0000
+  | | | | |  summary:     (21) expand
+  | | | | |
+  | o---+-+  changeset:   20:d30ed6450e32
+  |   | | |  parent:      0:e6eb3150255d
+  |  / / /   parent:      18:1aa84d96232a
+  | | | |    user:        test
+  | | | |    date:        Thu Jan 01 00:00:20 1970 +0000
+  | | | |    summary:     (20) merge two known; two far right
+  | | | |
+  o | | |    changeset:   19:31ddc2c1573b
+  |\ \ \ \   parent:      15:1dda3f72782d
+  | | | | |  parent:      17:44765d7c06e0
+  | | | | |  user:        test
+  | | | | |  date:        Thu Jan 01 00:00:19 1970 +0000
+  | | | | |  summary:     (19) expand
+  | | | | |
+  +---+---o  changeset:   18:1aa84d96232a
+  | | | |    parent:      1:6db2ef61d156
+  | | | |    parent:      15:1dda3f72782d
+  | | | |    user:        test
+  | | | |    date:        Thu Jan 01 00:00:18 1970 +0000
+  | | | |    summary:     (18) merge two known; two far left
+  | | | |
+  | o | |    changeset:   17:44765d7c06e0
+  | |\ \ \   parent:      12:86b91144a6e9
+  | | | | |  parent:      16:3677d192927d
+  | | | | |  user:        test
+  | | | | |  date:        Thu Jan 01 00:00:17 1970 +0000
+  | | | | |  summary:     (17) expand
+  | | | | |
+  | | o---+  changeset:   16:3677d192927d
+  | | | | |  parent:      0:e6eb3150255d
+  | | |/ /   parent:      1:6db2ef61d156
+  | | | |    user:        test
+  | | | |    date:        Thu Jan 01 00:00:16 1970 +0000
+  | | | |    summary:     (16) merge two known; one immediate right, one near right
+  | | | |
+  o | | |    changeset:   15:1dda3f72782d
+  |\ \ \ \   parent:      13:22d8966a97e3
+  | | | | |  parent:      14:8eac370358ef
+  | | | | |  user:        test
+  | | | | |  date:        Thu Jan 01 00:00:15 1970 +0000
+  | | | | |  summary:     (15) expand
+  | | | | |
+  | o-----+  changeset:   14:8eac370358ef
+  | | | | |  parent:      0:e6eb3150255d
+  | |/ / /   parent:      12:86b91144a6e9
+  | | | |    user:        test
+  | | | |    date:        Thu Jan 01 00:00:14 1970 +0000
+  | | | |    summary:     (14) merge two known; one immediate right, one far right
+  | | | |
+  o | | |    changeset:   13:22d8966a97e3
+  |\ \ \ \   parent:      9:7010c0af0a35
+  | | | | |  parent:      11:832d76e6bdf2
+  | | | | |  user:        test
+  | | | | |  date:        Thu Jan 01 00:00:13 1970 +0000
+  | | | | |  summary:     (13) expand
+  | | | | |
+  +---o | |  changeset:   12:86b91144a6e9
+  | | |/ /   parent:      1:6db2ef61d156
+  | | | |    parent:      9:7010c0af0a35
+  | | | |    user:        test
+  | | | |    date:        Thu Jan 01 00:00:12 1970 +0000
+  | | | |    summary:     (12) merge two known; one immediate right, one far left
+  | | | |
+  | o | |    changeset:   11:832d76e6bdf2
+  | |\ \ \   parent:      6:b105a072e251
+  | | | | |  parent:      10:74c64d036d72
+  | | | | |  user:        test
+  | | | | |  date:        Thu Jan 01 00:00:11 1970 +0000
+  | | | | |  summary:     (11) expand
+  | | | | |
+  | | o---+  changeset:   10:74c64d036d72
+  | | | | |  parent:      0:e6eb3150255d
+  | |/ / /   parent:      6:b105a072e251
+  | | | |    user:        test
+  | | | |    date:        Thu Jan 01 00:00:10 1970 +0000
+  | | | |    summary:     (10) merge two known; one immediate left, one near right
+  | | | |
+  o | | |    changeset:   9:7010c0af0a35
+  |\ \ \ \   parent:      7:b632bb1b1224
+  | | | | |  parent:      8:7a0b11f71937
+  | | | | |  user:        test
+  | | | | |  date:        Thu Jan 01 00:00:09 1970 +0000
+  | | | | |  summary:     (9) expand
+  | | | | |
+  | o-----+  changeset:   8:7a0b11f71937
+  | | | | |  parent:      0:e6eb3150255d
+  |/ / / /   parent:      7:b632bb1b1224
+  | | | |    user:        test
+  | | | |    date:        Thu Jan 01 00:00:08 1970 +0000
+  | | | |    summary:     (8) merge two known; one immediate left, one far right
+  | | | |
+  o | | |    changeset:   7:b632bb1b1224
+  |\ \ \ \   parent:      2:3d9a33b8d1e1
+  | | | | |  parent:      5:4409d547b708
+  | | | | |  user:        test
+  | | | | |  date:        Thu Jan 01 00:00:07 1970 +0000
+  | | | | |  summary:     (7) expand
+  | | | | |
+  +---o | |  changeset:   6:b105a072e251
+  | |/ / /   parent:      2:3d9a33b8d1e1
+  | | | |    parent:      5:4409d547b708
+  | | | |    user:        test
+  | | | |    date:        Thu Jan 01 00:00:06 1970 +0000
+  | | | |    summary:     (6) merge two known; one immediate left, one far left
+  | | | |
+  | o | |    changeset:   5:4409d547b708
+  | |\ \ \   parent:      3:27eef8ed80b4
+  | | | | |  parent:      4:26a8bac39d9f
+  | | | | |  user:        test
+  | | | | |  date:        Thu Jan 01 00:00:05 1970 +0000
+  | | | | |  summary:     (5) expand
+  | | | | |
+  | | o | |  changeset:   4:26a8bac39d9f
+  | |/|/ /   parent:      1:6db2ef61d156
+  | | | |    parent:      3:27eef8ed80b4
+  | | | |    user:        test
+  | | | |    date:        Thu Jan 01 00:00:04 1970 +0000
+  | | | |    summary:     (4) merge two known; one immediate left, one immediate right
+  | | | |
+  | o | |  changeset:   3:27eef8ed80b4
+  |/ / /   user:        test
+  | | |    date:        Thu Jan 01 00:00:03 1970 +0000
+  | | |    summary:     (3) collapse
+  | | |
+  o | |  changeset:   2:3d9a33b8d1e1
+  |/ /   user:        test
+  | |    date:        Thu Jan 01 00:00:02 1970 +0000
+  | |    summary:     (2) collapse
+  | |
+  o |  changeset:   1:6db2ef61d156
+  |/   user:        test
+  |    date:        Thu Jan 01 00:00:01 1970 +0000
+  |    summary:     (1) collapse
+  |
+  o  changeset:   0:e6eb3150255d
+     user:        test
+     date:        Thu Jan 01 00:00:00 1970 +0000
+     summary:     (0) root
   
-  show revision history alongside an ASCII revision graph
-  [255]
+
+
+File glog per revset (only merges):
 
-Only one file is allowed:
-  $ hg log -G foo bar
-  abort: --graph option allows at most one file
-  [255]
+  $ hg log -G -r 'file("a")' -m
+  o    changeset:   32:d06dffa21a31
+  |\   parent:      27:886ed638191b
+  | |  parent:      31:621d83e11f67
+  | |  user:        test
+  | |  date:        Thu Jan 01 00:00:32 1970 +0000
+  | |  summary:     (32) expand
+  | |
+  o |  changeset:   31:621d83e11f67
+  |\|  parent:      21:d42a756af44d
+  | |  parent:      30:6e11cd4b648f
+  | |  user:        test
+  | |  date:        Thu Jan 01 00:00:31 1970 +0000
+  | |  summary:     (31) expand
+  | |
+  o |    changeset:   30:6e11cd4b648f
+  |\ \   parent:      28:44ecd0b9ae99
+  | | |  parent:      29:cd9bb2be7593
+  | | |  user:        test
+  | | |  date:        Thu Jan 01 00:00:30 1970 +0000
+  | | |  summary:     (30) expand
+  | | |
+  o | |    changeset:   28:44ecd0b9ae99
+  |\ \ \   parent:      1:6db2ef61d156
+  | | | |  parent:      26:7f25b6c2f0b9
+  | | | |  user:        test
+  | | | |  date:        Thu Jan 01 00:00:28 1970 +0000
+  | | | |  summary:     (28) merge zero known
+  | | | |
+  o | | |    changeset:   26:7f25b6c2f0b9
+  |\ \ \ \   parent:      18:1aa84d96232a
+  | | | | |  parent:      25:91da8ed57247
+  | | | | |  user:        test
+  | | | | |  date:        Thu Jan 01 00:00:26 1970 +0000
+  | | | | |  summary:     (26) merge one known; far right
+  | | | | |
+  | o-----+  changeset:   25:91da8ed57247
+  | | | | |  parent:      21:d42a756af44d
+  | | | | |  parent:      24:a9c19a3d96b7
+  | | | | |  user:        test
+  | | | | |  date:        Thu Jan 01 00:00:25 1970 +0000
+  | | | | |  summary:     (25) merge one known; far left
+  | | | | |
+  | o | | |    changeset:   24:a9c19a3d96b7
+  | |\ \ \ \   parent:      0:e6eb3150255d
+  | | | | | |  parent:      23:a01cddf0766d
+  | | | | | |  user:        test
+  | | | | | |  date:        Thu Jan 01 00:00:24 1970 +0000
+  | | | | | |  summary:     (24) merge one known; immediate right
+  | | | | | |
+  | o---+ | |  changeset:   23:a01cddf0766d
+  | | | | | |  parent:      1:6db2ef61d156
+  | | | | | |  parent:      22:e0d9cccacb5d
+  | | | | | |  user:        test
+  | | | | | |  date:        Thu Jan 01 00:00:23 1970 +0000
+  | | | | | |  summary:     (23) merge one known; immediate left
+  | | | | | |
+  | o-------+  changeset:   22:e0d9cccacb5d
+  | | | | | |  parent:      18:1aa84d96232a
+  |/ / / / /   parent:      21:d42a756af44d
+  | | | | |    user:        test
+  | | | | |    date:        Thu Jan 01 00:00:22 1970 +0000
+  | | | | |    summary:     (22) merge two known; one far left, one far right
+  | | | | |
+  | | | | o    changeset:   21:d42a756af44d
+  | | | | |\   parent:      19:31ddc2c1573b
+  | | | | | |  parent:      20:d30ed6450e32
+  | | | | | |  user:        test
+  | | | | | |  date:        Thu Jan 01 00:00:21 1970 +0000
+  | | | | | |  summary:     (21) expand
+  | | | | | |
+  +-+-------o  changeset:   20:d30ed6450e32
+  | | | | |    parent:      0:e6eb3150255d
+  | | | | |    parent:      18:1aa84d96232a
+  | | | | |    user:        test
+  | | | | |    date:        Thu Jan 01 00:00:20 1970 +0000
+  | | | | |    summary:     (20) merge two known; two far right
+  | | | | |
+  | | | | o    changeset:   19:31ddc2c1573b
+  | | | | |\   parent:      15:1dda3f72782d
+  | | | | | |  parent:      17:44765d7c06e0
+  | | | | | |  user:        test
+  | | | | | |  date:        Thu Jan 01 00:00:19 1970 +0000
+  | | | | | |  summary:     (19) expand
+  | | | | | |
+  o---+---+ |  changeset:   18:1aa84d96232a
+    | | | | |  parent:      1:6db2ef61d156
+   / / / / /   parent:      15:1dda3f72782d
+  | | | | |    user:        test
+  | | | | |    date:        Thu Jan 01 00:00:18 1970 +0000
+  | | | | |    summary:     (18) merge two known; two far left
+  | | | | |
+  | | | | o    changeset:   17:44765d7c06e0
+  | | | | |\   parent:      12:86b91144a6e9
+  | | | | | |  parent:      16:3677d192927d
+  | | | | | |  user:        test
+  | | | | | |  date:        Thu Jan 01 00:00:17 1970 +0000
+  | | | | | |  summary:     (17) expand
+  | | | | | |
+  +-+-------o  changeset:   16:3677d192927d
+  | | | | |    parent:      0:e6eb3150255d
+  | | | | |    parent:      1:6db2ef61d156
+  | | | | |    user:        test
+  | | | | |    date:        Thu Jan 01 00:00:16 1970 +0000
+  | | | | |    summary:     (16) merge two known; one immediate right, one near right
+  | | | | |
+  | | | o |    changeset:   15:1dda3f72782d
+  | | | |\ \   parent:      13:22d8966a97e3
+  | | | | | |  parent:      14:8eac370358ef
+  | | | | | |  user:        test
+  | | | | | |  date:        Thu Jan 01 00:00:15 1970 +0000
+  | | | | | |  summary:     (15) expand
+  | | | | | |
+  +-------o |  changeset:   14:8eac370358ef
+  | | | | |/   parent:      0:e6eb3150255d
+  | | | | |    parent:      12:86b91144a6e9
+  | | | | |    user:        test
+  | | | | |    date:        Thu Jan 01 00:00:14 1970 +0000
+  | | | | |    summary:     (14) merge two known; one immediate right, one far right
+  | | | | |
+  | | | o |    changeset:   13:22d8966a97e3
+  | | | |\ \   parent:      9:7010c0af0a35
+  | | | | | |  parent:      11:832d76e6bdf2
+  | | | | | |  user:        test
+  | | | | | |  date:        Thu Jan 01 00:00:13 1970 +0000
+  | | | | | |  summary:     (13) expand
+  | | | | | |
+  | +---+---o  changeset:   12:86b91144a6e9
+  | | | | |    parent:      1:6db2ef61d156
+  | | | | |    parent:      9:7010c0af0a35
+  | | | | |    user:        test
+  | | | | |    date:        Thu Jan 01 00:00:12 1970 +0000
+  | | | | |    summary:     (12) merge two known; one immediate right, one far left
+  | | | | |
+  | | | | o    changeset:   11:832d76e6bdf2
+  | | | | |\   parent:      6:b105a072e251
+  | | | | | |  parent:      10:74c64d036d72
+  | | | | | |  user:        test
+  | | | | | |  date:        Thu Jan 01 00:00:11 1970 +0000
+  | | | | | |  summary:     (11) expand
+  | | | | | |
+  +---------o  changeset:   10:74c64d036d72
+  | | | | |/   parent:      0:e6eb3150255d
+  | | | | |    parent:      6:b105a072e251
+  | | | | |    user:        test
+  | | | | |    date:        Thu Jan 01 00:00:10 1970 +0000
+  | | | | |    summary:     (10) merge two known; one immediate left, one near right
+  | | | | |
+  | | | o |    changeset:   9:7010c0af0a35
+  | | | |\ \   parent:      7:b632bb1b1224
+  | | | | | |  parent:      8:7a0b11f71937
+  | | | | | |  user:        test
+  | | | | | |  date:        Thu Jan 01 00:00:09 1970 +0000
+  | | | | | |  summary:     (9) expand
+  | | | | | |
+  +-------o |  changeset:   8:7a0b11f71937
+  | | | |/ /   parent:      0:e6eb3150255d
+  | | | | |    parent:      7:b632bb1b1224
+  | | | | |    user:        test
+  | | | | |    date:        Thu Jan 01 00:00:08 1970 +0000
+  | | | | |    summary:     (8) merge two known; one immediate left, one far right
+  | | | | |
+  | | | o |    changeset:   7:b632bb1b1224
+  | | | |\ \   parent:      2:3d9a33b8d1e1
+  | | | | | |  parent:      5:4409d547b708
+  | | | | | |  user:        test
+  | | | | | |  date:        Thu Jan 01 00:00:07 1970 +0000
+  | | | | | |  summary:     (7) expand
+  | | | | | |
+  | | | +---o  changeset:   6:b105a072e251
+  | | | | |/   parent:      2:3d9a33b8d1e1
+  | | | | |    parent:      5:4409d547b708
+  | | | | |    user:        test
+  | | | | |    date:        Thu Jan 01 00:00:06 1970 +0000
+  | | | | |    summary:     (6) merge two known; one immediate left, one far left
+  | | | | |
+  | | | o |    changeset:   5:4409d547b708
+  | | | |\ \   parent:      3:27eef8ed80b4
+  | | | | | |  parent:      4:26a8bac39d9f
+  | | | | | |  user:        test
+  | | | | | |  date:        Thu Jan 01 00:00:05 1970 +0000
+  | | | | | |  summary:     (5) expand
+  | | | | | |
+  | +---o | |  changeset:   4:26a8bac39d9f
+  | | | |/ /   parent:      1:6db2ef61d156
+  | | | | |    parent:      3:27eef8ed80b4
+  | | | | |    user:        test
+  | | | | |    date:        Thu Jan 01 00:00:04 1970 +0000
+  | | | | |    summary:     (4) merge two known; one immediate left, one immediate right
+  | | | | |
+
 
 Empty revision range - display nothing:
   $ hg glog -r 1..0
@@ -733,10 +1153,10 @@
   |  summary:     more
   |
   o  changeset:   1:5ac72c0599bf
-     user:        test
-     date:        Thu Jan 01 00:00:00 1970 +0000
-     summary:     two
-  
+  |  user:        test
+  |  date:        Thu Jan 01 00:00:00 1970 +0000
+  |  summary:     two
+  |
 
 Issue1896: File log with explicit style
   $ hg glog --style=default one
@@ -868,7 +1288,26 @@
   | | |  summary:     (32) expand
   | | |
 
+Point out a common and an uncommon unshown parent
+
+  $ hg glog -r 'rev(8) or rev(9)'
+  o    changeset:   9:7010c0af0a35
+  |\   parent:      7:b632bb1b1224
+  | |  parent:      8:7a0b11f71937
+  | |  user:        test
+  | |  date:        Thu Jan 01 00:00:09 1970 +0000
+  | |  summary:     (9) expand
+  | |
+  o |  changeset:   8:7a0b11f71937
+  |\|  parent:      0:e6eb3150255d
+  | |  parent:      7:b632bb1b1224
+  | |  user:        test
+  | |  date:        Thu Jan 01 00:00:08 1970 +0000
+  | |  summary:     (8) merge two known; one immediate left, one far right
+  | |
+
 File + limit + -ra:b, b < tip:
+
   $ hg glog -l1 -r32:34 a
   o  changeset:   34:fea3ac5810e0
   |  parent:      32:d06dffa21a31
@@ -877,7 +1316,33 @@
   |  summary:     (34) head
   |
 
+file(File) + limit + -ra:b, b < tip:
+
+  $ hg glog -l1 -r32:34 -r 'file("a")'
+  o  changeset:   34:fea3ac5810e0
+  |  parent:      32:d06dffa21a31
+  |  user:        test
+  |  date:        Thu Jan 01 00:00:34 1970 +0000
+  |  summary:     (34) head
+  |
+
+limit(file(File) and a::b), b < tip:
+
+  $ hg glog -r 'limit(file("a") and 32::34, 1)'
+  o    changeset:   32:d06dffa21a31
+  |\   parent:      27:886ed638191b
+  | |  parent:      31:621d83e11f67
+  | |  user:        test
+  | |  date:        Thu Jan 01 00:00:32 1970 +0000
+  | |  summary:     (32) expand
+  | |
+
+File + limit + -ra:b, b < tip:
+
+  $ hg glog -r 'limit(file("a") and 34::32, 1)'
+
 File + limit + -ra:b, b < tip, (b - a) < limit:
+
   $ hg glog -l10 -r33:34 a
   o  changeset:   34:fea3ac5810e0
   |  parent:      32:d06dffa21a31
@@ -928,3 +1393,79 @@
   | | |  date:        Thu Jan 01 00:00:32 1970 +0000
   | | |  summary:     (32) expand
   | | |
+
+Test log -G options
+
+  $ hg log -G -u 'something nice'
+  $ hg log -G -b 'something nice'
+  abort: unknown revision 'something nice'!
+  [255]
+  $ hg log -G -k 'something nice'
+  $ hg log -G --only-branch 'something nice'
+  abort: unknown revision 'something nice'!
+  [255]
+  $ hg log -G --include 'some file' --exclude 'another file'
+  $ hg log -G --follow  --template 'nodetag {rev}\n' | grep nodetag | wc -l
+  \s*36 (re)
+  $ hg log -G --removed --template 'nodetag {rev}\n' | grep nodetag | wc -l
+  \s*0 (re)
+  $ hg log -G --only-merges --template 'nodetag {rev}\n' | grep nodetag | wc -l
+  \s*28 (re)
+  $ hg log -G --no-merges --template 'nodetag {rev}\n'
+  o  nodetag 35
+  |
+  o    nodetag 34
+  |\
+  | \
+  | |\
+  | | \
+  | | |\
+  | | | \
+  | | | |\
+  | | | | \
+  | | | | |\
+  +-+-+-+-----o  nodetag 33
+  | | | | | |
+  +---------o  nodetag 29
+  | | | | |
+  +-+-+---o  nodetag 27
+  | | | |/
+  | | | o  nodetag 3
+  | | |/
+  | | o  nodetag 2
+  | |/
+  | o  nodetag 1
+  |/
+  o  nodetag 0
+  
+  $ hg log -G -d 'brace ) in a date'
+  abort: invalid date: 'brace ) in a date'
+  [255]
+  $ hg log -G -P 32 --template '{rev}\n'
+  @  36
+  |
+  o  35
+  |
+  o  34
+  |
+  | o  33
+  | |
+  $ hg log -G --follow a
+  abort: -G/--graph option is incompatible with --follow with file argument
+  [255]
+
+Test multiple revision specifications are correctly handled
+
+  $ hg log -G -r 27 -r 25 -r 21 -r 34 -r 32 -r 31 --template '{rev}\n'
+  o  34
+  |
+  o    32
+  |\
+  | o    31
+  | |\
+  o | |  27
+  |/ /
+  | o  25
+  |/
+  o    21
+  |\
--- a/tests/test-grep.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-grep.t	Sat Jun 18 17:03:01 2011 -0500
@@ -1,6 +1,5 @@
-  $ mkdir t
+  $ hg init t
   $ cd t
-  $ hg init
   $ echo import > port
   $ hg add port
   $ hg commit -m 0 -u spam -d '0 0'
@@ -166,3 +165,11 @@
   $ hg grep --all red
   color:3:-:red
   color:1:+:red
+
+  $ hg init a
+  $ cd a
+  $ cp $TESTDIR/binfile.bin .
+  $ hg add binfile.bin
+  $ hg ci -m 'add binfile.bin'
+  $ hg grep "MaCam" --all
+  binfile.bin:0:+: Binary file matches
--- a/tests/test-hardlinks.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-hardlinks.t	Sat Jun 18 17:03:01 2011 -0500
@@ -25,9 +25,8 @@
 
 Prepare repo r1:
 
-  $ mkdir r1
+  $ hg init r1
   $ cd r1
-  $ hg init
 
   $ echo c1 > f1
   $ hg add f1
--- a/tests/test-help.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-help.t	Sat Jun 18 17:03:01 2011 -0500
@@ -86,7 +86,7 @@
    remove       remove the specified files on the next commit
    rename       rename files; equivalent of copy + remove
    resolve      redo merges or set/view the merge status of files
-   revert       restore individual files or directories to an earlier state
+   revert       restore files to their checkout state
    rollback     roll back the last transaction (dangerous)
    root         print the root (top) of the current working directory
    serve        start stand-alone webserver
@@ -105,19 +105,21 @@
   
    config       Configuration Files
    dates        Date Formats
-   patterns     File Name Patterns
+   diffs        Diff Formats
    environment  Environment Variables
-   revisions    Specifying Single Revisions
+   extensions   Using additional features
+   filesets     Specifying File Sets
+   glossary     Glossary
+   hgignore     syntax for Mercurial ignore files
+   hgweb        Configuring hgweb
+   merge-tools  Merge Tools
    multirevs    Specifying Multiple Revisions
+   patterns     File Name Patterns
+   revisions    Specifying Single Revisions
    revsets      Specifying Revision Sets
-   diffs        Diff Formats
-   merge-tools  Merge Tools
+   subrepos     Subrepositories
    templating   Template Usage
    urls         URL Paths
-   extensions   Using additional features
-   subrepos     Subrepositories
-   hgweb        Configuring hgweb
-   glossary     Glossary
   
   use "hg -v help" to show builtin aliases and global options
 
@@ -159,7 +161,7 @@
    remove       remove the specified files on the next commit
    rename       rename files; equivalent of copy + remove
    resolve      redo merges or set/view the merge status of files
-   revert       restore individual files or directories to an earlier state
+   revert       restore files to their checkout state
    rollback     roll back the last transaction (dangerous)
    root         print the root (top) of the current working directory
    serve        start stand-alone webserver
@@ -178,19 +180,21 @@
   
    config       Configuration Files
    dates        Date Formats
-   patterns     File Name Patterns
+   diffs        Diff Formats
    environment  Environment Variables
-   revisions    Specifying Single Revisions
+   extensions   Using additional features
+   filesets     Specifying File Sets
+   glossary     Glossary
+   hgignore     syntax for Mercurial ignore files
+   hgweb        Configuring hgweb
+   merge-tools  Merge Tools
    multirevs    Specifying Multiple Revisions
+   patterns     File Name Patterns
+   revisions    Specifying Single Revisions
    revsets      Specifying Revision Sets
-   diffs        Diff Formats
-   merge-tools  Merge Tools
+   subrepos     Subrepositories
    templating   Template Usage
    urls         URL Paths
-   extensions   Using additional features
-   subrepos     Subrepositories
-   hgweb        Configuring hgweb
-   glossary     Glossary
 
 Test short command list with verbose option
 
@@ -387,17 +391,6 @@
   
   add the specified files on the next commit
   
-      Schedule files to be version controlled and added to the repository.
-  
-      The files will be added to the repository at the next commit. To undo an
-      add before that, see "hg forget".
-  
-      If no names are given, add all files to the repository.
-  
-      Returns 0 if all files are successfully added.
-  
-  use "hg -v help add" to show verbose help
-  
   options:
   
    -I --include PATTERN [+]  include names matching the given patterns
@@ -407,7 +400,7 @@
   
   [+] marked option can be specified multiple times
   
-  use "hg -v help add" to show global options
+  use "hg help add" to show the full help text
   [255]
 
 Test ambiguous command help
@@ -682,7 +675,7 @@
    remove       remove the specified files on the next commit
    rename       rename files; equivalent of copy + remove
    resolve      redo merges or set/view the merge status of files
-   revert       restore individual files or directories to an earlier state
+   revert       restore files to their checkout state
    rollback     roll back the last transaction (dangerous)
    root         print the root (top) of the current working directory
    serve        start stand-alone webserver
@@ -705,22 +698,26 @@
   
    config       Configuration Files
    dates        Date Formats
-   patterns     File Name Patterns
+   diffs        Diff Formats
    environment  Environment Variables
-   revisions    Specifying Single Revisions
+   extensions   Using additional features
+   filesets     Specifying File Sets
+   glossary     Glossary
+   hgignore     syntax for Mercurial ignore files
+   hgweb        Configuring hgweb
+   merge-tools  Merge Tools
    multirevs    Specifying Multiple Revisions
+   patterns     File Name Patterns
+   revisions    Specifying Single Revisions
    revsets      Specifying Revision Sets
-   diffs        Diff Formats
-   merge-tools  Merge Tools
+   subrepos     Subrepositories
    templating   Template Usage
    urls         URL Paths
-   extensions   Using additional features
-   subrepos     Subrepositories
-   hgweb        Configuring hgweb
-   glossary     Glossary
   
   use "hg -v help" to show builtin aliases and global options
 
+
+
 Test list of commands with command with no help text
 
   $ hg help helpext
@@ -765,6 +762,14 @@
       working directory is checked out, it is equivalent to null. If an
       uncommitted merge is in progress, "." is the revision of the first parent.
 
+Test templating help
+
+  $ hg help templating | egrep '(desc|diffstat|firstline|nonempty)  '
+      desc        String. The text of the changeset description.
+      diffstat    String. Statistics of changes with the following format:
+      firstline   Any text. Returns the first line of text.
+      nonempty    Any text. Returns '(none)' if the string is empty.
+
 Test help hooks
 
   $ cat > helphook1.py <<EOF
--- a/tests/test-hg-parseurl.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-hg-parseurl.py	Sat Jun 18 17:03:01 2011 -0500
@@ -8,3 +8,6 @@
 testparse('http://example.com/no/anchor/branches', branch=['foo'])
 testparse('http://example.com/an/anchor/branches#bar', branch=['foo'])
 testparse('http://example.com/an/anchor/branches-None#foo', branch=None)
+testparse('http://example.com/')
+testparse('http://example.com')
+testparse('http://example.com#foo')
--- a/tests/test-hg-parseurl.py.out	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-hg-parseurl.py.out	Sat Jun 18 17:03:01 2011 -0500
@@ -3,3 +3,6 @@
 http://example.com/no/anchor/branches, branches: (None, ['foo'])
 http://example.com/an/anchor/branches, branches: ('bar', ['foo'])
 http://example.com/an/anchor/branches-None, branches: ('foo', [])
+http://example.com/, branches: (None, [])
+http://example.com/, branches: (None, [])
+http://example.com/, branches: ('foo', [])
--- a/tests/test-hgcia.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-hgcia.t	Sat Jun 18 17:03:01 2011 -0500
@@ -7,6 +7,9 @@
   > [hooks]
   > changegroup.cia = python:hgext.hgcia.hook
   > 
+  > [web]
+  > baseurl = http://hgserver/
+  > 
   > [cia]
   > user = testuser
   > project = testproject
@@ -43,8 +46,8 @@
         <author>test</author>
         <version>0:e63c23eaa88a</version>
         <log>foo</log>
-        
-        <files><file action="add">foo</file></files>
+        <url>http://hgserver/$TESTTMP/cia/rev/e63c23eaa88a</url>
+        <files><file uri="http://hgserver/$TESTTMP/cia/file/e63c23eaa88a/foo" action="add">foo</file></files>
       </commit>
     </body>
     <timestamp>0</timestamp>
--- a/tests/test-hgrc.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-hgrc.t	Sat Jun 18 17:03:01 2011 -0500
@@ -20,12 +20,12 @@
   $ cd foobar
   $ cat .hg/hgrc
   [paths]
-  default = */foo%bar (glob)
+  default = $TESTTMP/foo%bar
   $ hg paths
-  default = */foo%bar (glob)
+  default = $TESTTMP/foo%bar
   $ hg showconfig
-  bundle.mainreporoot=*/foobar (glob)
-  paths.default=*/foo%bar (glob)
+  bundle.mainreporoot=$TESTTMP/foobar
+  paths.default=$TESTTMP/foo%bar
   $ cd ..
 
 issue1829: wrong indentation
@@ -46,8 +46,12 @@
   $ export FAKEPATH
   $ echo '%include $FAKEPATH/no-such-file' > $HGRCPATH
   $ hg version
-  hg: parse error at $TESTTMP/hgrc:1: cannot include /path/to/nowhere/no-such-file (No such file or directory)
-  [255]
+  Mercurial Distributed SCM (version *) (glob)
+  (see http://mercurial.selenic.com for more information)
+  
+  Copyright (C) 2005-2011 Matt Mackall and others
+  This is free software; see the source for copying conditions. There is NO
+  warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
   $ unset FAKEPATH
 
 username expansion
@@ -133,3 +137,39 @@
   none: ui.verbose=False
   none: ui.debug=True
   none: ui.quiet=False
+
+plain mode with exceptions
+
+  $ cat > plain.py <<EOF
+  > def uisetup(ui):
+  >     ui.write('plain: %r\n' % ui.plain())
+  > EOF
+  $ echo "[extensions]" >> $HGRCPATH
+  $ echo "plain=./plain.py" >> $HGRCPATH
+  $ HGPLAINEXCEPT=; export HGPLAINEXCEPT
+  $ hg showconfig --config ui.traceback=True --debug
+  plain: True
+  read config from: $TESTTMP/hgrc
+  $TESTTMP/hgrc:15: extensions.plain=./plain.py
+  none: ui.traceback=True
+  none: ui.verbose=False
+  none: ui.debug=True
+  none: ui.quiet=False
+  $ unset HGPLAIN
+  $ hg showconfig --config ui.traceback=True --debug
+  plain: True
+  read config from: $TESTTMP/hgrc
+  $TESTTMP/hgrc:15: extensions.plain=./plain.py
+  none: ui.traceback=True
+  none: ui.verbose=False
+  none: ui.debug=True
+  none: ui.quiet=False
+  $ HGPLAINEXCEPT=i18n; export HGPLAINEXCEPT
+  $ hg showconfig --config ui.traceback=True --debug
+  plain: True
+  read config from: $TESTTMP/hgrc
+  $TESTTMP/hgrc:15: extensions.plain=./plain.py
+  none: ui.traceback=True
+  none: ui.verbose=False
+  none: ui.debug=True
+  none: ui.quiet=False
--- a/tests/test-hgweb-commands.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-hgweb-commands.t	Sat Jun 18 17:03:01 2011 -0500
@@ -16,6 +16,7 @@
   adding foo
   $ hg tag 1.0
   $ hg bookmark something
+  $ hg bookmark -r0 anotherthing
   $ echo another > foo
   $ hg branch stable
   marked working directory as branch stable
@@ -186,6 +187,7 @@
   <link rel="icon" href="/static/hgicon.png" type="image/png" />
   <meta name="robots" content="index, nofollow" />
   <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
+  <script type="text/javascript" src="/static/mercurial.js"></script>
   
   <title>test: log</title>
   <link rel="alternate" type="application/atom+xml"
@@ -244,19 +246,19 @@
     <th class="description">description</th>
    </tr>
    <tr class="parity0">
-    <td class="age">1970-01-01</td>
+    <td class="age">Thu Jan 01 00:00:00 1970 +0000</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> <span class="tag">something</span> </td>
    </tr>
    <tr class="parity1">
-    <td class="age">1970-01-01</td>
+    <td class="age">Thu Jan 01 00:00:00 1970 +0000</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">1970-01-01</td>
+    <td class="age">Thu Jan 01 00:00:00 1970 +0000</td>
     <td class="author">test</td>
-    <td class="description"><a href="/rev/2ef0ac749a14">base</a><span class="tag">1.0</span> </td>
+    <td class="description"><a href="/rev/2ef0ac749a14">base</a><span class="tag">1.0</span> <span class="tag">anotherthing</span> </td>
    </tr>
   
   </table>
@@ -270,6 +272,7 @@
   </div>
   </div>
   
+  <script type="text/javascript">process_dates()</script>
   
   
   </body>
@@ -284,6 +287,7 @@
   <link rel="icon" href="/static/hgicon.png" type="image/png" />
   <meta name="robots" content="index, nofollow" />
   <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
+  <script type="text/javascript" src="/static/mercurial.js"></script>
   
   <title>test: 2ef0ac749a14</title>
   </head>
@@ -317,7 +321,7 @@
   <div class="main">
   
   <h2><a href="/">test</a></h2>
-  <h3>changeset 0:2ef0ac749a14  <span class="tag">1.0</span>  </h3>
+  <h3>changeset 0:2ef0ac749a14  <span class="tag">1.0</span>  <span class="tag">anotherthing</span> </h3>
   
   <form class="search" action="/log">
   
@@ -335,7 +339,7 @@
   </tr>
   <tr>
    <th class="date">date</th>
-   <td class="date">Thu Jan 01 00:00:00 1970 +0000 (1970-01-01)</td></tr>
+   <td class="date age">Thu Jan 01 00:00:00 1970 +0000</td></tr>
   <tr>
    <th class="author">parents</th>
    <td class="author"></td>
@@ -348,6 +352,35 @@
    <th class="files">files</th>
    <td class="files"><a href="/file/2ef0ac749a14/da/foo">da/foo</a> <a href="/file/2ef0ac749a14/foo">foo</a> </td>
   </tr>
+  <tr>
+    <th class="diffstat">diffstat</th>
+    <td class="diffstat">
+       2 files changed, 2 insertions(+), 0 deletions(-)
+  
+      <a id="diffstatexpand" href="javascript:showDiffstat()"/>[<tt>+</tt>]</a>
+      <div id="diffstatdetails" style="display:none;">
+        <a href="javascript:hideDiffstat()"/>[<tt>-</tt>]</a>
+        <p>
+        <table>  <tr class="parity0">
+      <td class="diffstat-file"><a href="#l1.1">da/foo</a></td>
+      <td class="diffstat-total" align="right">1</td>
+      <td class="diffstat-graph">
+        <span class="diffstat-add" style="width:100.0%;">&nbsp;</span>
+        <span class="diffstat-remove" style="width:0.0%;">&nbsp;</span>
+      </td>
+    </tr>
+    <tr class="parity1">
+      <td class="diffstat-file"><a href="#l2.1">foo</a></td>
+      <td class="diffstat-total" align="right">1</td>
+      <td class="diffstat-graph">
+        <span class="diffstat-add" style="width:100.0%;">&nbsp;</span>
+        <span class="diffstat-remove" style="width:0.0%;">&nbsp;</span>
+      </td>
+    </tr>
+  </table>
+      </div>
+    </td>
+  </tr>
   </table>
   
   <div class="overflow">
@@ -366,6 +399,7 @@
   
   </div>
   </div>
+  <script type="text/javascript">process_dates()</script>
   
   
   </body>
@@ -397,6 +431,7 @@
   <link rel="icon" href="/static/hgicon.png" type="image/png" />
   <meta name="robots" content="index, nofollow" />
   <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
+  <script type="text/javascript" src="/static/mercurial.js"></script>
   
   <title>test: searching for base</title>
   </head>
@@ -441,9 +476,9 @@
     <th class="description">description</th>
    </tr>
    <tr class="parity0">
-    <td class="age">1970-01-01</td>
+    <td class="age">Thu Jan 01 00:00:00 1970 +0000</td>
     <td class="author">test</td>
-    <td class="description"><a href="/rev/2ef0ac749a14">base</a><span class="tag">1.0</span> </td>
+    <td class="description"><a href="/rev/2ef0ac749a14">base</a><span class="tag">1.0</span> <span class="tag">anotherthing</span> </td>
    </tr>
   
   </table>
@@ -456,6 +491,7 @@
   </div>
   </div>
   
+  <script type="text/javascript">process_dates()</script>
   
   
   </body>
@@ -495,6 +531,7 @@
   <link rel="icon" href="/static/hgicon.png" type="image/png" />
   <meta name="robots" content="index, nofollow" />
   <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
+  <script type="text/javascript" src="/static/mercurial.js"></script>
   
   <title>test: a4f92ed23982 foo</title>
   </head>
@@ -549,7 +586,7 @@
   </tr>
   <tr>
    <th class="date">date</th>
-   <td class="date">Thu Jan 01 00:00:00 1970 +0000 (1970-01-01)</td>
+   <td class="date age">Thu Jan 01 00:00:00 1970 +0000</td>
   </tr>
   <tr>
    <th class="author">parents</th>
@@ -572,6 +609,7 @@
   </div>
   </div>
   
+  <script type="text/javascript">process_dates()</script>
   
   
   </body>
@@ -603,6 +641,11 @@
   
   stable	1d22e65f027e5a0609357e7d8e7508cd2ba5d2fe	open
   default	a4f92ed23982be056b9852de5dfe873eaac7f0de	inactive
+  $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/raw-bookmarks'
+  200 Script output follows
+  
+  anotherthing	2ef0ac749a14e4f57a5a822464a0902c6f7f448f
+  something	1d22e65f027e5a0609357e7d8e7508cd2ba5d2fe
   $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/summary/?style=gitweb'
   200 Script output follows
   
@@ -613,7 +656,7 @@
   <link rel="icon" href="/static/hgicon.png" type="image/png" />
   <meta name="robots" content="index, nofollow"/>
   <link rel="stylesheet" href="/static/style-gitweb.css" type="text/css" />
-  
+  <script type="text/javascript" src="/static/mercurial.js"></script>
   
   <title>test: Summary</title>
   <link rel="alternate" type="application/atom+xml"
@@ -658,7 +701,7 @@
   <table cellspacing="0">
   
   <tr class="parity0">
-  <td class="age"><i>1970-01-01</i></td>
+  <td class="age"><i class="age">Thu Jan 01 00:00:00 1970 +0000</i></td>
   <td><i>test</i></td>
   <td>
   <a class="list" href="/rev/1d22e65f027e?style=gitweb">
@@ -672,7 +715,7 @@
   </td>
   </tr>
   <tr class="parity1">
-  <td class="age"><i>1970-01-01</i></td>
+  <td class="age"><i class="age">Thu Jan 01 00:00:00 1970 +0000</i></td>
   <td><i>test</i></td>
   <td>
   <a class="list" href="/rev/a4f92ed23982?style=gitweb">
@@ -686,12 +729,12 @@
   </td>
   </tr>
   <tr class="parity0">
-  <td class="age"><i>1970-01-01</i></td>
+  <td class="age"><i class="age">Thu Jan 01 00:00:00 1970 +0000</i></td>
   <td><i>test</i></td>
   <td>
   <a class="list" href="/rev/2ef0ac749a14?style=gitweb">
   <b>base</b>
-  <span class="logtags"><span class="tagtag" title="1.0">1.0</span> </span>
+  <span class="logtags"><span class="tagtag" title="1.0">1.0</span> <span class="bookmarktag" title="anotherthing">anotherthing</span> </span>
   </a>
   </td>
   <td class="link" nowrap>
@@ -706,7 +749,7 @@
   <table cellspacing="0">
   
   <tr class="parity0">
-  <td class="age"><i>1970-01-01</i></td>
+  <td class="age"><i class="age">Thu Jan 01 00:00:00 1970 +0000</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> |
@@ -717,11 +760,35 @@
   <tr class="light"><td colspan="3"><a class="list" href="/tags?style=gitweb">...</a></td></tr>
   </table>
   
+  <div><a class="title" href="/bookmarks?style=gitweb">bookmarks</a></div>
+  <table cellspacing="0">
+  
+  <tr class="parity0">
+  <td class="age"><i class="age">Thu Jan 01 00:00:00 1970 +0000</i></td>
+  <td><a class="list" href="/rev/2ef0ac749a14?style=gitweb"><b>anotherthing</b></a></td>
+  <td class="link">
+  <a href="/rev/2ef0ac749a14?style=gitweb">changeset</a> |
+  <a href="/log/2ef0ac749a14?style=gitweb">changelog</a> |
+  <a href="/file/2ef0ac749a14?style=gitweb">files</a>
+  </td>
+  </tr>
+  <tr class="parity1">
+  <td class="age"><i class="age">Thu Jan 01 00:00:00 1970 +0000</i></td>
+  <td><a class="list" href="/rev/1d22e65f027e?style=gitweb"><b>something</b></a></td>
+  <td class="link">
+  <a href="/rev/1d22e65f027e?style=gitweb">changeset</a> |
+  <a href="/log/1d22e65f027e?style=gitweb">changelog</a> |
+  <a href="/file/1d22e65f027e?style=gitweb">files</a>
+  </td>
+  </tr>
+  <tr class="light"><td colspan="3"><a class="list" href="/bookmarks?style=gitweb">...</a></td></tr>
+  </table>
+  
   <div><a class="title" href="#">branches</a></div>
   <table cellspacing="0">
   
   <tr class="parity0">
-  <td class="age"><i>1970-01-01</i></td>
+  <td class="age"><i class="age">Thu Jan 01 00:00:00 1970 +0000</i></td>
   <td><a class="list" href="/shortlog/1d22e65f027e?style=gitweb"><b>1d22e65f027e</b></a></td>
   <td class="">stable</td>
   <td class="link">
@@ -731,7 +798,7 @@
   </td>
   </tr>
   <tr class="parity1">
-  <td class="age"><i>1970-01-01</i></td>
+  <td class="age"><i class="age">Thu Jan 01 00:00:00 1970 +0000</i></td>
   <td><a class="list" href="/shortlog/a4f92ed23982?style=gitweb"><b>a4f92ed23982</b></a></td>
   <td class="">default</td>
   <td class="link">
@@ -744,6 +811,7 @@
     <td colspan="4"><a class="list"  href="#">...</a></td>
   </tr>
   </table>
+  <script type="text/javascript">process_dates()</script>
   <div class="page_footer">
   <div class="page_footer_text">test</div>
   <div class="rss_logo">
@@ -766,7 +834,7 @@
   <link rel="icon" href="/static/hgicon.png" type="image/png" />
   <meta name="robots" content="index, nofollow"/>
   <link rel="stylesheet" href="/static/style-gitweb.css" type="text/css" />
-  
+  <script type="text/javascript" src="/static/mercurial.js"></script>
   
   <title>test: Graph</title>
   <link rel="alternate" type="application/atom+xml"
@@ -813,11 +881,10 @@
   <ul id="graphnodes"></ul>
   </div>
   
-  <script type="text/javascript" src="/static/graph.js"></script>
   <script>
   <!-- hide script content
   
-  var data = [["1d22e65f027e", [0, 1], [[0, 0, 1]], "branch", "test", "1970-01-01", ["stable", true], ["tip"], ["something"]], ["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 data = [["1d22e65f027e", [0, 1], [[0, 0, 1]], "branch", "test", "1970-01-01", ["stable", true], ["tip"], ["something"]], ["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"], ["anotherthing"]]];
   var graph = new Graph();
   graph.scale(39);
   
@@ -895,6 +962,7 @@
   | <a href="/graph/2ef0ac749a14?style=gitweb">(0)</a> <a href="/graph/2ef0ac749a14?style=gitweb">-2</a> <a href="/graph/tip?style=gitweb">tip</a> 
   </div>
   
+  <script type="text/javascript">process_dates()</script>
   <div class="page_footer">
   <div class="page_footer_text">test</div>
   <div class="rss_logo">
@@ -913,7 +981,7 @@
   $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '?cmd=capabilities'; echo
   200 Script output follows
   
-  lookup changegroupsubset branchmap pushkey unbundle=HG10GZ,HG10BZ,HG10UN
+  lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch unbundle=HG10GZ,HG10BZ,HG10UN httpheader=1024
 
 heads
 
@@ -1082,7 +1150,7 @@
 
   $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/graph/' \
   >     | grep '^var data ='
-  var data = [["40b4d6888e92", [0, 1], [[0, 0, 1]], "\u80fd", "test", "1970-01-01", ["stable", true], ["tip"], ["something"]], ["1d22e65f027e", [0, 1], [[0, 0, 1]], "branch", "test", "1970-01-01", ["stable", false], [], []], ["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 data = [["40b4d6888e92", [0, 1], [[0, 0, 1]], "\u80fd", "test", "1970-01-01", ["stable", true], ["tip"], ["something"]], ["1d22e65f027e", [0, 1], [[0, 0, 1]], "branch", "test", "1970-01-01", ["stable", false], [], []], ["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"], ["anotherthing"]]];
 
 ERRORS ENCOUNTERED
 
--- a/tests/test-hgweb-descend-empties.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-hgweb-descend-empties.t	Sat Jun 18 17:03:01 2011 -0500
@@ -36,6 +36,7 @@
   <link rel="icon" href="/static/hgicon.png" type="image/png" />
   <meta name="robots" content="index, nofollow" />
   <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
+  <script type="text/javascript" src="/static/mercurial.js"></script>
   
   <title>test: 9087c84a0f5d /</title>
   </head>
@@ -129,6 +130,7 @@
   </table>
   </div>
   </div>
+  <script type="text/javascript">process_dates()</script>
   
   
   </body>
--- a/tests/test-hgweb-diffs.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-hgweb-diffs.t	Sat Jun 18 17:03:01 2011 -0500
@@ -29,6 +29,7 @@
   <link rel="icon" href="/static/hgicon.png" type="image/png" />
   <meta name="robots" content="index, nofollow" />
   <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
+  <script type="text/javascript" src="/static/mercurial.js"></script>
   
   <title>test: 0cd96de13884</title>
   </head>
@@ -80,7 +81,7 @@
   </tr>
   <tr>
    <th class="date">date</th>
-   <td class="date">Thu Jan 01 00:00:00 1970 +0000 (1970-01-01)</td></tr>
+   <td class="date age">Thu Jan 01 00:00:00 1970 +0000</td></tr>
   <tr>
    <th class="author">parents</th>
    <td class="author"></td>
@@ -93,6 +94,35 @@
    <th class="files">files</th>
    <td class="files"><a href="/file/0cd96de13884/a">a</a> <a href="/file/0cd96de13884/b">b</a> </td>
   </tr>
+  <tr>
+    <th class="diffstat">diffstat</th>
+    <td class="diffstat">
+       2 files changed, 2 insertions(+), 0 deletions(-)
+  
+      <a id="diffstatexpand" href="javascript:showDiffstat()"/>[<tt>+</tt>]</a>
+      <div id="diffstatdetails" style="display:none;">
+        <a href="javascript:hideDiffstat()"/>[<tt>-</tt>]</a>
+        <p>
+        <table>  <tr class="parity0">
+      <td class="diffstat-file"><a href="#l1.1">a</a></td>
+      <td class="diffstat-total" align="right">1</td>
+      <td class="diffstat-graph">
+        <span class="diffstat-add" style="width:100.0%;">&nbsp;</span>
+        <span class="diffstat-remove" style="width:0.0%;">&nbsp;</span>
+      </td>
+    </tr>
+    <tr class="parity1">
+      <td class="diffstat-file"><a href="#l2.1">b</a></td>
+      <td class="diffstat-total" align="right">1</td>
+      <td class="diffstat-graph">
+        <span class="diffstat-add" style="width:100.0%;">&nbsp;</span>
+        <span class="diffstat-remove" style="width:0.0%;">&nbsp;</span>
+      </td>
+    </tr>
+  </table>
+      </div>
+    </td>
+  </tr>
   </table>
   
   <div class="overflow">
@@ -111,6 +141,7 @@
   
   </div>
   </div>
+  <script type="text/javascript">process_dates()</script>
   
   
   </body>
@@ -153,6 +184,7 @@
   <link rel="icon" href="/static/hgicon.png" type="image/png" />
   <meta name="robots" content="index, nofollow" />
   <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
+  <script type="text/javascript" src="/static/mercurial.js"></script>
   
   <title>test: a diff</title>
   </head>
@@ -208,7 +240,7 @@
   </tr>
   <tr>
    <th>date</th>
-   <td>Thu Jan 01 00:00:00 1970 +0000 (1970-01-01)</td>
+   <td class="date age">Thu Jan 01 00:00:00 1970 +0000</td>
   </tr>
   <tr>
    <th>parents</th>
@@ -233,6 +265,7 @@
   </div>
   </div>
   
+  <script type="text/javascript">process_dates()</script>
   
   
   </body>
@@ -256,6 +289,7 @@
   <link rel="icon" href="/static/hgicon.png" type="image/png" />
   <meta name="robots" content="index, nofollow" />
   <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
+  <script type="text/javascript" src="/static/mercurial.js"></script>
   
   <title>test: 0cd96de13884</title>
   </head>
@@ -307,7 +341,7 @@
   </tr>
   <tr>
    <th class="date">date</th>
-   <td class="date">Thu Jan 01 00:00:00 1970 +0000 (1970-01-01)</td></tr>
+   <td class="date age">Thu Jan 01 00:00:00 1970 +0000</td></tr>
   <tr>
    <th class="author">parents</th>
    <td class="author"></td>
@@ -320,6 +354,35 @@
    <th class="files">files</th>
    <td class="files"><a href="/file/0cd96de13884/a">a</a> <a href="/file/0cd96de13884/b">b</a> </td>
   </tr>
+  <tr>
+    <th class="diffstat">diffstat</th>
+    <td class="diffstat">
+       2 files changed, 2 insertions(+), 0 deletions(-)
+  
+      <a id="diffstatexpand" href="javascript:showDiffstat()"/>[<tt>+</tt>]</a>
+      <div id="diffstatdetails" style="display:none;">
+        <a href="javascript:hideDiffstat()"/>[<tt>-</tt>]</a>
+        <p>
+        <table>  <tr class="parity0">
+      <td class="diffstat-file"><a href="#l1.1">a</a></td>
+      <td class="diffstat-total" align="right">1</td>
+      <td class="diffstat-graph">
+        <span class="diffstat-add" style="width:100.0%;">&nbsp;</span>
+        <span class="diffstat-remove" style="width:0.0%;">&nbsp;</span>
+      </td>
+    </tr>
+    <tr class="parity1">
+      <td class="diffstat-file"><a href="#l2.1">b</a></td>
+      <td class="diffstat-total" align="right">1</td>
+      <td class="diffstat-graph">
+        <span class="diffstat-add" style="width:100.0%;">&nbsp;</span>
+        <span class="diffstat-remove" style="width:0.0%;">&nbsp;</span>
+      </td>
+    </tr>
+  </table>
+      </div>
+    </td>
+  </tr>
   </table>
   
   <div class="overflow">
@@ -340,6 +403,7 @@
   
   </div>
   </div>
+  <script type="text/javascript">process_dates()</script>
   
   
   </body>
@@ -384,6 +448,7 @@
   <link rel="icon" href="/static/hgicon.png" type="image/png" />
   <meta name="robots" content="index, nofollow" />
   <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
+  <script type="text/javascript" src="/static/mercurial.js"></script>
   
   <title>test: a diff</title>
   </head>
@@ -439,7 +504,7 @@
   </tr>
   <tr>
    <th>date</th>
-   <td>Thu Jan 01 00:00:00 1970 +0000 (1970-01-01)</td>
+   <td class="date age">Thu Jan 01 00:00:00 1970 +0000</td>
   </tr>
   <tr>
    <th>parents</th>
@@ -465,6 +530,7 @@
   </div>
   </div>
   
+  <script type="text/javascript">process_dates()</script>
   
   
   </body>
--- a/tests/test-hgweb-empty.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-hgweb-empty.t	Sat Jun 18 17:03:01 2011 -0500
@@ -13,6 +13,7 @@
   <link rel="icon" href="/static/hgicon.png" type="image/png" />
   <meta name="robots" content="index, nofollow" />
   <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
+  <script type="text/javascript" src="/static/mercurial.js"></script>
   
   <title>test: log</title>
   <link rel="alternate" type="application/atom+xml"
@@ -82,6 +83,7 @@
   </div>
   </div>
   
+  <script type="text/javascript">process_dates()</script>
   
   
   </body>
@@ -96,6 +98,7 @@
   <link rel="icon" href="/static/hgicon.png" type="image/png" />
   <meta name="robots" content="index, nofollow" />
   <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
+  <script type="text/javascript" src="/static/mercurial.js"></script>
   
   <title>test: log</title>
   <link rel="alternate" type="application/atom+xml"
@@ -165,6 +168,7 @@
   </div>
   </div>
   
+  <script type="text/javascript">process_dates()</script>
   
   
   </body>
@@ -179,6 +183,7 @@
   <link rel="icon" href="/static/hgicon.png" type="image/png" />
   <meta name="robots" content="index, nofollow" />
   <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
+  <script type="text/javascript" src="/static/mercurial.js"></script>
   
   <title>test: revision graph</title>
   <link rel="alternate" type="application/atom+xml"
@@ -236,7 +241,6 @@
   <ul id="graphnodes"></ul>
   </div>
   
-  <script type="text/javascript" src="/static/graph.js"></script>
   <script type="text/javascript">
   <!-- hide script content
   
@@ -320,6 +324,7 @@
   </div>
   </div>
   
+  <script type="text/javascript">process_dates()</script>
   
   
   </body>
@@ -334,6 +339,7 @@
   <link rel="icon" href="/static/hgicon.png" type="image/png" />
   <meta name="robots" content="index, nofollow" />
   <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
+  <script type="text/javascript" src="/static/mercurial.js"></script>
   
   <title>test: 000000000000 /</title>
   </head>
@@ -391,6 +397,7 @@
   </table>
   </div>
   </div>
+  <script type="text/javascript">process_dates()</script>
   
   
   </body>
--- a/tests/test-hgweb-filelog.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-hgweb-filelog.t	Sat Jun 18 17:03:01 2011 -0500
@@ -117,6 +117,7 @@
   <link rel="icon" href="/static/hgicon.png" type="image/png" />
   <meta name="robots" content="index, nofollow" />
   <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
+  <script type="text/javascript" src="/static/mercurial.js"></script>
   
   <title>test: a history</title>
   <link rel="alternate" type="application/atom+xml"
@@ -178,12 +179,12 @@
     <th class="description">description</th>
    </tr>
    <tr class="parity0">
-    <td class="age">1970-01-01</td>
+    <td class="age">Thu Jan 01 00:00:00 1970 +0000</td>
     <td class="author">test</td>
     <td class="description"><a href="/rev/01de2d66a28d">second a</a></td>
    </tr>
    <tr class="parity1">
-    <td class="age">1970-01-01</td>
+    <td class="age">Thu Jan 01 00:00:00 1970 +0000</td>
     <td class="author">test</td>
     <td class="description"><a href="/rev/5ed941583260">first a</a></td>
    </tr>
@@ -199,6 +200,7 @@
   </div>
   </div>
   
+  <script type="text/javascript">process_dates()</script>
   
   
   </body>
@@ -216,6 +218,7 @@
   <link rel="icon" href="/static/hgicon.png" type="image/png" />
   <meta name="robots" content="index, nofollow" />
   <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
+  <script type="text/javascript" src="/static/mercurial.js"></script>
   
   <title>test: a history</title>
   <link rel="alternate" type="application/atom+xml"
@@ -277,12 +280,12 @@
     <th class="description">description</th>
    </tr>
    <tr class="parity0">
-    <td class="age">1970-01-01</td>
+    <td class="age">Thu Jan 01 00:00:00 1970 +0000</td>
     <td class="author">test</td>
     <td class="description"><a href="/rev/01de2d66a28d">second a</a></td>
    </tr>
    <tr class="parity1">
-    <td class="age">1970-01-01</td>
+    <td class="age">Thu Jan 01 00:00:00 1970 +0000</td>
     <td class="author">test</td>
     <td class="description"><a href="/rev/5ed941583260">first a</a></td>
    </tr>
@@ -298,6 +301,7 @@
   </div>
   </div>
   
+  <script type="text/javascript">process_dates()</script>
   
   
   </body>
@@ -315,6 +319,7 @@
   <link rel="icon" href="/static/hgicon.png" type="image/png" />
   <meta name="robots" content="index, nofollow" />
   <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
+  <script type="text/javascript" src="/static/mercurial.js"></script>
   
   <title>test: a history</title>
   <link rel="alternate" type="application/atom+xml"
@@ -376,7 +381,7 @@
     <th class="description">description</th>
    </tr>
    <tr class="parity0">
-    <td class="age">1970-01-01</td>
+    <td class="age">Thu Jan 01 00:00:00 1970 +0000</td>
     <td class="author">test</td>
     <td class="description"><a href="/rev/5ed941583260">first a</a></td>
    </tr>
@@ -392,6 +397,7 @@
   </div>
   </div>
   
+  <script type="text/javascript">process_dates()</script>
   
   
   </body>
@@ -409,6 +415,7 @@
   <link rel="icon" href="/static/hgicon.png" type="image/png" />
   <meta name="robots" content="index, nofollow" />
   <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
+  <script type="text/javascript" src="/static/mercurial.js"></script>
   
   <title>test: a history</title>
   <link rel="alternate" type="application/atom+xml"
@@ -470,7 +477,7 @@
     <th class="description">description</th>
    </tr>
    <tr class="parity0">
-    <td class="age">1970-01-01</td>
+    <td class="age">Thu Jan 01 00:00:00 1970 +0000</td>
     <td class="author">test</td>
     <td class="description"><a href="/rev/5ed941583260">first a</a></td>
    </tr>
@@ -486,6 +493,7 @@
   </div>
   </div>
   
+  <script type="text/javascript">process_dates()</script>
   
   
   </body>
@@ -503,6 +511,7 @@
   <link rel="icon" href="/static/hgicon.png" type="image/png" />
   <meta name="robots" content="index, nofollow" />
   <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
+  <script type="text/javascript" src="/static/mercurial.js"></script>
   
   <title>test: error</title>
   </head>
@@ -547,6 +556,7 @@
   </div>
   </div>
   
+  <script type="text/javascript">process_dates()</script>
   
   
   </body>
@@ -565,6 +575,7 @@
   <link rel="icon" href="/static/hgicon.png" type="image/png">
   <meta name="robots" content="index, nofollow" />
   <link rel="stylesheet" href="/static/style.css" type="text/css" />
+  <script type="text/javascript" src="/static/mercurial.js"></script>
   
   <title>test: c history</title>
   <link rel="alternate" type="application/atom+xml"
@@ -593,7 +604,7 @@
   
   <table class="logEntry parity0">
    <tr>
-    <th class="age">1970-01-01:</th>
+    <th><span class="age">Thu Jan 01 00:00:00 1970 +0000</span>:</th>
     <th class="firstline"><a href="/rev/b7682196df1c?style=spartan">change c</a></th>
    </tr>
    <tr>
@@ -618,7 +629,7 @@
   
   <table class="logEntry parity1">
    <tr>
-    <th class="age">1970-01-01:</th>
+    <th><span class="age">Thu Jan 01 00:00:00 1970 +0000</span>:</th>
     <th class="firstline"><a href="/rev/1a6696706df2?style=spartan">mv b</a></th>
    </tr>
    <tr>
@@ -651,6 +662,7 @@
   
   
   
+  <script type="text/javascript">process_dates()</script>
   
   <div class="logo">
   <a href="http://mercurial.selenic.com/">
--- a/tests/test-hgweb-no-path-info.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-hgweb-no-path-info.t	Sat Jun 18 17:03:01 2011 -0500
@@ -2,9 +2,8 @@
 no longer passed with the request. Instead, SCRIPT_NAME and PATH_INFO
 should be used from d74fc8dec2b4 onward to route the request.
 
-  $ mkdir repo
+  $ hg init repo
   $ cd repo
-  $ hg init
   $ echo foo > bar
   $ hg add bar
   $ hg commit -m "test"
--- a/tests/test-hgweb-no-request-uri.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-hgweb-no-request-uri.t	Sat Jun 18 17:03:01 2011 -0500
@@ -2,9 +2,8 @@
 no longer passed with the request. Instead, SCRIPT_NAME and PATH_INFO
 should be used from d74fc8dec2b4 onward to route the request.
 
-  $ mkdir repo
+  $ hg init repo
   $ cd repo
-  $ hg init
   $ echo foo > bar
   $ hg add bar
   $ hg commit -m "test"
--- a/tests/test-hgweb-non-interactive.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-hgweb-non-interactive.t	Sat Jun 18 17:03:01 2011 -0500
@@ -1,9 +1,8 @@
 Tests if hgweb can run without touching sys.stdin, as is required
 by the WSGI standard and strictly implemented by mod_wsgi.
 
-  $ mkdir repo
+  $ hg init repo
   $ cd repo
-  $ hg init
   $ echo foo > bar
   $ hg add bar
   $ hg commit -m "test"
--- a/tests/test-hgweb-raw.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-hgweb-raw.t	Sat Jun 18 17:03:01 2011 -0500
@@ -10,6 +10,7 @@
   > care about things like that.
   > ENDSOME
   $ hg add 'sub/some "text".txt'
+  warning: filename contains '"', which is reserved on Windows: 'sub/some "text".txt'
   $ hg commit -d "1 0" -m "Just some text"
 
   $ hg serve -p $HGPORT -A access.log -E error.log -d --pid-file=hg.pid
--- a/tests/test-hgweb-removed.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-hgweb-removed.t	Sat Jun 18 17:03:01 2011 -0500
@@ -24,6 +24,7 @@
   <link rel="icon" href="/static/hgicon.png" type="image/png" />
   <meta name="robots" content="index, nofollow" />
   <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
+  <script type="text/javascript" src="/static/mercurial.js"></script>
   
   <title>test: c78f6c5cbea9</title>
   </head>
@@ -75,7 +76,7 @@
   </tr>
   <tr>
    <th class="date">date</th>
-   <td class="date">Thu Jan 01 00:00:00 1970 +0000 (1970-01-01)</td></tr>
+   <td class="date age">Thu Jan 01 00:00:00 1970 +0000</td></tr>
   <tr>
    <th class="author">parents</th>
    <td class="author"><a href="/rev/cb9a9f314b8b">cb9a9f314b8b</a> </td>
@@ -88,6 +89,27 @@
    <th class="files">files</th>
    <td class="files">a </td>
   </tr>
+  <tr>
+    <th class="diffstat">diffstat</th>
+    <td class="diffstat">
+       1 files changed, 0 insertions(+), 1 deletions(-)
+  
+      <a id="diffstatexpand" href="javascript:showDiffstat()"/>[<tt>+</tt>]</a>
+      <div id="diffstatdetails" style="display:none;">
+        <a href="javascript:hideDiffstat()"/>[<tt>-</tt>]</a>
+        <p>
+        <table>  <tr class="parity0">
+      <td class="diffstat-file"><a href="#l1.1">a</a></td>
+      <td class="diffstat-total" align="right">1</td>
+      <td class="diffstat-graph">
+        <span class="diffstat-add" style="width:0.0%;">&nbsp;</span>
+        <span class="diffstat-remove" style="width:100.0%;">&nbsp;</span>
+      </td>
+    </tr>
+  </table>
+      </div>
+    </td>
+  </tr>
   </table>
   
   <div class="overflow">
@@ -102,6 +124,7 @@
   
   </div>
   </div>
+  <script type="text/javascript">process_dates()</script>
   
   
   </body>
@@ -119,6 +142,7 @@
   <link rel="icon" href="/static/hgicon.png" type="image/png" />
   <meta name="robots" content="index, nofollow" />
   <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
+  <script type="text/javascript" src="/static/mercurial.js"></script>
   
   <title>test: a diff</title>
   </head>
@@ -174,7 +198,7 @@
   </tr>
   <tr>
    <th>date</th>
-   <td>Thu Jan 01 00:00:00 1970 +0000 (1970-01-01)</td>
+   <td class="date age">Thu Jan 01 00:00:00 1970 +0000</td>
   </tr>
   <tr>
    <th>parents</th>
@@ -199,6 +223,7 @@
   </div>
   </div>
   
+  <script type="text/javascript">process_dates()</script>
   
   
   </body>
--- a/tests/test-hgweb.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-hgweb.t	Sat Jun 18 17:03:01 2011 -0500
@@ -47,6 +47,7 @@
   <link rel="icon" href="/static/hgicon.png" type="image/png" />
   <meta name="robots" content="index, nofollow" />
   <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
+  <script type="text/javascript" src="/static/mercurial.js"></script>
   
   <title>test: error</title>
   </head>
@@ -91,6 +92,7 @@
   </div>
   </div>
   
+  <script type="text/javascript">process_dates()</script>
   
   
   </body>
@@ -133,6 +135,7 @@
   <link rel="icon" href="/static/hgicon.png" type="image/png" />
   <meta name="robots" content="index, nofollow" />
   <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
+  <script type="text/javascript" src="/static/mercurial.js"></script>
   
   <title>test: error</title>
   </head>
@@ -177,6 +180,7 @@
   </div>
   </div>
   
+  <script type="text/javascript">process_dates()</script>
   
   
   </body>
@@ -201,6 +205,7 @@
   <link rel="icon" href="/static/hgicon.png" type="image/png" />
   <meta name="robots" content="index, nofollow" />
   <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
+  <script type="text/javascript" src="/static/mercurial.js"></script>
   
   <title>test: 2ef0ac749a14 /</title>
   </head>
@@ -279,6 +284,7 @@
   </table>
   </div>
   </div>
+  <script type="text/javascript">process_dates()</script>
   
   
   </body>
--- a/tests/test-hgwebdir.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-hgwebdir.t	Sat Jun 18 17:03:01 2011 -0500
@@ -143,6 +143,7 @@
   <link rel="icon" href="/static/hgicon.png" type="image/png" />
   <meta name="robots" content="index, nofollow" />
   <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
+  <script type="text/javascript" src="/static/mercurial.js"></script>
   
   <title>Mercurial repositories index</title>
   </head>
@@ -169,7 +170,7 @@
   <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">* ago</td> (glob)
+  <td class="age">*</td> (glob)
   <td class="indexlinks"></td>
   </tr>
   
@@ -177,7 +178,7 @@
   <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">* ago</td> (glob)
+  <td class="age">*</td> (glob)
   <td class="indexlinks"></td>
   </tr>
   
@@ -185,7 +186,7 @@
   <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">* ago</td> (glob)
+  <td class="age">*</td> (glob)
   <td class="indexlinks"></td>
   </tr>
   
@@ -193,7 +194,7 @@
   <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">* ago</td> (glob)
+  <td class="age">*</td> (glob)
   <td class="indexlinks"></td>
   </tr>
   
@@ -201,7 +202,7 @@
   <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">* ago</td> (glob)
+  <td class="age">*</td> (glob)
   <td class="indexlinks"></td>
   </tr>
   
@@ -209,7 +210,7 @@
   <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">* ago</td> (glob)
+  <td class="age">*</td> (glob)
   <td class="indexlinks"></td>
   </tr>
   
@@ -217,7 +218,7 @@
   <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">* ago</td> (glob)
+  <td class="age">*</td> (glob)
   <td class="indexlinks"></td>
   </tr>
   
@@ -225,7 +226,7 @@
   <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">* ago</td> (glob)
+  <td class="age">*</td> (glob)
   <td class="indexlinks"></td>
   </tr>
   
@@ -233,7 +234,7 @@
   <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">* ago</td> (glob)
+  <td class="age">*</td> (glob)
   <td class="indexlinks"></td>
   </tr>
   
@@ -241,7 +242,7 @@
   <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">* ago</td> (glob)
+  <td class="age">*</td> (glob)
   <td class="indexlinks"></td>
   </tr>
   
@@ -249,7 +250,7 @@
   <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">* ago</td> (glob)
+  <td class="age">*</td> (glob)
   <td class="indexlinks"></td>
   </tr>
   
@@ -257,7 +258,7 @@
   <td><a href="/star/webdir/a/?style=paper">star/webdir/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">* ago</td> (glob)
+  <td class="age">*</td> (glob)
   <td class="indexlinks"></td>
   </tr>
   
@@ -265,7 +266,7 @@
   <td><a href="/star/webdir/a/.hg/patches/?style=paper">star/webdir/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">* ago</td> (glob)
+  <td class="age">*</td> (glob)
   <td class="indexlinks"></td>
   </tr>
   
@@ -273,7 +274,7 @@
   <td><a href="/star/webdir/b/?style=paper">star/webdir/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">* ago</td> (glob)
+  <td class="age">*</td> (glob)
   <td class="indexlinks"></td>
   </tr>
   
@@ -281,7 +282,7 @@
   <td><a href="/star/webdir/c/?style=paper">star/webdir/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">* ago</td> (glob)
+  <td class="age">*</td> (glob)
   <td class="indexlinks"></td>
   </tr>
   
@@ -289,7 +290,7 @@
   <td><a href="/starstar/webdir/a/?style=paper">starstar/webdir/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">* ago</td> (glob)
+  <td class="age">*</td> (glob)
   <td class="indexlinks"></td>
   </tr>
   
@@ -297,7 +298,7 @@
   <td><a href="/starstar/webdir/a/.hg/patches/?style=paper">starstar/webdir/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">* ago</td> (glob)
+  <td class="age">*</td> (glob)
   <td class="indexlinks"></td>
   </tr>
   
@@ -305,7 +306,7 @@
   <td><a href="/starstar/webdir/b/?style=paper">starstar/webdir/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">* ago</td> (glob)
+  <td class="age">*</td> (glob)
   <td class="indexlinks"></td>
   </tr>
   
@@ -313,7 +314,7 @@
   <td><a href="/starstar/webdir/b/d/?style=paper">starstar/webdir/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">* ago</td> (glob)
+  <td class="age">*</td> (glob)
   <td class="indexlinks"></td>
   </tr>
   
@@ -321,7 +322,7 @@
   <td><a href="/starstar/webdir/c/?style=paper">starstar/webdir/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">* ago</td> (glob)
+  <td class="age">*</td> (glob)
   <td class="indexlinks"></td>
   </tr>
   
@@ -329,7 +330,7 @@
   <td><a href="/astar/?style=paper">astar</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">* ago</td> (glob)
+  <td class="age">*</td> (glob)
   <td class="indexlinks"></td>
   </tr>
   
@@ -337,13 +338,14 @@
   <td><a href="/astar/.hg/patches/?style=paper">astar/.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">* ago</td> (glob)
+  <td class="age">*</td> (glob)
   <td class="indexlinks"></td>
   </tr>
   
   </table>
   </div>
   </div>
+  <script type="text/javascript">process_dates()</script>
   
   
   </body>
@@ -370,6 +372,7 @@
   <link rel="icon" href="/static/hgicon.png" type="image/png" />
   <meta name="robots" content="index, nofollow" />
   <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
+  <script type="text/javascript" src="/static/mercurial.js"></script>
   
   <title>Mercurial repositories index</title>
   </head>
@@ -396,13 +399,14 @@
   <td><a href="/t/a/?style=paper">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">* ago</td> (glob)
+  <td class="age">*</td> (glob)
   <td class="indexlinks"></td>
   </tr>
   
   </table>
   </div>
   </div>
+  <script type="text/javascript">process_dates()</script>
   
   
   </body>
@@ -560,6 +564,7 @@
   <link rel="icon" href="/static/hgicon.png" type="image/png" />
   <meta name="robots" content="index, nofollow" />
   <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
+  <script type="text/javascript" src="/static/mercurial.js"></script>
   
   <title>Mercurial repositories index</title>
   </head>
@@ -585,6 +590,7 @@
   </table>
   </div>
   </div>
+  <script type="text/javascript">process_dates()</script>
   
   
   </body>
--- a/tests/test-highlight.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-highlight.t	Sat Jun 18 17:03:01 2011 -0500
@@ -65,6 +65,7 @@
   <link rel="icon" href="/static/hgicon.png" type="image/png" />
   <meta name="robots" content="index, nofollow" />
   <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
+  <script type="text/javascript" src="/static/mercurial.js"></script>
   
   <link rel="stylesheet" href="/highlightcss" type="text/css" />
   <title>test: 853dcd4de2a6 primes.py</title>
@@ -120,7 +121,7 @@
   </tr>
   <tr>
    <th class="date">date</th>
-   <td class="date">Thu Jan 01 00:00:00 1970 +0000 (1970-01-01)</td>
+   <td class="date age">Thu Jan 01 00:00:00 1970 +0000</td>
   </tr>
   <tr>
    <th class="author">parents</th>
@@ -173,6 +174,7 @@
   </div>
   </div>
   
+  <script type="text/javascript">process_dates()</script>
   
   
   </body>
@@ -191,6 +193,7 @@
   <link rel="icon" href="/static/hgicon.png" type="image/png" />
   <meta name="robots" content="index, nofollow" />
   <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
+  <script type="text/javascript" src="/static/mercurial.js"></script>
   
   <link rel="stylesheet" href="/highlightcss" type="text/css" />
   <title>test: primes.py annotate</title>
@@ -248,7 +251,7 @@
   </tr>
   <tr>
    <th class="date">date</th>
-   <td class="date">Thu Jan 01 00:00:00 1970 +0000 (1970-01-01)</td>
+   <td class="date age">Thu Jan 01 00:00:00 1970 +0000</td>
   </tr>
   <tr>
    <th class="author">parents</th>
@@ -497,6 +500,7 @@
   </div>
   </div>
   
+  <script type="text/javascript">process_dates()</script>
   
   
   </body>
--- a/tests/test-hook.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-hook.t	Sat Jun 18 17:03:01 2011 -0500
@@ -168,6 +168,61 @@
   update hook: HG_ERROR=0 HG_PARENT1=539e4b31b6dc 
   2 files updated, 0 files merged, 0 files removed, 0 files unresolved
 
+pushkey hook
+
+  $ echo 'pushkey = python "$TESTDIR"/printenv.py pushkey' >> .hg/hgrc
+  $ cd ../b
+  $ hg bookmark -r null foo
+  $ hg push -B foo ../a
+  pushing to ../a
+  searching for changes
+  no changes found
+  exporting bookmark foo
+  pushkey hook: HG_KEY=foo HG_NAMESPACE=bookmarks HG_NEW=0000000000000000000000000000000000000000 HG_RET=1 
+  $ cd ../a
+
+listkeys hook
+
+  $ echo 'listkeys = python "$TESTDIR"/printenv.py listkeys' >> .hg/hgrc
+  $ hg bookmark -r null bar
+  $ cd ../b
+  $ hg pull -B bar ../a
+  pulling from ../a
+  listkeys hook: HG_NAMESPACE=bookmarks HG_VALUES={'bar': '0000000000000000000000000000000000000000', 'foo': '0000000000000000000000000000000000000000'} 
+  no changes found
+  listkeys hook: HG_NAMESPACE=bookmarks HG_VALUES={'bar': '0000000000000000000000000000000000000000', 'foo': '0000000000000000000000000000000000000000'} 
+  importing bookmark bar
+  $ cd ../a
+
+test that prepushkey can prevent incoming keys
+
+  $ echo 'prepushkey = python "$TESTDIR"/printenv.py prepushkey.forbid 1' >> .hg/hgrc
+  $ cd ../b
+  $ hg bookmark -r null baz
+  $ hg push -B baz ../a
+  pushing to ../a
+  searching for changes
+  no changes found
+  listkeys hook: HG_NAMESPACE=bookmarks HG_VALUES={'bar': '0000000000000000000000000000000000000000', 'foo': '0000000000000000000000000000000000000000'} 
+  listkeys hook: HG_NAMESPACE=bookmarks HG_VALUES={'bar': '0000000000000000000000000000000000000000', 'foo': '0000000000000000000000000000000000000000'} 
+  exporting bookmark baz
+  prepushkey.forbid hook: HG_KEY=baz HG_NAMESPACE=bookmarks HG_NEW=0000000000000000000000000000000000000000 
+  abort: prepushkey hook exited with status 1
+  [255]
+  $ cd ../a
+
+test that prelistkeys can prevent listing keys
+
+  $ echo 'prelistkeys = python "$TESTDIR"/printenv.py prelistkeys.forbid 1' >> .hg/hgrc
+  $ hg bookmark -r null quux
+  $ cd ../b
+  $ hg pull -B quux ../a
+  pulling from ../a
+  prelistkeys.forbid hook: HG_NAMESPACE=bookmarks 
+  abort: prelistkeys hook exited with status 1
+  [255]
+  $ cd ../a
+
 prechangegroup hook can prevent incoming changes
 
   $ cd ../b
@@ -291,6 +346,9 @@
   > def brokenhook(**args):
   >     return 1 + {}
   > 
+  > def verbosehook(ui, **args):
+  >     ui.note('verbose output from hook\n')
+  > 
   > class container:
   >     unreachable = 1
   > EOF
@@ -480,3 +538,14 @@
   cb9a9f314b8b
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
 
+make sure --verbose (and --quiet/--debug etc.) are propogated to the local ui
+that is passed to pre/post hooks
+
+  $ echo '[hooks]' > .hg/hgrc
+  $ echo 'pre-identify = python:hooktests.verbosehook' >> .hg/hgrc
+  $ hg id
+  cb9a9f314b8b
+  $ hg id --verbose
+  calling hook pre-identify: hooktests.verbosehook
+  verbose output from hook
+  cb9a9f314b8b
--- a/tests/test-http-branchmap.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-http-branchmap.t	Sat Jun 18 17:03:01 2011 -0500
@@ -30,7 +30,7 @@
   $ echo bar >> b/foo
   $ hg -R b ci -m bar
   $ hg --encoding utf-8 -R b push
-  pushing to http://localhost:$HGPORT1
+  pushing to http://localhost:$HGPORT1/
   searching for changes
   remote: adding changesets
   remote: adding manifests
@@ -79,7 +79,7 @@
   > 
   > myui = ui.ui()
   > repo = hg.repository(myui, 'a')
-  > commands.serve(myui, repo, stdio=True)
+  > commands.serve(myui, repo, stdio=True, cmdserver=False)
   > EOF
   $ echo baz >> b/foo
   $ hg -R b ci -m baz
--- a/tests/test-http-clone-r.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-http-clone-r.t	Sat Jun 18 17:03:01 2011 -0500
@@ -1,81 +1,15 @@
+creating 'remote
 
   $ hg init remote
   $ cd remote
-
-creating 'remote
-
-  $ cat >>afile <<EOF
-  > 0
-  > EOF
-  $ hg add afile
-  $ hg commit -m "0.0"
-  $ cat >>afile <<EOF
-  > 1
-  > EOF
-  $ hg commit -m "0.1"
-  $ cat >>afile <<EOF
-  > 2
-  > EOF
-  $ hg commit -m "0.2"
-  $ cat >>afile <<EOF
-  > 3
-  > EOF
-  $ hg commit -m "0.3"
-  $ hg update -C 0
+  $ hg unbundle $TESTDIR/bundles/remote.hg
+  adding changesets
+  adding manifests
+  adding file changes
+  added 9 changesets with 7 changes to 4 files (+1 heads)
+  (run 'hg heads' to see heads, 'hg merge' to merge)
+  $ hg up tip
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
-  $ cat >>afile <<EOF
-  > 1
-  > EOF
-  $ hg commit -m "1.1"
-  created new head
-  $ cat >>afile <<EOF
-  > 2
-  > EOF
-  $ hg commit -m "1.2"
-  $ cat >fred <<EOF
-  > a line
-  > EOF
-  $ cat >>afile <<EOF
-  > 3
-  > EOF
-  $ hg add fred
-  $ hg commit -m "1.3"
-  $ hg mv afile adifferentfile
-  $ hg commit -m "1.3m"
-  $ hg update -C 3
-  1 files updated, 0 files merged, 2 files removed, 0 files unresolved
-  $ hg mv afile anotherfile
-  $ hg commit -m "0.3m"
-  $ hg debugindex .hg/store/data/afile.i
-     rev    offset  length   base linkrev nodeid       p1           p2
-       0         0       3      0       0 362fef284ce2 000000000000 000000000000
-       1         3       5      1       1 125144f7e028 362fef284ce2 000000000000
-       2         8       7      2       2 4c982badb186 125144f7e028 000000000000
-       3        15       9      3       3 19b1fc555737 4c982badb186 000000000000
-  $ hg debugindex .hg/store/data/adifferentfile.i
-     rev    offset  length   base linkrev nodeid       p1           p2
-       0         0      75      0       7 2565f3199a74 000000000000 000000000000
-  $ hg debugindex .hg/store/data/anotherfile.i
-     rev    offset  length   base linkrev nodeid       p1           p2
-       0         0      75      0       8 2565f3199a74 000000000000 000000000000
-  $ hg debugindex .hg/store/data/fred.i
-     rev    offset  length   base linkrev nodeid       p1           p2
-       0         0       8      0       6 12ab3bcc5ea4 000000000000 000000000000
-  $ hg debugindex .hg/store/00manifest.i
-     rev    offset  length   base linkrev nodeid       p1           p2
-       0         0      48      0       0 43eadb1d2d06 000000000000 000000000000
-       1        48      48      1       1 8b89697eba2c 43eadb1d2d06 000000000000
-       2        96      48      2       2 626a32663c2f 8b89697eba2c 000000000000
-       3       144      48      3       3 f54c32f13478 626a32663c2f 000000000000
-       4       192      58      3       6 de68e904d169 626a32663c2f 000000000000
-       5       250      68      3       7 09bb521d218d de68e904d169 000000000000
-       6       318      54      6       8 1fde233dfb0f f54c32f13478 000000000000
-  $ hg verify
-  checking changesets
-  checking manifests
-  crosschecking files in changesets and manifests
-  checking files
-  4 files, 9 changesets, 7 total revisions
 
 Starting server
 
@@ -214,7 +148,7 @@
   adding changesets
   adding manifests
   adding file changes
-  added 1 changesets with 0 changes to 1 files (+1 heads)
+  added 1 changesets with 0 changes to 0 files (+1 heads)
   (run 'hg heads' to see heads, 'hg merge' to merge)
   $ hg verify
   checking changesets
@@ -238,7 +172,7 @@
   adding changesets
   adding manifests
   adding file changes
-  added 2 changesets with 0 changes to 1 files (+1 heads)
+  added 2 changesets with 0 changes to 0 files (+1 heads)
   (run 'hg heads' to see heads, 'hg merge' to merge)
   $ hg verify
   checking changesets
--- a/tests/test-http-proxy.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-http-proxy.t	Sat Jun 18 17:03:01 2011 -0500
@@ -98,27 +98,23 @@
   updating to branch default
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
   $ cat proxy.log
-  * - - [*] "GET http://localhost:$HGPORT/?pairs=0000000000000000000000000000000000000000-0000000000000000000000000000000000000000&cmd=between HTTP/1.1" - - (glob)
   * - - [*] "GET http://localhost:$HGPORT/?cmd=capabilities HTTP/1.1" - - (glob)
   * - - [*] "GET http://localhost:$HGPORT/?cmd=stream_out HTTP/1.1" - - (glob)
-  * - - [*] "GET http://localhost:$HGPORT/?pairs=0000000000000000000000000000000000000000-0000000000000000000000000000000000000000&cmd=between HTTP/1.1" - - (glob)
-  * - - [*] "GET http://localhost:$HGPORT/?cmd=heads HTTP/1.1" - - (glob)
-  * - - [*] "GET http://localhost:$HGPORT/?cmd=changegroup&roots=0000000000000000000000000000000000000000 HTTP/1.1" - - (glob)
+  * - - [*] "GET http://localhost:$HGPORT/?cmd=listkeys HTTP/1.1" - - x-hgarg-1:namespace=bookmarks (glob)
   * - - [*] "GET http://localhost:$HGPORT/?cmd=capabilities HTTP/1.1" - - (glob)
-  * - - [*] "GET http://localhost:$HGPORT/?cmd=listkeys&namespace=bookmarks HTTP/1.1" - - (glob)
-  * - - [*] "GET http://localhost:$HGPORT/?pairs=0000000000000000000000000000000000000000-0000000000000000000000000000000000000000&cmd=between HTTP/1.1" - - (glob)
-  * - - [*] "GET http://localhost:$HGPORT/?cmd=heads HTTP/1.1" - - (glob)
-  * - - [*] "GET http://localhost:$HGPORT/?cmd=changegroup&roots=0000000000000000000000000000000000000000 HTTP/1.1" - - (glob)
+  * - - [*] "GET http://localhost:$HGPORT/?cmd=batch HTTP/1.1" - - x-hgarg-1:cmds=heads+%3Bknown+nodes%3D (glob)
+  * - - [*] "GET http://localhost:$HGPORT/?cmd=getbundle HTTP/1.1" - - x-hgarg-1:common=0000000000000000000000000000000000000000&heads=83180e7845de420a1bb46896fd5fe05294f8d629 (glob)
+  * - - [*] "GET http://localhost:$HGPORT/?cmd=listkeys HTTP/1.1" - - x-hgarg-1:namespace=bookmarks (glob)
   * - - [*] "GET http://localhost:$HGPORT/?cmd=capabilities HTTP/1.1" - - (glob)
-  * - - [*] "GET http://localhost:$HGPORT/?cmd=listkeys&namespace=bookmarks HTTP/1.1" - - (glob)
-  * - - [*] "GET http://localhost:$HGPORT/?pairs=0000000000000000000000000000000000000000-0000000000000000000000000000000000000000&cmd=between HTTP/1.1" - - (glob)
-  * - - [*] "GET http://localhost:$HGPORT/?cmd=heads HTTP/1.1" - - (glob)
-  * - - [*] "GET http://localhost:$HGPORT/?cmd=changegroup&roots=0000000000000000000000000000000000000000 HTTP/1.1" - - (glob)
+  * - - [*] "GET http://localhost:$HGPORT/?cmd=batch HTTP/1.1" - - x-hgarg-1:cmds=heads+%3Bknown+nodes%3D (glob)
+  * - - [*] "GET http://localhost:$HGPORT/?cmd=getbundle HTTP/1.1" - - x-hgarg-1:common=0000000000000000000000000000000000000000&heads=83180e7845de420a1bb46896fd5fe05294f8d629 (glob)
+  * - - [*] "GET http://localhost:$HGPORT/?cmd=listkeys HTTP/1.1" - - x-hgarg-1:namespace=bookmarks (glob)
   * - - [*] "GET http://localhost:$HGPORT/?cmd=capabilities HTTP/1.1" - - (glob)
-  * - - [*] "GET http://localhost:$HGPORT/?cmd=listkeys&namespace=bookmarks HTTP/1.1" - - (glob)
-  * - - [*] "GET http://localhost:$HGPORT/?pairs=0000000000000000000000000000000000000000-0000000000000000000000000000000000000000&cmd=between HTTP/1.1" - - (glob)
-  * - - [*] "GET http://localhost:$HGPORT/?cmd=heads HTTP/1.1" - - (glob)
-  * - - [*] "GET http://localhost:$HGPORT/?cmd=changegroup&roots=0000000000000000000000000000000000000000 HTTP/1.1" - - (glob)
+  * - - [*] "GET http://localhost:$HGPORT/?cmd=batch HTTP/1.1" - - x-hgarg-1:cmds=heads+%3Bknown+nodes%3D (glob)
+  * - - [*] "GET http://localhost:$HGPORT/?cmd=getbundle HTTP/1.1" - - x-hgarg-1:common=0000000000000000000000000000000000000000&heads=83180e7845de420a1bb46896fd5fe05294f8d629 (glob)
+  * - - [*] "GET http://localhost:$HGPORT/?cmd=listkeys HTTP/1.1" - - x-hgarg-1:namespace=bookmarks (glob)
   * - - [*] "GET http://localhost:$HGPORT/?cmd=capabilities HTTP/1.1" - - (glob)
-  * - - [*] "GET http://localhost:$HGPORT/?cmd=listkeys&namespace=bookmarks HTTP/1.1" - - (glob)
+  * - - [*] "GET http://localhost:$HGPORT/?cmd=batch HTTP/1.1" - - x-hgarg-1:cmds=heads+%3Bknown+nodes%3D (glob)
+  * - - [*] "GET http://localhost:$HGPORT/?cmd=getbundle HTTP/1.1" - - x-hgarg-1:common=0000000000000000000000000000000000000000&heads=83180e7845de420a1bb46896fd5fe05294f8d629 (glob)
+  * - - [*] "GET http://localhost:$HGPORT/?cmd=listkeys HTTP/1.1" - - x-hgarg-1:namespace=bookmarks (glob)
 
--- a/tests/test-http.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-http.t	Sat Jun 18 17:03:01 2011 -0500
@@ -70,6 +70,24 @@
   adding bar
   $ cd ..
 
+incoming via HTTP
+
+  $ hg clone http://localhost:$HGPORT1/ --rev 0 partial
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 4 changes to 4 files
+  updating to branch default
+  4 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ cd partial
+  $ touch LOCAL
+  $ hg ci -qAm LOCAL
+  $ hg incoming http://localhost:$HGPORT1/ --template '{desc}\n'
+  comparing with http://localhost:$HGPORT1/
+  searching for changes
+  2
+  $ cd ..
+
 pull
 
   $ cd copy-pull
--- a/tests/test-https.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-https.t	Sat Jun 18 17:03:01 2011 -0500
@@ -8,7 +8,7 @@
 Can be dumped with:
  openssl x509 -in pub.pem -text
 
-  $ cat << EOT > priv.pem 
+  $ cat << EOT > priv.pem
   > -----BEGIN PRIVATE KEY-----
   > MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEApjCWeYGrIa/Vo7LH
   > aRF8ou0tbgHKE33Use/whCnKEUm34rDaXQd4lxxX6aDWg06n9tiVStAKTgQAHJY8
@@ -21,7 +21,7 @@
   > -----END PRIVATE KEY-----
   > EOT
 
-  $ cat << EOT > pub.pem 
+  $ cat << EOT > pub.pem
   > -----BEGIN CERTIFICATE-----
   > MIIBqzCCAVWgAwIBAgIJANAXFFyWjGnRMA0GCSqGSIb3DQEBBQUAMDExEjAQBgNV
   > BAMMCWxvY2FsaG9zdDEbMBkGCSqGSIb3DQEJARYMaGdAbG9jYWxob3N0MB4XDTEw
@@ -37,7 +37,7 @@
   $ cat priv.pem pub.pem >> server.pem
   $ PRIV=`pwd`/server.pem
 
-  $ cat << EOT > pub-other.pem 
+  $ cat << EOT > pub-other.pem
   > -----BEGIN CERTIFICATE-----
   > MIIBqzCCAVWgAwIBAgIJALwZS731c/ORMA0GCSqGSIb3DQEBBQUAMDExEjAQBgNV
   > BAMMCWxvY2FsaG9zdDEbMBkGCSqGSIb3DQEJARYMaGdAbG9jYWxob3N0MB4XDTEw
@@ -53,7 +53,7 @@
 
 pub.pem patched with other notBefore / notAfter:
 
-  $ cat << EOT > pub-not-yet.pem 
+  $ cat << EOT > pub-not-yet.pem
   > -----BEGIN CERTIFICATE-----
   > MIIBqzCCAVWgAwIBAgIJANAXFFyWjGnRMA0GCSqGSIb3DQEBBQUAMDExEjAQBgNVBAMMCWxvY2Fs
   > aG9zdDEbMBkGCSqGSIb3DQEJARYMaGdAbG9jYWxob3N0MB4XDTM1MDYwNTIwMzAxNFoXDTM1MDYw
@@ -67,7 +67,7 @@
   > EOT
   $ cat priv.pem pub-not-yet.pem > server-not-yet.pem
 
-  $ cat << EOT > pub-expired.pem 
+  $ cat << EOT > pub-expired.pem
   > -----BEGIN CERTIFICATE-----
   > MIIBqzCCAVWgAwIBAgIJANAXFFyWjGnRMA0GCSqGSIb3DQEBBQUAMDExEjAQBgNVBAMMCWxvY2Fs
   > aG9zdDEbMBkGCSqGSIb3DQEJARYMaGdAbG9jYWxob3N0MB4XDTEwMTAxNDIwMzAxNFoXDTEwMTAx
@@ -118,9 +118,9 @@
   adding manifests
   adding file changes
   added 1 changesets with 4 changes to 4 files
-  warning: localhost certificate with fingerprint 91:4f:1a:ff:87:24:9c:09:b6:85:9b:88:b1:90:6d:30:75:64:91:ca not verified (check hostfingerprints or web.cacerts config setting)
   updating to branch default
   4 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  warning: localhost certificate with fingerprint 91:4f:1a:ff:87:24:9c:09:b6:85:9b:88:b1:90:6d:30:75:64:91:ca not verified (check hostfingerprints or web.cacerts config setting)
   $ hg verify -R copy-pull
   checking changesets
   checking manifests
@@ -198,7 +198,7 @@
 
 Test server cert which isn't valid yet
 
-  $ hg -R test serve -p $HGPORT1 -d --pid-file=hg1.pid --certificate=server-not-yet.pem  
+  $ hg -R test serve -p $HGPORT1 -d --pid-file=hg1.pid --certificate=server-not-yet.pem
   $ cat hg1.pid >> $DAEMON_PIDS
   $ hg -R copy-pull pull --config web.cacerts=pub-not-yet.pem https://localhost:$HGPORT1/
   abort: error: *:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed (glob)
@@ -206,7 +206,7 @@
 
 Test server cert which no longer is valid
 
-  $ hg -R test serve -p $HGPORT2 -d --pid-file=hg2.pid --certificate=server-expired.pem  
+  $ hg -R test serve -p $HGPORT2 -d --pid-file=hg2.pid --certificate=server-expired.pem
   $ cat hg2.pid >> $DAEMON_PIDS
   $ hg -R copy-pull pull --config web.cacerts=pub-expired.pem https://localhost:$HGPORT2/
   abort: error: *:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed (glob)
--- a/tests/test-i18n.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-i18n.t	Sat Jun 18 17:03:01 2011 -0500
@@ -8,17 +8,17 @@
 using the "replace" error handler:
 
   $ LANGUAGE=pt_BR hg tip
-  abortado: N?o h? um reposit?rio do Mercurial aqui (.hg n?o encontrado)!
+  abortado: n?o foi encontrado um reposit?rio em '$TESTTMP' (.hg n?o encontrado)!
   [255]
 
 Using a more accomodating encoding:
 
   $ HGENCODING=UTF-8 LANGUAGE=pt_BR hg tip
-  abortado: N\xc3\xa3o h\xc3\xa1 um reposit\xc3\xb3rio do Mercurial aqui (.hg n\xc3\xa3o encontrado)! (esc)
+  abortado: n\xc3\xa3o foi encontrado um reposit\xc3\xb3rio em '$TESTTMP' (.hg n\xc3\xa3o encontrado)! (esc)
   [255]
 
 Different encoding:
 
   $ HGENCODING=Latin-1 LANGUAGE=pt_BR hg tip
-  abortado: N\xe3o h\xe1 um reposit\xf3rio do Mercurial aqui (.hg n\xe3o encontrado)! (esc)
+  abortado: n\xe3o foi encontrado um reposit\xf3rio em '$TESTTMP' (.hg n\xe3o encontrado)! (esc)
   [255]
--- a/tests/test-identify.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-identify.t	Sat Jun 18 17:03:01 2011 -0500
@@ -65,36 +65,53 @@
 remote with rev number?
 
   $ hg id -n http://localhost:$HGPORT1/
-  abort: can't query remote revision number, branch, tags, or bookmarks
+  abort: can't query remote revision number, branch, or tags
   [255]
 
 remote with tags?
 
   $ hg id -t http://localhost:$HGPORT1/
-  abort: can't query remote revision number, branch, tags, or bookmarks
+  abort: can't query remote revision number, branch, or tags
   [255]
 
 remote with branch?
 
   $ hg id -b http://localhost:$HGPORT1/
-  abort: can't query remote revision number, branch, tags, or bookmarks
+  abort: can't query remote revision number, branch, or tags
   [255]
 
-remote with bookmarks?
+test bookmark support
 
-  $ hg id -B http://localhost:$HGPORT1/
-  abort: can't query remote revision number, branch, tags, or bookmarks
-  [255]
+  $ hg bookmark Y
+  $ hg bookmark Z
+  $ hg bookmarks
+     Y                         0:cb9a9f314b8b
+   * Z                         0:cb9a9f314b8b
+  $ hg id
+  cb9a9f314b8b+ tip Y/Z
+  $ hg id --bookmarks
+  Y Z
+
+test remote identify with bookmarks
+
+  $ hg id http://localhost:$HGPORT1/
+  cb9a9f314b8b Y/Z
+  $ hg id --bookmarks http://localhost:$HGPORT1/
+  Y Z
+  $ hg id -r . http://localhost:$HGPORT1/
+  cb9a9f314b8b Y/Z
+  $ hg id --bookmarks -r . http://localhost:$HGPORT1/
+  Y Z
 
 Make sure we do not obscure unknown requires file entries (issue2649)
 
   $ echo fake >> .hg/requires
   $ hg id
-  abort: requirement 'fake' not supported!
+  abort: unknown repository format: requires feature 'fake' (upgrade Mercurial)!
   [255]
 
   $ cd ..
   $ hg id test
-  abort: requirement 'fake' not supported!
+  abort: unknown repository format: requires feature 'fake' (upgrade Mercurial)!
   [255]
 
--- a/tests/test-impexp-branch.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-impexp-branch.t	Sat Jun 18 17:03:01 2011 -0500
@@ -11,6 +11,7 @@
   >         sys.exit(0)
   > sys.exit(1)
   > EOF
+
   $ hg init a
   $ cd a
   $ echo "Rev 1" >rev
@@ -20,11 +21,17 @@
   marked working directory as branch abranch
   $ echo "Rev  2" >rev
   $ hg commit -m "With branch."
-  $ if hg export 0 | python ../findbranch.py; then
+
+  $ hg export 0 > ../r0.patch
+  $ hg export 1 > ../r1.patch
+  $ cd ..
+
+  $ if python findbranch.py < r0.patch; then
   >     echo "Export of default branch revision has Branch header" 1>&2
   >     exit 1
   > fi
-  $ if hg export 1 | python ../findbranch.py; then
+
+  $ if python findbranch.py < r1.patch; then
   >     :  # Do nothing
   > else
   >     echo "Export of branch revision is missing Branch header" 1>&2
@@ -33,18 +40,17 @@
 
 Make sure import still works with branch information in patches.
 
-  $ cd ..
   $ hg init b
   $ cd b
-  $ hg -R ../a export 0 | hg import -
-  applying patch from stdin
-  $ hg -R ../a export 1 | hg import -
-  applying patch from stdin
+  $ hg import ../r0.patch
+  applying ../r0.patch
+  $ hg import ../r1.patch
+  applying ../r1.patch
   $ cd ..
-  $ rm -rf b
-  $ hg init b
-  $ cd b
-  $ hg -R ../a export 0 | hg import --exact -
-  applying patch from stdin
-  $ hg -R ../a export 1 | hg import --exact -
-  applying patch from stdin
+
+  $ hg init c
+  $ cd c
+  $ hg import --exact ../r0.patch
+  applying ../r0.patch
+  $ hg import --exact ../r1.patch
+  applying ../r1.patch
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-import-bypass.t	Sat Jun 18 17:03:01 2011 -0500
@@ -0,0 +1,261 @@
+  $ echo "[extensions]" >> $HGRCPATH
+  $ echo "purge=" >> $HGRCPATH
+  $ echo "graphlog=" >> $HGRCPATH
+
+  $ shortlog() {
+  >     hg glog --template '{rev}:{node|short} {author} {date|hgdate} - {branch} - {desc|firstline}\n'
+  > }
+
+Test --bypass with other options
+
+  $ hg init repo-options
+  $ cd repo-options
+  $ echo a > a
+  $ hg ci -Am adda
+  adding a
+  $ echo a >> a
+  $ hg branch foo
+  marked working directory as branch foo
+  $ hg ci -Am changea
+  $ hg export . > ../test.diff
+  $ hg up null
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+
+Test importing an existing revision
+
+  $ hg import --bypass --exact ../test.diff
+  applying ../test.diff
+  $ shortlog
+  o  1:4e322f7ce8e3 test 0 0 - foo - changea
+  |
+  o  0:07f494440405 test 0 0 - default - adda
+  
+
+Test failure without --exact
+
+  $ hg import --bypass ../test.diff
+  applying ../test.diff
+  unable to find 'a' for patching
+  abort: patch failed to apply
+  [255]
+  $ hg st
+  $ shortlog
+  o  1:4e322f7ce8e3 test 0 0 - foo - changea
+  |
+  o  0:07f494440405 test 0 0 - default - adda
+  
+
+Test --user, --date and --message
+
+  $ hg up 0
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ hg import --bypass --u test2 -d '1 0' -m patch2 ../test.diff
+  applying ../test.diff
+  $ cat .hg/last-message.txt
+  patch2 (no-eol)
+  $ shortlog
+  o  2:2e127d1da504 test2 1 0 - default - patch2
+  |
+  | o  1:4e322f7ce8e3 test 0 0 - foo - changea
+  |/
+  @  0:07f494440405 test 0 0 - default - adda
+  
+  $ hg rollback
+  repository tip rolled back to revision 1 (undo commit)
+  working directory now based on revision 0
+
+Test --import-branch
+
+  $ hg import --bypass --import-branch ../test.diff
+  applying ../test.diff
+  $ shortlog
+  o  1:4e322f7ce8e3 test 0 0 - foo - changea
+  |
+  @  0:07f494440405 test 0 0 - default - adda
+  
+  $ hg rollback
+  repository tip rolled back to revision 1 (undo commit)
+  working directory now based on revision 0
+
+Test --strip
+
+  $ hg import --bypass --strip 0 - <<EOF
+  > # HG changeset patch
+  > # User test
+  > # Date 0 0
+  > # Branch foo
+  > # Node ID 4e322f7ce8e3e4203950eac9ece27bf7e45ffa6c
+  > # Parent  07f4944404050f47db2e5c5071e0e84e7a27bba9
+  > changea
+  > 
+  > diff -r 07f494440405 -r 4e322f7ce8e3 a
+  > --- a	Thu Jan 01 00:00:00 1970 +0000
+  > +++ a	Thu Jan 01 00:00:00 1970 +0000
+  > @@ -1,1 +1,2 @@
+  >  a
+  > +a
+  > EOF
+  applying patch from stdin
+  $ hg rollback
+  repository tip rolled back to revision 1 (undo commit)
+  working directory now based on revision 0
+
+Test unsupported combinations
+
+  $ hg import --bypass --no-commit ../test.diff
+  abort: cannot use --no-commit with --bypass
+  [255]
+  $ hg import --bypass --similarity 50 ../test.diff
+  abort: cannot use --similarity with --bypass
+  [255]
+
+Test commit editor
+
+  $ hg diff -c 1 > ../test.diff
+  $ HGEDITOR=cat hg import --bypass ../test.diff
+  applying ../test.diff
+  
+  
+  HG: Enter commit message.  Lines beginning with 'HG:' are removed.
+  HG: Leave message empty to abort commit.
+  HG: --
+  HG: user: test
+  HG: branch 'default'
+  HG: changed a
+  abort: empty commit message
+  [255]
+
+Test patch.eol is handled
+
+  $ python -c 'file("a", "wb").write("a\r\n")'
+  $ hg ci -m makeacrlf
+  $ hg import -m 'should fail because of eol' --bypass ../test.diff
+  applying ../test.diff
+  patching file a
+  Hunk #1 FAILED at 0
+  abort: patch failed to apply
+  [255]
+  $ hg --config patch.eol=auto import -d '0 0' -m 'test patch.eol' --bypass ../test.diff
+  applying ../test.diff
+  $ shortlog
+  o  3:d7805b4d2cb3 test 0 0 - default - test patch.eol
+  |
+  @  2:872023de769d test 0 0 - default - makeacrlf
+  |
+  | o  1:4e322f7ce8e3 test 0 0 - foo - changea
+  |/
+  o  0:07f494440405 test 0 0 - default - adda
+  
+
+Test applying multiple patches
+
+  $ hg up -qC 0
+  $ echo e > e
+  $ hg ci -Am adde
+  adding e
+  created new head
+  $ hg export . > ../patch1.diff
+  $ hg up -qC 1
+  $ echo f > f
+  $ hg ci -Am addf
+  adding f
+  $ hg export . > ../patch2.diff
+  $ cd ..
+  $ hg clone -r1 repo-options repo-multi1
+  adding changesets
+  adding manifests
+  adding file changes
+  added 2 changesets with 2 changes to 1 files
+  updating to branch foo
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ cd repo-multi1
+  $ hg up 0
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ hg import --bypass ../patch1.diff ../patch2.diff
+  applying ../patch1.diff
+  applying ../patch2.diff
+  applied 16581080145e
+  $ shortlog
+  o  3:bc8ca3f8a7c4 test 0 0 - default - addf
+  |
+  o  2:16581080145e test 0 0 - default - adde
+  |
+  | o  1:4e322f7ce8e3 test 0 0 - foo - changea
+  |/
+  @  0:07f494440405 test 0 0 - default - adda
+  
+
+Test applying multiple patches with --exact
+
+  $ cd ..
+  $ hg clone -r1 repo-options repo-multi2
+  adding changesets
+  adding manifests
+  adding file changes
+  added 2 changesets with 2 changes to 1 files
+  updating to branch foo
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ cd repo-multi2
+  $ hg import --bypass --exact ../patch1.diff ../patch2.diff
+  applying ../patch1.diff
+  applying ../patch2.diff
+  applied 16581080145e
+  $ shortlog
+  o  3:d60cb8989666 test 0 0 - foo - addf
+  |
+  | o  2:16581080145e test 0 0 - default - adde
+  | |
+  @ |  1:4e322f7ce8e3 test 0 0 - foo - changea
+  |/
+  o  0:07f494440405 test 0 0 - default - adda
+  
+
+  $ cd ..
+
+Test complicated patch with --exact
+
+  $ hg init repo-exact
+  $ cd repo-exact
+  $ echo a > a
+  $ echo c > c
+  $ echo d > d
+  $ echo e > e
+  $ echo f > f
+  $ chmod +x f
+  $ ln -s c linkc
+  $ hg ci -Am t
+  adding a
+  adding c
+  adding d
+  adding e
+  adding f
+  adding linkc
+  $ hg cp a aa1
+  $ echo b >> a
+  $ echo b > b
+  $ hg add b
+  $ hg cp a aa2
+  $ echo aa >> aa2
+  $ chmod +x e
+  $ chmod -x f
+  $ ln -s a linka
+  $ hg rm d
+  $ hg rm linkc
+  $ hg mv c cc
+  $ hg ci -m patch
+  $ hg export --git . > ../test.diff
+  $ hg up -C null
+  0 files updated, 0 files merged, 7 files removed, 0 files unresolved
+  $ hg purge
+  $ hg st
+  $ hg import --bypass --exact ../test.diff
+  applying ../test.diff
+
+The patch should have matched the exported revision and generated no additional
+data. If not, diff both heads to debug it.
+
+  $ shortlog
+  o  1:2978fd5c8aa4 test 0 0 - default - patch
+  |
+  o  0:a0e19e636a43 test 0 0 - default - t
+  
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-import-git.t	Sat Jun 18 17:03:01 2011 -0500
@@ -0,0 +1,468 @@
+
+  $ hg init
+
+New file:
+
+  $ hg import -d "1000000 0" -mnew - <<EOF
+  > diff --git a/new b/new
+  > new file mode 100644
+  > index 0000000..7898192
+  > --- /dev/null
+  > +++ b/new
+  > @@ -0,0 +1 @@
+  > +a
+  > EOF
+  applying patch from stdin
+
+  $ hg tip -q
+  0:ae3ee40d2079
+
+New empty file:
+
+  $ hg import -d "1000000 0" -mempty - <<EOF
+  > diff --git a/empty b/empty
+  > new file mode 100644
+  > EOF
+  applying patch from stdin
+
+  $ hg tip -q
+  1:ab199dc869b5
+
+  $ hg locate empty
+  empty
+
+chmod +x:
+
+  $ hg import -d "1000000 0" -msetx - <<EOF
+  > diff --git a/new b/new
+  > old mode 100644
+  > new mode 100755
+  > EOF
+  applying patch from stdin
+
+  $ hg tip -q
+  2:3a34410f282e
+
+  $ test -x new
+
+Copy:
+
+  $ hg import -d "1000000 0" -mcopy - <<EOF
+  > diff --git a/new b/copy
+  > old mode 100755
+  > new mode 100644
+  > similarity index 100%
+  > copy from new
+  > copy to copy
+  > diff --git a/new b/copyx
+  > similarity index 100%
+  > copy from new
+  > copy to copyx
+  > EOF
+  applying patch from stdin
+
+  $ hg tip -q
+  3:37bacb7ca14d
+
+  $ if "$TESTDIR/hghave" -q execbit; then
+  >     test -f copy -a ! -x copy || echo bad
+  >     test -x copyx || echo bad
+  > else
+  >     test -f copy || echo bad
+  > fi
+
+  $ cat copy
+  a
+
+  $ hg cat copy
+  a
+
+Rename:
+
+  $ hg import -d "1000000 0" -mrename - <<EOF
+  > diff --git a/copy b/rename
+  > similarity index 100%
+  > rename from copy
+  > rename to rename
+  > EOF
+  applying patch from stdin
+
+  $ hg tip -q
+  4:47b81a94361d
+
+  $ hg locate
+  copyx
+  empty
+  new
+  rename
+
+Delete:
+
+  $ hg import -d "1000000 0" -mdelete - <<EOF
+  > diff --git a/copyx b/copyx
+  > deleted file mode 100755
+  > index 7898192..0000000
+  > --- a/copyx
+  > +++ /dev/null
+  > @@ -1 +0,0 @@
+  > -a
+  > EOF
+  applying patch from stdin
+
+  $ hg tip -q
+  5:d9b001d98336
+
+  $ hg locate
+  empty
+  new
+  rename
+
+  $ test -f copyx
+  [1]
+
+Regular diff:
+
+  $ hg import -d "1000000 0" -mregular - <<EOF
+  > diff --git a/rename b/rename
+  > index 7898192..72e1fe3 100644
+  > --- a/rename
+  > +++ b/rename
+  > @@ -1 +1,5 @@
+  >  a
+  > +a
+  > +a
+  > +a
+  > +a
+  > EOF
+  applying patch from stdin
+
+  $ hg tip -q
+  6:ebe901e7576b
+
+Copy and modify:
+
+  $ hg import -d "1000000 0" -mcopymod - <<EOF
+  > diff --git a/rename b/copy2
+  > similarity index 80%
+  > copy from rename
+  > copy to copy2
+  > index 72e1fe3..b53c148 100644
+  > --- a/rename
+  > +++ b/copy2
+  > @@ -1,5 +1,5 @@
+  >  a
+  >  a
+  > -a
+  > +b
+  >  a
+  >  a
+  > EOF
+  applying patch from stdin
+
+  $ hg tip -q
+  7:18f368958ecd
+
+  $ hg cat copy2
+  a
+  a
+  b
+  a
+  a
+
+Rename and modify:
+
+  $ hg import -d "1000000 0" -mrenamemod - <<EOF
+  > diff --git a/copy2 b/rename2
+  > similarity index 80%
+  > rename from copy2
+  > rename to rename2
+  > index b53c148..8f81e29 100644
+  > --- a/copy2
+  > +++ b/rename2
+  > @@ -1,5 +1,5 @@
+  >  a
+  >  a
+  >  b
+  > -a
+  > +c
+  >  a
+  > EOF
+  applying patch from stdin
+
+  $ hg tip -q
+  8:c32b0d7e6f44
+
+  $ hg locate copy2
+  [1]
+  $ hg cat rename2
+  a
+  a
+  b
+  c
+  a
+
+One file renamed multiple times:
+
+  $ hg import -d "1000000 0" -mmultirenames - <<EOF
+  > diff --git a/rename2 b/rename3
+  > rename from rename2
+  > rename to rename3
+  > diff --git a/rename2 b/rename3-2
+  > rename from rename2
+  > rename to rename3-2
+  > EOF
+  applying patch from stdin
+
+  $ hg tip -q
+  9:034a6bf95330
+
+  $ hg log -vr. --template '{rev} {files} / {file_copies}\n'
+  9 rename2 rename3 rename3-2 / rename3 (rename2)rename3-2 (rename2)
+
+  $ hg locate rename2 rename3 rename3-2
+  rename3
+  rename3-2
+
+  $ hg cat rename3
+  a
+  a
+  b
+  c
+  a
+
+  $ hg cat rename3-2
+  a
+  a
+  b
+  c
+  a
+
+  $ echo foo > foo
+  $ hg add foo
+  $ hg ci -m 'add foo'
+
+Binary files and regular patch hunks:
+
+  $ hg import -d "1000000 0" -m binaryregular - <<EOF
+  > diff --git a/binary b/binary
+  > new file mode 100644
+  > index 0000000000000000000000000000000000000000..593f4708db84ac8fd0f5cc47c634f38c013fe9e4
+  > GIT binary patch
+  > literal 4
+  > Lc\${NkU|;|M00aO5
+  > 
+  > diff --git a/foo b/foo2
+  > rename from foo
+  > rename to foo2
+  > EOF
+  applying patch from stdin
+
+  $ hg tip -q
+  11:c39bce63e786
+
+  $ cat foo2
+  foo
+
+  $ hg manifest --debug | grep binary
+  045c85ba38952325e126c70962cc0f9d9077bc67 644   binary
+
+Multiple binary files:
+
+  $ hg import -d "1000000 0" -m multibinary - <<EOF
+  > diff --git a/mbinary1 b/mbinary1
+  > new file mode 100644
+  > index 0000000000000000000000000000000000000000..593f4708db84ac8fd0f5cc47c634f38c013fe9e4
+  > GIT binary patch
+  > literal 4
+  > Lc\${NkU|;|M00aO5
+  > 
+  > diff --git a/mbinary2 b/mbinary2
+  > new file mode 100644
+  > index 0000000000000000000000000000000000000000..112363ac1917b417ffbd7f376ca786a1e5fa7490
+  > GIT binary patch
+  > literal 5
+  > Mc\${NkU|\`?^000jF3jhEB
+  > 
+  > EOF
+  applying patch from stdin
+
+  $ hg tip -q
+  12:30b530085242
+
+  $ hg manifest --debug | grep mbinary
+  045c85ba38952325e126c70962cc0f9d9077bc67 644   mbinary1
+  a874b471193996e7cb034bb301cac7bdaf3e3f46 644   mbinary2
+
+Filenames with spaces:
+
+  $ hg import -d "1000000 0" -m spaces - <<EOF
+  > diff --git a/foo bar b/foo bar
+  > new file mode 100644
+  > index 0000000..257cc56
+  > --- /dev/null
+  > +++ b/foo bar	
+  > @@ -0,0 +1 @@
+  > +foo
+  > EOF
+  applying patch from stdin
+
+  $ hg tip -q
+  13:04750ef42fb3
+
+  $ cat "foo bar"
+  foo
+
+Copy then modify the original file:
+
+  $ hg import -d "1000000 0" -m copy-mod-orig - <<EOF
+  > diff --git a/foo2 b/foo2
+  > index 257cc56..fe08ec6 100644
+  > --- a/foo2
+  > +++ b/foo2
+  > @@ -1 +1,2 @@
+  >  foo
+  > +new line
+  > diff --git a/foo2 b/foo3
+  > similarity index 100%
+  > copy from foo2
+  > copy to foo3
+  > EOF
+  applying patch from stdin
+
+  $ hg tip -q
+  14:c4cd9cdeaa74
+
+  $ cat foo3
+  foo
+
+Move text file and patch as binary
+
+  $ echo a > text2
+  $ hg ci -Am0
+  adding text2
+  $ hg import -d "1000000 0" -m rename-as-binary - <<"EOF"
+  > diff --git a/text2 b/binary2
+  > rename from text2
+  > rename to binary2
+  > index 78981922613b2afb6025042ff6bd878ac1994e85..10efcb362e9f3b3420fcfbfc0e37f3dc16e29757
+  > GIT binary patch
+  > literal 5
+  > Mc$`b*O5$Pw00T?_*Z=?k
+  > 
+  > EOF
+  applying patch from stdin
+
+  $ cat binary2
+  a
+  b
+  \x00 (no-eol) (esc)
+
+  $ hg st --copies --change . 
+  A binary2
+    text2
+  R text2
+  $ cd ..
+
+Consecutive import with renames (issue2459)
+
+  $ hg init issue2459
+  $ cd issue2459
+  $ hg import --no-commit --force - <<EOF
+  > diff --git a/a b/a
+  > new file mode 100644
+  > EOF
+  applying patch from stdin
+  $ hg import --no-commit --force - <<EOF
+  > diff --git a/a b/b
+  > rename from a
+  > rename to b
+  > EOF
+  applying patch from stdin
+  a has not been committed yet, so no copy data will be stored for b.
+  $ hg debugstate
+  a   0         -1 unset               b
+  $ hg ci -m done
+  $ cd ..
+
+Renames and strip
+
+  $ hg init renameandstrip
+  $ cd renameandstrip
+  $ echo a > a
+  $ hg ci -Am adda
+  adding a
+  $ hg import --no-commit -p2 - <<EOF
+  > diff --git a/foo/a b/foo/b
+  > rename from foo/a
+  > rename to foo/b
+  > EOF
+  applying patch from stdin
+  $ hg st --copies
+  A b
+    a
+  R a
+  $ cd ..
+
+Pure copy with existing destination
+
+  $ hg init copytoexisting
+  $ cd copytoexisting
+  $ echo a > a
+  $ echo b > b
+  $ hg ci -Am add
+  adding a
+  adding b
+  $ hg import --no-commit - <<EOF
+  > diff --git a/a b/b
+  > copy from a
+  > copy to b
+  > EOF
+  applying patch from stdin
+  abort: cannot create b: destination already exists
+  [255]
+  $ cat b
+  b
+
+Copy and changes with existing destination
+
+  $ hg import --no-commit - <<EOF
+  > diff --git a/a b/b
+  > copy from a
+  > copy to b
+  > --- a/a
+  > +++ b/b
+  > @@ -1,1 +1,2 @@
+  > a
+  > +b
+  > EOF
+  applying patch from stdin
+  cannot create b: destination already exists
+  1 out of 1 hunks FAILED -- saving rejects to file b.rej
+  abort: patch failed to apply
+  [255]
+  $ cat b
+  b
+
+  $ ln -s b linkb
+  $ hg add linkb
+  $ hg ci -m addlinkb
+  $ hg import --no-commit - <<EOF
+  > diff --git a/linkb b/linkb
+  > deleted file mode 120000
+  > --- a/linkb
+  > +++ /dev/null
+  > @@ -1,1 +0,0 @@
+  > -badhunk
+  > \ No newline at end of file
+  > EOF
+  applying patch from stdin
+  patching file linkb
+  Hunk #1 FAILED at 0
+  1 out of 1 hunks FAILED -- saving rejects to file linkb.rej
+  abort: patch failed to apply
+  [255]
+  $ hg st
+  ? b.rej
+  ? linkb.rej
+
+  $ cd ..
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-import-unknown.t	Sat Jun 18 17:03:01 2011 -0500
@@ -0,0 +1,67 @@
+  $ cat <<EOF >> $HGRCPATH
+  > [extensions]
+  > purge =
+  > EOF
+
+  $ hg init test
+  $ cd test
+  $ echo a > changed
+  $ echo a > removed
+  $ echo a > source
+  $ hg ci -Am addfiles
+  adding changed
+  adding removed
+  adding source
+  $ echo a >> changed
+  $ echo a > added
+  $ hg add added
+  $ hg rm removed
+  $ hg cp source copied
+  $ hg diff --git > ../unknown.diff
+
+Test adding on top of an unknown file
+
+  $ hg up -qC 0
+  $ hg purge
+  $ echo a > added
+  $ hg import --no-commit ../unknown.diff
+  applying ../unknown.diff
+  file added already exists
+  1 out of 1 hunks FAILED -- saving rejects to file added.rej
+  abort: patch failed to apply
+  [255]
+
+Test modifying an unknown file
+
+  $ hg revert -aq
+  $ hg purge
+  $ hg rm changed
+  $ hg ci -m removechanged
+  $ echo a > changed
+  $ hg import --no-commit ../unknown.diff
+  applying ../unknown.diff
+  abort: cannot patch changed: file is not tracked
+  [255]
+
+Test removing an unknown file
+
+  $ hg up -qC 0
+  $ hg purge
+  $ hg rm removed
+  $ hg ci -m removeremoved
+  created new head
+  $ echo a > removed
+  $ hg import --no-commit ../unknown.diff
+  applying ../unknown.diff
+  abort: cannot patch removed: file is not tracked
+  [255]
+
+Test copying onto an unknown file
+
+  $ hg up -qC 0
+  $ hg purge
+  $ echo a > copied
+  $ hg import --no-commit ../unknown.diff
+  applying ../unknown.diff
+  abort: cannot create copied: destination already exists
+  [255]
--- a/tests/test-import.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-import.t	Sat Jun 18 17:03:01 2011 -0500
@@ -11,6 +11,12 @@
   $ hg --cwd a ci -u someone -d '1 0' -m'second change'
 
 
+generate patches for the test
+
+  $ hg --cwd a export tip > exported-tip.patch
+  $ hg --cwd a diff -r0:1 > diffed-tip.patch
+
+
 import exported patch
 
   $ hg clone -r0 a b
@@ -20,19 +26,18 @@
   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
-  $ hg --cwd a export tip > tip.patch
-  $ hg --cwd b import ../tip.patch
-  applying ../tip.patch
+  $ hg --cwd b import ../exported-tip.patch
+  applying ../exported-tip.patch
 
-message should be same
+message and committer should be same
 
-  $ hg --cwd b tip | grep 'second change'
+  $ hg --cwd b tip
+  changeset:   1:1d4bd90af0e4
+  tag:         tip
+  user:        someone
+  date:        Thu Jan 01 00:00:01 1970 +0000
   summary:     second change
-
-committer should be same
-
-  $ hg --cwd b tip | grep someone
-  user:        someone
+  
   $ rm -r b
 
 
@@ -50,9 +55,8 @@
   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
-  $ hg --cwd a export tip > tip.patch
-  $ hg --config ui.patch='python ../dummypatch.py' --cwd b import ../tip.patch
-  applying ../tip.patch
+  $ hg --config ui.patch='python ../dummypatch.py' --cwd b import ../exported-tip.patch
+  applying ../exported-tip.patch
   $ cat b/a
   line2
   $ rm -r b
@@ -67,9 +71,8 @@
   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
-  $ hg --cwd a diff -r0:1 > tip.patch
-  $ hg --cwd b import ../tip.patch
-  applying ../tip.patch
+  $ hg --cwd b import ../diffed-tip.patch
+  applying ../diffed-tip.patch
   abort: empty commit message
   [255]
   $ rm -r b
@@ -84,9 +87,8 @@
   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
-  $ hg --cwd a diff -r0:1 > tip.patch
-  $ hg --cwd b import -mpatch ../tip.patch
-  applying ../tip.patch
+  $ hg --cwd b import -mpatch ../diffed-tip.patch
+  applying ../diffed-tip.patch
   $ rm -r b
 
 
@@ -99,9 +101,8 @@
   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
-  $ hg --cwd a diff -r0:1 > tip.patch
-  $ hg --cwd b import -mpatch -d '1 0' -u 'user@nowhere.net' ../tip.patch
-  applying ../tip.patch
+  $ hg --cwd b import -mpatch -d '1 0' -u 'user@nowhere.net' ../diffed-tip.patch
+  applying ../diffed-tip.patch
   $ hg -R b tip -pv
   changeset:   1:ca68f19f3a40
   tag:         tip
@@ -131,9 +132,8 @@
   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
-  $ hg --cwd a diff -r0:1 > tip.patch
-  $ hg --cwd b import --no-commit ../tip.patch
-  applying ../tip.patch
+  $ hg --cwd b import --no-commit ../diffed-tip.patch
+  applying ../diffed-tip.patch
   $ hg --cwd b diff --nodates
   diff -r 80971e65b431 a
   --- a/a
@@ -153,8 +153,7 @@
   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
-  $ hg --cwd a diff -r0:1 > tip.patch
-  $ sed 's/1,1/foo/' < tip.patch > broken.patch
+  $ sed 's/1,1/foo/' < diffed-tip.patch > broken.patch
   $ hg --cwd b import -mpatch ../broken.patch
   applying ../broken.patch
   abort: bad hunk #1
@@ -174,10 +173,9 @@
   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
-  $ hg --cwd a export tip > dir/tip.patch
   $ cd dir
-  $ hg -R b import tip.patch
-  applying tip.patch
+  $ hg -R b import ../exported-tip.patch
+  applying ../exported-tip.patch
   $ cd ..
   $ rm -r dir
 
@@ -191,7 +189,7 @@
   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
-  $ hg --cwd a export tip | hg --cwd b import -
+  $ hg --cwd b import - < exported-tip.patch
   applying patch from stdin
   $ rm -r b
 
@@ -218,7 +216,7 @@
   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
-  $ hg --cwd a export tip | hg --cwd b import -m 'override' -
+  $ hg --cwd b import -m 'override' - < exported-tip.patch
   applying patch from stdin
   $ hg --cwd b tip | grep override
   summary:     override
@@ -227,7 +225,8 @@
   $ cat > mkmsg.py <<EOF
   > import email.Message, sys
   > msg = email.Message.Message()
-  > msg.set_payload('email commit message\n' + open('tip.patch', 'rb').read())
+  > patch = open(sys.argv[1], 'rb').read()
+  > msg.set_payload('email commit message\n' + patch)
   > msg['Subject'] = 'email patch'
   > msg['From'] = 'email patcher'
   > sys.stdout.write(msg.as_string())
@@ -243,8 +242,7 @@
   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
-  $ hg --cwd a diff -r0:1 > tip.patch
-  $ python mkmsg.py > msg.patch
+  $ python mkmsg.py diffed-tip.patch > msg.patch
   $ hg --cwd b import ../msg.patch
   applying ../msg.patch
   $ hg --cwd b tip | grep email
@@ -306,8 +304,7 @@
   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
-  $ hg --cwd a export tip > tip.patch
-  $ python mkmsg.py | hg --cwd b import -
+  $ python mkmsg.py exported-tip.patch | hg --cwd b import -
   applying patch from stdin
   $ hg --cwd b tip | grep second
   summary:     second change
@@ -320,7 +317,8 @@
   $ cat > mkmsg2.py <<EOF
   > import email.Message, sys
   > msg = email.Message.Message()
-  > msg.set_payload('email patch\n\nnext line\n---\n' + open('tip.patch').read())
+  > patch = open(sys.argv[1], 'rb').read()
+  > msg.set_payload('email patch\n\nnext line\n---\n' + patch)
   > msg['Subject'] = '[PATCH] email patch'
   > msg['From'] = 'email patcher'
   > sys.stdout.write(msg.as_string())
@@ -336,8 +334,7 @@
   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
-  $ hg --cwd a diff -r0:1 > tip.patch
-  $ python mkmsg2.py | hg --cwd b import -
+  $ python mkmsg2.py diffed-tip.patch | hg --cwd b import -
   applying patch from stdin
   $ hg --cwd b tip --template '{desc}\n'
   email patch
@@ -386,22 +383,23 @@
   updating to branch default
   2 files updated, 0 files merged, 0 files removed, 0 files unresolved
   $ hg --cwd a export tip > tmp
-  $ sed -e 's/d1\/d2\///' < tmp > tip.patch
+  $ sed -e 's/d1\/d2\///' < tmp > subdir-tip.patch
   $ dir=`pwd`
   $ cd b/d1/d2 2>&1 > /dev/null
-  $ hg import  ../../../tip.patch
-  applying ../../../tip.patch
+  $ hg import  ../../../subdir-tip.patch
+  applying ../../../subdir-tip.patch
   $ cd "$dir"
 
 message should be 'subdir change'
-
-  $ hg --cwd b tip | grep 'subdir change'
-  summary:     subdir change
-
 committer should be 'someoneelse'
 
-  $ hg --cwd b tip | grep someoneelse
+  $ hg --cwd b tip
+  changeset:   1:3577f5aea227
+  tag:         tip
   user:        someoneelse
+  date:        Thu Jan 01 00:00:01 1970 +0000
+  summary:     subdir change
+  
 
 should be empty
 
@@ -422,7 +420,7 @@
   $ echo line0 >> a
   $ echo line3 >> a
   $ hg ci -m change a
-  $ hg export tip > tip.patch
+  $ hg export tip > fuzzy-tip.patch
   $ hg up -C 0
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
   $ echo line1 > a
@@ -431,8 +429,8 @@
   $ echo line0 >> a
   $ hg ci -m brancha
   created new head
-  $ hg import --no-commit -v tip.patch
-  applying tip.patch
+  $ hg import --no-commit -v fuzzy-tip.patch
+  applying fuzzy-tip.patch
   patching file a
   Hunk #1 succeeded at 1 with fuzz 2 (offset -2 lines).
   $ hg revert -a
@@ -447,8 +445,8 @@
 
 test fuzziness with eol=auto
 
-  $ hg --config patch.eol=auto import --no-commit -v tip.patch
-  applying tip.patch
+  $ hg --config patch.eol=auto import --no-commit -v fuzzy-tip.patch
+  applying fuzzy-tip.patch
   patching file a
   Hunk #1 succeeded at 1 with fuzz 2 (offset -2 lines).
   $ cd ..
@@ -619,7 +617,7 @@
   > rename to bar
   > EOF
   applying patch from stdin
-  abort: ../outside/foo not under root
+  abort: path contains illegal component: ../outside/foo
   [255]
   $ cd ..
 
--- a/tests/test-incoming-outgoing.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-incoming-outgoing.t	Sat Jun 18 17:03:01 2011 -0500
@@ -1,6 +1,5 @@
-  $ mkdir test
+  $ hg init test
   $ cd test
-  $ hg init
   $ for i in 0 1 2 3 4 5 6 7 8; do
   >     echo $i >> foo
   >     hg commit -A -m $i
--- a/tests/test-init.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-init.t	Sat Jun 18 17:03:01 2011 -0500
@@ -1,26 +1,5 @@
 This test tries to exercise the ssh functionality with a dummy script
 
-  $ cat <<EOF > dummyssh
-  > import sys
-  > import os
-  > 
-  > os.chdir(os.path.dirname(sys.argv[0]))
-  > if sys.argv[1] != "user@dummy":
-  >     sys.exit(-1)
-  > 
-  > if not os.path.exists("dummyssh"):
-  >     sys.exit(-1)
-  > 
-  > log = open("dummylog", "ab")
-  > log.write("Got arguments")
-  > for i, arg in enumerate(sys.argv[1:]):
-  >     log.write(" %d:%s" % (i+1, arg))
-  > log.write("\n")
-  > log.close()
-  > r = os.system(sys.argv[2])
-  > sys.exit(bool(r))
-  > EOF
-
   $ checknewrepo()
   > {
   >    name=$1
@@ -80,7 +59,7 @@
 
 init+push to remote2
 
-  $ hg init -e "python ./dummyssh" ssh://user@dummy/remote2
+  $ hg init -e "python $TESTDIR/dummyssh" ssh://user@dummy/remote2
   $ hg incoming -R remote2 local
   comparing with local
   changeset:   0:08b9e9f63b32
@@ -90,7 +69,7 @@
   summary:     init
   
 
-  $ hg push -R local -e "python ./dummyssh" ssh://user@dummy/remote2
+  $ hg push -R local -e "python $TESTDIR/dummyssh" ssh://user@dummy/remote2
   pushing to ssh://user@dummy/remote2
   searching for changes
   remote: adding changesets
@@ -100,7 +79,7 @@
 
 clone to remote1
 
-  $ hg clone -e "python ./dummyssh" local ssh://user@dummy/remote1
+  $ hg clone -e "python $TESTDIR/dummyssh" local ssh://user@dummy/remote1
   searching for changes
   remote: adding changesets
   remote: adding manifests
@@ -109,14 +88,14 @@
 
 init to existing repo
 
-  $ hg init -e "python ./dummyssh" ssh://user@dummy/remote1
+  $ hg init -e "python $TESTDIR/dummyssh" ssh://user@dummy/remote1
   abort: repository remote1 already exists!
   abort: could not create remote repo!
   [255]
 
 clone to existing repo
 
-  $ hg clone -e "python ./dummyssh" local ssh://user@dummy/remote1
+  $ hg clone -e "python $TESTDIR/dummyssh" local ssh://user@dummy/remote1
   abort: repository remote1 already exists!
   abort: could not create remote repo!
   [255]
@@ -199,3 +178,17 @@
   store
   fncache
   dotencode
+
+clone bookmarks
+
+  $ hg -R local bookmark test
+  $ hg -R local bookmarks
+   * test                      0:08b9e9f63b32
+  $ hg clone -e "python $TESTDIR/dummyssh" local ssh://user@dummy/remote-bookmarks
+  searching for changes
+  remote: adding changesets
+  remote: adding manifests
+  remote: adding file changes
+  remote: added 1 changesets with 1 changes to 1 files
+  $ hg -R remote-bookmarks bookmarks
+     test                      0:08b9e9f63b32
--- a/tests/test-inotify-dirty-dirstate.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-inotify-dirty-dirstate.t	Sat Jun 18 17:03:01 2011 -0500
@@ -7,8 +7,7 @@
 
 issue1810: inotify and fetch
 
-  $ mkdir test; cd test
-  $ hg init
+  $ hg init test; cd test
   $ hg inserve -d --pid-file=../hg.pid
   $ cat ../hg.pid >> "$DAEMON_PIDS"
   $ echo foo > foo
--- a/tests/test-install.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-install.t	Sat Jun 18 17:03:01 2011 -0500
@@ -3,7 +3,6 @@
   Checking encoding (ascii)...
   Checking installed modules (*/mercurial)... (glob)
   Checking templates...
-  Checking patch...
   Checking commit editor...
   Checking username...
   No problems detected
@@ -13,7 +12,6 @@
   Checking encoding (ascii)...
   Checking installed modules (*/mercurial)... (glob)
   Checking templates...
-  Checking patch...
   Checking commit editor...
   Checking username...
    no username supplied (see "hg help config")
--- a/tests/test-issue1306.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-issue1306.t	Sat Jun 18 17:03:01 2011 -0500
@@ -18,14 +18,14 @@
   adding c
 
   $ hg log
-  changeset:   2:1630aed6ed2b
+  changeset:   2:ae3d9c30ec50
   branch:      br
   tag:         tip
   user:        test
   date:        Thu Jan 01 00:00:00 1970 +0000
   summary:     c
   
-  changeset:   1:234f53e6c5ff
+  changeset:   1:3f7f930ca414
   branch:      br
   user:        test
   date:        Thu Jan 01 00:00:00 1970 +0000
@@ -50,7 +50,7 @@
   2 files updated, 0 files merged, 0 files removed, 0 files unresolved
 
   $ hg -R local1 parents
-  changeset:   2:1630aed6ed2b
+  changeset:   2:ae3d9c30ec50
   branch:      br
   tag:         tip
   user:        test
@@ -86,7 +86,7 @@
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
 
   $ hg -R local3 parents
-  changeset:   1:234f53e6c5ff
+  changeset:   1:3f7f930ca414
   branch:      br
   user:        test
   date:        Thu Jan 01 00:00:00 1970 +0000
--- a/tests/test-issue1502.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-issue1502.t	Sat Jun 18 17:03:01 2011 -0500
@@ -19,8 +19,7 @@
   adding manifests
   adding file changes
   added 1 changesets with 1 changes to 1 files (+1 heads)
-  not updating, since new heads added
-  (run 'hg heads' to see heads, 'hg merge' to merge)
+  not updating: crosses branches (merge branches or update --check to force update)
 
   $ hg -R foo1 book branchy
   $ hg -R foo1 book
--- a/tests/test-issue322.t	Wed Jun 01 16:32:48 2011 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,59 +0,0 @@
-http://mercurial.selenic.com/bts/issue322
-
-File replaced with directory:
-
-  $ hg init a
-  $ cd a
-  $ echo a > a
-  $ hg commit -Ama
-  adding a
-  $ rm a
-  $ mkdir a
-  $ echo a > a/a
-
-Should fail - would corrupt dirstate:
-
-  $ hg add a/a
-  abort: file 'a' in dirstate clashes with 'a/a'
-  [255]
-
-  $ cd ..
-
-Directory replaced with file:
-
-  $ hg init c
-  $ cd c
-  $ mkdir a
-  $ echo a > a/a
-  $ hg commit -Ama
-  adding a/a
-
-  $ rm -r a
-  $ echo a > a
-
-Should fail - would corrupt dirstate:
-
-  $ hg add a
-  abort: directory 'a' already in dirstate
-  [255]
-
-  $ cd ..
-
-Directory replaced with file:
-
-  $ hg init d
-  $ cd d
-  $ mkdir b
-  $ mkdir b/c
-  $ echo a > b/c/d
-  $ hg commit -Ama
-  adding b/c/d
-  $ rm -r b
-  $ echo a > b
-
-Should fail - would corrupt dirstate:
-
-  $ hg add b
-  abort: directory 'b' already in dirstate
-  [255]
-
--- a/tests/test-issue433.t	Wed Jun 01 16:32:48 2011 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,10 +0,0 @@
-http://mercurial.selenic.com/bts/issue433
-
-  $ hg init
-  $ echo a > a
-  $ hg commit -Ama
-  adding a
-
-  $ hg parents -r 0 doesnotexist
-  abort: 'doesnotexist' not found in manifest!
-  [255]
--- a/tests/test-issue436.t	Wed Jun 01 16:32:48 2011 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,6 +0,0 @@
-http://mercurial.selenic.com/bts/issue436
-
-  $ hg init
-  $ hg -v log -v
-  $ hg -v log -v x
-
--- a/tests/test-issue522.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-issue522.t	Sat Jun 18 17:03:01 2011 -0500
@@ -48,7 +48,7 @@
   $ hg manifest --debug | grep foo
   c6fc755d7e68f49f880599da29f15add41f42f5a 644   foo
 
-  $ hg debugindex .hg/store/data/foo.i
+  $ hg debugindex foo
      rev    offset  length   base linkrev nodeid       p1           p2
        0         0       5      0       0 2ed2a3912a0b 000000000000 000000000000
        1         5       9      1       1 6f4310b00b9a 2ed2a3912a0b 000000000000
--- a/tests/test-issue660.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-issue660.t	Sat Jun 18 17:03:01 2011 -0500
@@ -1,4 +1,5 @@
-http://mercurial.selenic.com/bts/issue660
+http://mercurial.selenic.com/bts/issue660 and:
+http://mercurial.selenic.com/bts/issue322
 
   $ hg init
   $ echo a > a
Binary file tests/test-keyword.hg has changed
--- a/tests/test-keyword.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-keyword.t	Sat Jun 18 17:03:01 2011 -0500
@@ -78,7 +78,7 @@
  hg ci -m addsym -u mercurial
  hg bundle --base null ../test-keyword.hg
 
-  $ hg pull -u "$TESTDIR"/test-keyword.hg
+  $ hg pull -u "$TESTDIR"/bundles/test-keyword.hg
   pulling from *test-keyword.hg (glob)
   requesting all changes
   adding changesets
@@ -209,7 +209,7 @@
   To: Test
   
   changeset a2392c293916 in $TESTTMP/Test
-  details: *cmd=changeset;node=a2392c293916 (glob)
+  details: $TESTTMP/Test?cmd=changeset;node=a2392c293916
   description:
   	addsym
   
@@ -982,7 +982,7 @@
   $ HGMERGE=internal:local hg resolve -a
   $ hg commit -m localresolve
   $ cat m
-  $Id: m 41efa6d38e9b Thu, 01 Jan 1970 00:00:00 +0000 test $
+  $Id: m 800511b3a22d Thu, 01 Jan 1970 00:00:00 +0000 test $
   bar
 
 Test restricted mode with transplant -b
@@ -1000,19 +1000,19 @@
   2 files updated, 0 files merged, 0 files removed, 0 files unresolved
   $ hg -y transplant -b foo tip
   applying 4aa30d025d50
-  4aa30d025d50 transplanted to 5a4da427c162
+  4aa30d025d50 transplanted to e00abbf63521
 
 Expansion in changeset but not in file
 
   $ hg tip -p
-  changeset:   11:5a4da427c162
+  changeset:   11:e00abbf63521
   tag:         tip
-  parent:      9:41efa6d38e9b
+  parent:      9:800511b3a22d
   user:        test
   date:        Thu Jan 01 00:00:00 1970 +0000
   summary:     9foobranch
   
-  diff -r 41efa6d38e9b -r 5a4da427c162 a
+  diff -r 800511b3a22d -r e00abbf63521 a
   --- a/a	Thu Jan 01 00:00:00 1970 +0000
   +++ b/a	Thu Jan 01 00:00:00 1970 +0000
   @@ -1,3 +1,4 @@
@@ -1023,7 +1023,7 @@
   
   $ head -n 2 a
   foobranch
-  expand $Id: a 5a4da427c162 Thu, 01 Jan 1970 00:00:00 +0000 test $
+  expand $Id: a e00abbf63521 Thu, 01 Jan 1970 00:00:00 +0000 test $
 
 Turn off expansion
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-known.t	Sat Jun 18 17:03:01 2011 -0500
@@ -0,0 +1,37 @@
+
+= Test the known() protocol function =
+
+Create a test repository:
+
+  $ hg init repo
+  $ cd repo
+  $ touch a ; hg add a ; hg ci -ma
+  $ touch b ; hg add b ; hg ci -mb
+  $ touch c ; hg add c ; hg ci -mc
+  $ hg log --template '{node}\n'
+  991a3460af53952d10ec8a295d3d2cc2e5fa9690
+  0e067c57feba1a5694ca4844f05588bb1bf82342
+  3903775176ed42b1458a6281db4a0ccf4d9f287a
+  $ cd ..
+
+Test locally:
+
+  $ hg debugknown repo 991a3460af53952d10ec8a295d3d2cc2e5fa9690 0e067c57feba1a5694ca4844f05588bb1bf82342 3903775176ed42b1458a6281db4a0ccf4d9f287a
+  111
+  $ hg debugknown repo 000a3460af53952d10ec8a295d3d2cc2e5fa9690 0e067c57feba1a5694ca4844f05588bb1bf82342 0003775176ed42b1458a6281db4a0ccf4d9f287a
+  010
+  $ hg debugknown repo
+  
+
+Test via HTTP:
+
+  $ hg serve -R repo -p $HGPORT -d --pid-file=hg.pid -E error.log -A access.log
+  $ cat hg.pid >> $DAEMON_PIDS
+  $ hg debugknown http://localhost:$HGPORT/ 991a3460af53952d10ec8a295d3d2cc2e5fa9690 0e067c57feba1a5694ca4844f05588bb1bf82342 3903775176ed42b1458a6281db4a0ccf4d9f287a
+  111
+  $ hg debugknown http://localhost:$HGPORT/ 000a3460af53952d10ec8a295d3d2cc2e5fa9690 0e067c57feba1a5694ca4844f05588bb1bf82342 0003775176ed42b1458a6281db4a0ccf4d9f287a
+  010
+  $ hg debugknown http://localhost:$HGPORT/
+  
+  $ cat error.log
+
--- a/tests/test-locate.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-locate.t	Sat Jun 18 17:03:01 2011 -0500
@@ -1,6 +1,5 @@
-  $ mkdir t
+  $ hg init t
   $ cd t
-  $ hg init
   $ echo 0 > a
   $ echo 0 > b
   $ echo 0 > t.h
--- a/tests/test-log.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-log.t	Sat Jun 18 17:03:01 2011 -0500
@@ -512,12 +512,33 @@
   date:        Thu Jan 01 00:00:01 1970 +0000
   summary:     r1
   
+log -d " " (whitespaces only)
 
+  $ hg log -d " "
+  abort: dates cannot consist entirely of whitespace
+  [255]
 
 log -d -1
 
   $ hg log -d -1
 
+log -d ">"
+
+  $ hg log -d ">"
+  abort: invalid day spec, use '>DATE'
+  [255]
+
+log -d "<"
+
+  $ hg log -d "<"
+  abort: invalid day spec, use '<DATE'
+  [255]
+
+Negative ranges
+  $ hg log -d "--2"
+  abort: -2 must be nonnegative (see 'hg help dates')
+  [255]
+
 
 log -p -l2 --color=always
 
@@ -1117,3 +1138,21 @@
   date:        Thu Jan 01 00:00:00 1970 +0000
   summary:     a
   
+  $ cat > $HGTMP/testhidden.py << EOF
+  > def reposetup(ui, repo):
+  >     for line in repo.opener('hidden'):
+  >         ctx = repo[line.strip()]
+  >         repo.changelog.hiddenrevs.add(ctx.rev())
+  > EOF
+  $ echo '[extensions]' >> $HGRCPATH
+  $ echo "hidden=$HGTMP/testhidden.py" >> $HGRCPATH
+  $ touch .hg/hidden
+  $ hg log --template='{rev}:{node}\n'
+  1:a765632148dc55d38c35c4f247c618701886cb2f
+  0:9f758d63dcde62d547ebfb08e1e7ee96535f2b05
+  $ echo a765632148dc55d38c35c4f247c618701886cb2f > .hg/hidden
+  $ hg log --template='{rev}:{node}\n'
+  0:9f758d63dcde62d547ebfb08e1e7ee96535f2b05
+  $ hg log --template='{rev}:{node}\n' --hidden
+  1:a765632148dc55d38c35c4f247c618701886cb2f
+  0:9f758d63dcde62d547ebfb08e1e7ee96535f2b05
Binary file tests/test-manifest.hg has changed
--- a/tests/test-manifest.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-manifest.t	Sat Jun 18 17:03:01 2011 -0500
@@ -10,7 +10,7 @@
 # hg ci -Amb -d'1 0'
 
   $ hg init
-  $ hg -q pull "$TESTDIR/test-manifest.hg"
+  $ hg -q pull "$TESTDIR/bundles/test-manifest.hg"
 
 The next call is expected to return nothing:
 
@@ -53,6 +53,10 @@
   b/a
   l
 
+  $ hg manifest --all
+  a
+  b/a
+  l
 
 The next two calls are expected to abort:
 
--- a/tests/test-merge-commit.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-merge-commit.t	Sat Jun 18 17:03:01 2011 -0500
@@ -34,7 +34,7 @@
 
   $ hg ci -m '3: merge with local rename'
 
-  $ hg debugindex .hg/store/data/bar.i
+  $ hg debugindex bar
      rev    offset  length   base linkrev nodeid       p1           p2
        0         0      77      0       2 d35118874825 000000000000 000000000000
        1        77      76      0       3 5345f5ab8abd 000000000000 d35118874825
@@ -42,7 +42,7 @@
   $ hg debugrename bar
   bar renamed from foo:9e25c27b87571a1edee5ae4dddee5687746cc8e2
 
-  $ hg debugindex .hg/store/data/foo.i
+  $ hg debugindex foo
      rev    offset  length   base linkrev nodeid       p1           p2
        0         0       7      0       0 690b295714ae 000000000000 000000000000
        1         7      13      1       1 9e25c27b8757 690b295714ae 000000000000
@@ -87,7 +87,7 @@
 
   $ hg ci -m '5: merge'
 
-  $ hg debugindex .hg/store/data/bar.i
+  $ hg debugindex bar
      rev    offset  length   base linkrev nodeid       p1           p2
        0         0      77      0       2 d35118874825 000000000000 000000000000
        1        77      76      0       3 5345f5ab8abd 000000000000 d35118874825
@@ -121,7 +121,7 @@
 
   $ hg ci -m '3: merge with remote rename'
 
-  $ hg debugindex .hg/store/data/bar.i
+  $ hg debugindex bar
      rev    offset  length   base linkrev nodeid       p1           p2
        0         0      77      0       2 d35118874825 000000000000 000000000000
        1        77      76      0       3 5345f5ab8abd 000000000000 d35118874825
@@ -129,7 +129,7 @@
   $ hg debugrename bar
   bar renamed from foo:9e25c27b87571a1edee5ae4dddee5687746cc8e2
 
-  $ hg debugindex .hg/store/data/foo.i
+  $ hg debugindex foo
      rev    offset  length   base linkrev nodeid       p1           p2
        0         0       7      0       0 690b295714ae 000000000000 000000000000
        1         7      13      1       1 9e25c27b8757 690b295714ae 000000000000
@@ -174,7 +174,7 @@
 
   $ hg ci -m '5: merge'
 
-  $ hg debugindex .hg/store/data/bar.i
+  $ hg debugindex bar
      rev    offset  length   base linkrev nodeid       p1           p2
        0         0      77      0       2 d35118874825 000000000000 000000000000
        1        77      76      0       3 5345f5ab8abd 000000000000 d35118874825
Binary file tests/test-merge-symlinks.hg has changed
--- a/tests/test-merge-symlinks.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-merge-symlinks.t	Sat Jun 18 17:03:01 2011 -0500
@@ -30,7 +30,7 @@
 
   $ hg init t
   $ cd t
-  $ hg -q pull "$TESTDIR/test-merge-symlinks.hg"
+  $ hg -q pull "$TESTDIR/bundles/test-merge-symlinks.hg"
   $ hg up -C 3
   3 files updated, 0 files merged, 0 files removed, 0 files unresolved
 
--- a/tests/test-merge1.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-merge1.t	Sat Jun 18 17:03:01 2011 -0500
@@ -12,9 +12,8 @@
   > EOF
   $ HGMERGE="python ../merge"; export HGMERGE
 
-  $ mkdir t
+  $ hg init t
   $ cd t
-  $ hg init
   $ echo This is file a1 > a
   $ hg add a
   $ hg commit -m "commit #0"
@@ -49,9 +48,8 @@
   M b
   $ cd ..; rm -r t
 
-  $ mkdir t
+  $ hg init t
   $ cd t
-  $ hg init
   $ echo This is file a1 > a
   $ hg add a
   $ hg commit -m "commit #0"
@@ -86,9 +84,8 @@
   M b
   $ cd ..; rm -r t
 
-  $ mkdir t
+  $ hg init t
   $ cd t
-  $ hg init
   $ echo This is file a1 > a
   $ hg add a
   $ hg commit -m "commit #0"
@@ -129,9 +126,8 @@
   M b
   $ cd ..; rm -r t
 
-  $ mkdir t
+  $ hg init t
   $ cd t
-  $ hg init
   $ echo This is file a1 > a
   $ hg add a
   $ hg commit -m "commit #0"
--- a/tests/test-merge2.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-merge2.t	Sat Jun 18 17:03:01 2011 -0500
@@ -1,6 +1,5 @@
-  $ mkdir t
+  $ hg init t
   $ cd t
-  $ hg init
   $ echo This is file a1 > a
   $ hg add a
   $ hg commit -m "commit #0"
@@ -34,9 +33,8 @@
   created new head
   $ cd ..; rm -r t
 
-  $ mkdir t
+  $ hg init t
   $ cd t
-  $ hg init
   $ echo This is file a1 > a
   $ hg add a
   $ hg commit -m "commit #0"
--- a/tests/test-merge5.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-merge5.t	Sat Jun 18 17:03:01 2011 -0500
@@ -14,7 +14,7 @@
   $ hg update 1
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
   $ hg update
-  abort: crosses branches (merge branches or use --check to force update)
+  abort: crosses branches (merge branches or update --check to force update)
   [255]
   $ hg update -c
   0 files updated, 0 files merged, 1 files removed, 0 files unresolved
--- a/tests/test-merge6.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-merge6.t	Sat Jun 18 17:03:01 2011 -0500
@@ -4,9 +4,8 @@
   > EOF
   $ HGMERGE="python ../merge"; export HGMERGE
 
-  $ mkdir A1
+  $ hg init A1
   $ cd A1
-  $ hg init
   $ echo This is file foo1 > foo
   $ echo This is file bar1 > bar
   $ hg add foo bar
--- a/tests/test-merge7.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-merge7.t	Sat Jun 18 17:03:01 2011 -0500
@@ -104,7 +104,7 @@
   >>>>>>> other
   three
 
-  $ hg debugindex .hg/store/data/test.txt.i
+  $ hg debugindex test.txt
      rev    offset  length   base linkrev nodeid       p1           p2
        0         0       7      0       0 01365c4cca56 000000000000 000000000000
        1         7       9      1       1 7b013192566a 01365c4cca56 000000000000
--- a/tests/test-mq-guards.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-mq-guards.t	Sat Jun 18 17:03:01 2011 -0500
@@ -63,7 +63,7 @@
 should fail
 
   $ hg qpush a.patch
-  cannot push 'a.patch' - guarded by ['+a']
+  cannot push 'a.patch' - guarded by '+a'
   [1]
 
   $ hg qguard a.patch
@@ -309,7 +309,7 @@
 
 qseries again, but with color
 
-  $ hg --config extensions.color= qseries -v --color=always
+  $ hg --config extensions.color= --config color.mode=ansi qseries -v --color=always
   0 G \x1b[0;30;1mnew.patch\x1b[0m (esc)
   1 G \x1b[0;30;1mb.patch\x1b[0m (esc)
   2 A \x1b[0;34;1;4mc.patch\x1b[0m (esc)
@@ -366,9 +366,9 @@
   3 G d.patch
   $ hg qpush -a
   applying new.patch
-  skipping b.patch - guarded by ['+2']
+  skipping b.patch - guarded by '+2'
   applying c.patch
-  skipping d.patch - guarded by ['+2']
+  skipping d.patch - guarded by '+2'
   now at: c.patch
   $ qappunappv
   % hg qapplied
@@ -432,5 +432,5 @@
 
 hg qseries -m with color
 
-  $ hg --config extensions.color= qseries -m --color=always
+  $ hg --config extensions.color= --config color.mode=ansi qseries -m --color=always
   \x1b[0;31;1mb.patch\x1b[0m (esc)
--- a/tests/test-mq-merge.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-mq-merge.t	Sat Jun 18 17:03:01 2011 -0500
@@ -130,7 +130,7 @@
   patch failed, unable to continue (try -v)
   patch failed, rejects left in working dir
   patch didn't work out, merging patcha
-  1 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
   0 files updated, 2 files merged, 0 files removed, 0 files unresolved
   (branch merge, don't forget to commit)
   applying patcha2
--- a/tests/test-mq-missingfiles.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-mq-missingfiles.t	Sat Jun 18 17:03:01 2011 -0500
@@ -102,7 +102,6 @@
   unable to find 'b' for patching
   1 out of 1 hunks FAILED -- saving rejects to file b.rej
   patch failed, unable to continue (try -v)
-  b: No such file or directory
   patch failed, rejects left in working dir
   errors during apply, please fix and refresh changeb
   [2]
--- a/tests/test-mq-qdelete.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-mq-qdelete.t	Sat Jun 18 17:03:01 2011 -0500
@@ -8,77 +8,77 @@
   $ hg ci -Ambase -d '1 0'
   adding base
 
-  $ hg qnew -d '1 0' a
-  $ hg qnew -d '1 0' b
-  $ hg qnew -d '1 0' c
+  $ hg qnew -d '1 0' pa
+  $ hg qnew -d '1 0' pb
+  $ hg qnew -d '1 0' pc
 
   $ hg qdel
   abort: qdelete requires at least one revision or patch name
   [255]
 
-  $ hg qdel c
-  abort: cannot delete applied patch c
+  $ hg qdel pc
+  abort: cannot delete applied patch pc
   [255]
 
   $ hg qpop
-  popping c
-  now at: b
+  popping pc
+  now at: pb
 
 Delete the same patch twice in one command (issue2427)
 
-  $ hg qdel c c
+  $ hg qdel pc pc
 
   $ hg qseries
-  a
-  b
+  pa
+  pb
 
   $ ls .hg/patches
-  a
-  b
+  pa
+  pb
   series
   status
 
   $ hg qpop
-  popping b
-  now at: a
+  popping pb
+  now at: pa
 
   $ hg qdel -k 1
 
   $ ls .hg/patches
-  a
-  b
+  pa
+  pb
   series
   status
 
-  $ hg qdel -r a
-  patch a finalized without changeset message
+  $ hg qdel -r pa
+  patch pa finalized without changeset message
 
   $ hg qapplied
 
   $ hg log --template '{rev} {desc}\n'
-  1 [mq]: a
+  1 [mq]: pa
   0 base
 
-  $ hg qnew d
-  $ hg qnew e
-  $ hg qnew f
+  $ hg qnew pd
+  $ hg qnew pe
+  $ hg qnew pf
 
-  $ hg qdel -r e
+  $ hg qdel -r pe
   abort: cannot delete revision 3 above applied patches
   [255]
 
-  $ hg qdel -r qbase:e
-  patch d finalized without changeset message
-  patch e finalized without changeset message
+  $ hg qdel -r qbase:pe
+  patch pd finalized without changeset message
+  patch pe finalized without changeset message
 
   $ hg qapplied
-  f
+  pf
 
   $ hg log --template '{rev} {desc}\n'
-  4 [mq]: f
-  3 [mq]: e
-  2 [mq]: d
-  1 [mq]: a
+  4 [mq]: pf
+  3 [mq]: pe
+  2 [mq]: pd
+  1 [mq]: pa
   0 base
 
   $ cd ..
@@ -97,53 +97,53 @@
   $ hg qfinish -a
   no patches applied
 
-  $ hg qnew -d '1 0' a
-  $ hg qnew -d '1 0' b
-  $ hg qnew c # XXX fails to apply by /usr/bin/patch if we put a date
+  $ hg qnew -d '1 0' pa
+  $ hg qnew -d '1 0' pb
+  $ hg qnew pc # XXX fails to apply by /usr/bin/patch if we put a date
 
   $ hg qfinish 0
   abort: revision 0 is not managed
   [255]
 
-  $ hg qfinish b
+  $ hg qfinish pb
   abort: cannot delete revision 2 above applied patches
   [255]
 
   $ hg qpop
-  popping c
-  now at: b
+  popping pc
+  now at: pb
 
-  $ hg qfinish -a c
-  abort: unknown revision 'c'!
+  $ hg qfinish -a pc
+  abort: unknown revision 'pc'!
   [255]
 
   $ hg qpush
-  applying c
-  patch c is empty
-  now at: c
+  applying pc
+  patch pc is empty
+  now at: pc
 
-  $ hg qfinish qbase:b
-  patch a finalized without changeset message
-  patch b finalized without changeset message
+  $ hg qfinish qbase:pb
+  patch pa finalized without changeset message
+  patch pb finalized without changeset message
 
   $ hg qapplied
-  c
+  pc
 
   $ hg log --template '{rev} {desc}\n'
-  3 imported patch c
-  2 [mq]: b
-  1 [mq]: a
+  3 imported patch pc
+  2 [mq]: pb
+  1 [mq]: pa
   0 base
 
-  $ hg qfinish -a c
-  patch c finalized without changeset message
+  $ hg qfinish -a pc
+  patch pc finalized without changeset message
 
   $ hg qapplied
 
   $ hg log --template '{rev} {desc}\n'
-  3 imported patch c
-  2 [mq]: b
-  1 [mq]: a
+  3 imported patch pc
+  2 [mq]: pb
+  1 [mq]: pa
   0 base
 
   $ ls .hg/patches
@@ -162,3 +162,33 @@
   adding 3.diff to series file
   $ hg qfinish -a
   no patches applied
+
+
+resilience to inconsistency: qfinish -a with applied patches not in series
+
+  $ hg qser
+  3.diff
+  $ hg qapplied
+  $ hg qpush
+  applying 3.diff
+  patch 3.diff is empty
+  now at: 3.diff
+  $ echo next >>  base
+  $ hg qrefresh -d '1 0'
+  $ echo > .hg/patches/series # remove 3.diff from series to confuse mq
+  $ hg qfinish -a
+  revision 47dfa8501675 refers to unknown patches: 3.diff
+
+more complex state 'both known and unknown patches
+
+  $ echo hip >>  base
+  $ hg qnew -f -d '1 0' -m 4 4.diff
+  $ echo hop >>  base
+  $ hg qnew -f -d '1 0' -m 5 5.diff
+  $ echo > .hg/patches/series # remove 4.diff and 5.diff from series to confuse mq
+  $ echo hup >>  base
+  $ hg qnew -f -d '1 0' -m 6 6.diff
+  $ hg qfinish -a
+  revision 2b1c98802260 refers to unknown patches: 5.diff
+  revision 33a6861311c0 refers to unknown patches: 4.diff
+
--- a/tests/test-mq-qimport.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-mq-qimport.t	Sat Jun 18 17:03:01 2011 -0500
@@ -202,3 +202,26 @@
   $ hg qser
   this-name-is-better
   url.diff
+
+qimport with bad name, should abort before reading file
+
+  $ hg qimport non-existant-file --name .hg
+  abort: patch name cannot begin with ".hg"
+  [255]
+
+qimport http:// patch with leading slashes in url
+
+set up hgweb
+
+  $ cd ..
+  $ hg init served
+  $ cd served
+  $ echo a > a
+  $ hg ci -Am patch
+  adding a
+  $ hg serve -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log
+  $ cat hg.pid >> $DAEMON_PIDS
+
+  $ cd ../repo
+  $ hg qimport http://localhost:$HGPORT/raw-rev/0///
+  adding 0 to series file
--- a/tests/test-mq-qnew.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-mq-qnew.t	Sat Jun 18 17:03:01 2011 -0500
@@ -106,10 +106,10 @@
   abort: "guards" cannot be used as the name of a patch
   abort: "." cannot be used as the name of a patch
   abort: ".." cannot be used as the name of a patch
-  abort: ".hgignore" cannot be used as the name of a patch
-  abort: ".mqfoo" cannot be used as the name of a patch
-  abort: "foo#bar" cannot be used as the name of a patch
-  abort: "foo:bar" cannot be used as the name of a patch
+  abort: patch name cannot begin with ".hg"
+  abort: patch name cannot begin with ".mq"
+  abort: "#" cannot be used in the name of a patch
+  abort: ":" cannot be used in the name of a patch
   % qnew with name containing slash
   abort: path ends in directory separator: foo/
   abort: "foo" already exists as a directory
@@ -173,10 +173,10 @@
   abort: "guards" cannot be used as the name of a patch
   abort: "." cannot be used as the name of a patch
   abort: ".." cannot be used as the name of a patch
-  abort: ".hgignore" cannot be used as the name of a patch
-  abort: ".mqfoo" cannot be used as the name of a patch
-  abort: "foo#bar" cannot be used as the name of a patch
-  abort: "foo:bar" cannot be used as the name of a patch
+  abort: patch name cannot begin with ".hg"
+  abort: patch name cannot begin with ".mq"
+  abort: "#" cannot be used in the name of a patch
+  abort: ":" cannot be used in the name of a patch
   % qnew with name containing slash
   abort: path ends in directory separator: foo/
   abort: "foo" already exists as a directory
--- a/tests/test-mq-qpush-exact.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-mq-qpush-exact.t	Sat Jun 18 17:03:01 2011 -0500
@@ -163,8 +163,12 @@
   $ hg update 1 -q
   $ echo c0 >> f0
   $ hg qpush -e
-  abort: local changes found, refresh first
-  [255]
+  applying p0
+  now at: p0
+  $ cat f0
+  c0
+  $ hg qpop -aq
+  patch queue now empty
   $ hg qpush -ef
   applying p0
   now at: p0
@@ -178,8 +182,13 @@
   $ hg update 1 -q
   $ echo c0 >> f0
   $ hg qpush -e p1
-  abort: local changes found, refresh first
-  [255]
+  applying p0
+  applying p1
+  now at: p1
+  $ cat f0
+  c0
+  $ hg qpop -aq
+  patch queue now empty
   $ hg qpush -e p1 -f
   applying p0
   applying p1
@@ -197,7 +206,7 @@
   $ echo cp0-bad >> fp0
   $ hg add fp0
   $ hg qpush -e
-  abort: local changes found, refresh first
+  abort: local changes found
   [255]
   $ hg qpush -ef
   applying p0
@@ -223,7 +232,7 @@
   $ echo cp1-bad >> fp1
   $ hg add fp1
   $ hg qpush -e p1
-  abort: local changes found, refresh first
+  abort: local changes found
   [255]
   $ hg qpush -e p1 -f
   applying p0
--- a/tests/test-mq-qpush-fail.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-mq-qpush-fail.t	Sat Jun 18 17:03:01 2011 -0500
@@ -122,7 +122,7 @@
 try to push and pop while a is guarded
 
   $ hg qpush a
-  cannot push 'a' - guarded by ['+block']
+  cannot push 'a' - guarded by '+block'
   [1]
   $ hg qpush -a
   applying b
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-mq-qrefresh-interactive.t	Sat Jun 18 17:03:01 2011 -0500
@@ -0,0 +1,348 @@
+Create configuration
+
+  $ echo "[ui]" >> $HGRCPATH
+  $ echo "interactive=true" >> $HGRCPATH
+
+help qrefresh (no record)
+
+  $ echo "[extensions]" >> $HGRCPATH
+  $ echo "mq=" >> $HGRCPATH
+  $ hg help qrefresh
+  hg qrefresh [-I] [-X] [-e] [-m TEXT] [-l FILE] [-s] [FILE]...
+  
+  update the current patch
+  
+      If any file patterns are provided, the refreshed patch will contain only
+      the modifications that match those patterns; the remaining modifications
+      will remain in the working directory.
+  
+      If -s/--short is specified, files currently included in the patch will be
+      refreshed just like matched files and remain in the patch.
+  
+      If -e/--edit is specified, Mercurial will start your configured editor for
+      you to enter a message. In case qrefresh fails, you will find a backup of
+      your message in ".hg/last-message.txt".
+  
+      hg add/remove/copy/rename work as usual, though you might want to use git-
+      style patches (-g/--git or [diff] git=1) to track copies and renames. See
+      the diffs help topic for more information on the git diff format.
+  
+      Returns 0 on success.
+  
+  options:
+  
+   -e --edit                 edit commit message
+   -g --git                  use git extended diff format
+   -s --short                refresh only files already in the patch and
+                             specified files
+   -U --currentuser          add/update author field in patch with current user
+   -u --user USER            add/update author field in patch with given user
+   -D --currentdate          add/update date field in patch with current date
+   -d --date DATE            add/update date field in patch with given date
+   -I --include PATTERN [+]  include names matching the given patterns
+   -X --exclude PATTERN [+]  exclude names matching the given patterns
+   -m --message TEXT         use text as commit message
+   -l --logfile FILE         read commit message from file
+  
+  [+] marked option can be specified multiple times
+  
+  use "hg -v help qrefresh" to show global options
+
+help qrefresh (record)
+
+  $ echo "record=" >> $HGRCPATH
+  $ hg help qrefresh
+  hg qrefresh [-I] [-X] [-e] [-m TEXT] [-l FILE] [-s] [FILE]...
+  
+  update the current patch
+  
+      If any file patterns are provided, the refreshed patch will contain only
+      the modifications that match those patterns; the remaining modifications
+      will remain in the working directory.
+  
+      If -s/--short is specified, files currently included in the patch will be
+      refreshed just like matched files and remain in the patch.
+  
+      If -e/--edit is specified, Mercurial will start your configured editor for
+      you to enter a message. In case qrefresh fails, you will find a backup of
+      your message in ".hg/last-message.txt".
+  
+      hg add/remove/copy/rename work as usual, though you might want to use git-
+      style patches (-g/--git or [diff] git=1) to track copies and renames. See
+      the diffs help topic for more information on the git diff format.
+  
+      Returns 0 on success.
+  
+  options:
+  
+   -e --edit                 edit commit message
+   -g --git                  use git extended diff format
+   -s --short                refresh only files already in the patch and
+                             specified files
+   -U --currentuser          add/update author field in patch with current user
+   -u --user USER            add/update author field in patch with given user
+   -D --currentdate          add/update date field in patch with current date
+   -d --date DATE            add/update date field in patch with given date
+   -I --include PATTERN [+]  include names matching the given patterns
+   -X --exclude PATTERN [+]  exclude names matching the given patterns
+   -m --message TEXT         use text as commit message
+   -l --logfile FILE         read commit message from file
+   -i --interactive          interactively select changes to refresh
+  
+  [+] marked option can be specified multiple times
+  
+  use "hg -v help qrefresh" to show global options
+
+  $ hg init a
+  $ cd a
+
+Base commit
+
+  $ cat > 1.txt <<EOF
+  > 1
+  > 2
+  > 3
+  > 4
+  > 5
+  > EOF
+  $ cat > 2.txt <<EOF
+  > a
+  > b
+  > c
+  > d
+  > e
+  > f
+  > EOF
+
+  $ mkdir dir
+  $ cat > dir/a.txt <<EOF
+  > hello world
+  > 
+  > someone
+  > up
+  > there
+  > loves
+  > me
+  > EOF
+
+  $ hg add 1.txt 2.txt dir/a.txt
+  $ hg commit -m aaa
+  $ hg qnew -d '0 0' patch
+
+Changing files
+
+  $ sed -e 's/2/2 2/;s/4/4 4/' 1.txt > 1.txt.new
+  $ sed -e 's/b/b b/' 2.txt > 2.txt.new
+  $ sed -e 's/hello world/hello world!/' dir/a.txt > dir/a.txt.new
+
+  $ mv -f 1.txt.new 1.txt
+  $ mv -f 2.txt.new 2.txt
+  $ mv -f dir/a.txt.new dir/a.txt
+
+Whole diff
+
+  $ hg diff --nodates
+  diff -r ed27675cb5df 1.txt
+  --- a/1.txt
+  +++ b/1.txt
+  @@ -1,5 +1,5 @@
+   1
+  -2
+  +2 2
+   3
+  -4
+  +4 4
+   5
+  diff -r ed27675cb5df 2.txt
+  --- a/2.txt
+  +++ b/2.txt
+  @@ -1,5 +1,5 @@
+   a
+  -b
+  +b b
+   c
+   d
+   e
+  diff -r ed27675cb5df dir/a.txt
+  --- a/dir/a.txt
+  +++ b/dir/a.txt
+  @@ -1,4 +1,4 @@
+  -hello world
+  +hello world!
+   
+   someone
+   up
+
+partial qrefresh
+
+  $ hg qrefresh -i -d '0 0' <<EOF
+  > y
+  > y
+  > n
+  > y
+  > y
+  > n
+  > EOF
+  diff --git a/1.txt b/1.txt
+  2 hunks, 2 lines changed
+  examine changes to '1.txt'? [Ynsfdaq?] 
+  @@ -1,3 +1,3 @@
+   1
+  -2
+  +2 2
+   3
+  record change 1/4 to '1.txt'? [Ynsfdaq?] 
+  @@ -3,3 +3,3 @@
+   3
+  -4
+  +4 4
+   5
+  record change 2/4 to '1.txt'? [Ynsfdaq?] 
+  diff --git a/2.txt b/2.txt
+  1 hunks, 1 lines changed
+  examine changes to '2.txt'? [Ynsfdaq?] 
+  @@ -1,5 +1,5 @@
+   a
+  -b
+  +b b
+   c
+   d
+   e
+  record change 3/4 to '2.txt'? [Ynsfdaq?] 
+  diff --git a/dir/a.txt b/dir/a.txt
+  1 hunks, 1 lines changed
+  examine changes to 'dir/a.txt'? [Ynsfdaq?] 
+
+After partial qrefresh 'tip'
+
+  $ hg tip -p
+  changeset:   1:0738af1a8211
+  tag:         patch
+  tag:         qbase
+  tag:         qtip
+  tag:         tip
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     [mq]: patch
+  
+  diff -r 1fd39ab63a33 -r 0738af1a8211 1.txt
+  --- a/1.txt	Thu Jan 01 00:00:00 1970 +0000
+  +++ b/1.txt	Thu Jan 01 00:00:00 1970 +0000
+  @@ -1,5 +1,5 @@
+   1
+  -2
+  +2 2
+   3
+   4
+   5
+  diff -r 1fd39ab63a33 -r 0738af1a8211 2.txt
+  --- a/2.txt	Thu Jan 01 00:00:00 1970 +0000
+  +++ b/2.txt	Thu Jan 01 00:00:00 1970 +0000
+  @@ -1,5 +1,5 @@
+   a
+  -b
+  +b b
+   c
+   d
+   e
+  
+After partial qrefresh 'diff'
+
+  $ hg diff --nodates
+  diff -r 0738af1a8211 1.txt
+  --- a/1.txt
+  +++ b/1.txt
+  @@ -1,5 +1,5 @@
+   1
+   2 2
+   3
+  -4
+  +4 4
+   5
+  diff -r 0738af1a8211 dir/a.txt
+  --- a/dir/a.txt
+  +++ b/dir/a.txt
+  @@ -1,4 +1,4 @@
+  -hello world
+  +hello world!
+   
+   someone
+   up
+
+qrefresh interactively everything else
+
+  $ hg qrefresh -i -d '0 0' <<EOF
+  > y
+  > y
+  > y
+  > y
+  > EOF
+  diff --git a/1.txt b/1.txt
+  1 hunks, 1 lines changed
+  examine changes to '1.txt'? [Ynsfdaq?] 
+  @@ -1,5 +1,5 @@
+   1
+   2 2
+   3
+  -4
+  +4 4
+   5
+  record change 1/2 to '1.txt'? [Ynsfdaq?] 
+  diff --git a/dir/a.txt b/dir/a.txt
+  1 hunks, 1 lines changed
+  examine changes to 'dir/a.txt'? [Ynsfdaq?] 
+  @@ -1,4 +1,4 @@
+  -hello world
+  +hello world!
+   
+   someone
+   up
+  record change 2/2 to 'dir/a.txt'? [Ynsfdaq?] 
+
+After final qrefresh 'tip'
+
+  $ hg tip -p
+  changeset:   1:2c3f66afeed9
+  tag:         patch
+  tag:         qbase
+  tag:         qtip
+  tag:         tip
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     [mq]: patch
+  
+  diff -r 1fd39ab63a33 -r 2c3f66afeed9 1.txt
+  --- a/1.txt	Thu Jan 01 00:00:00 1970 +0000
+  +++ b/1.txt	Thu Jan 01 00:00:00 1970 +0000
+  @@ -1,5 +1,5 @@
+   1
+  -2
+  +2 2
+   3
+  -4
+  +4 4
+   5
+  diff -r 1fd39ab63a33 -r 2c3f66afeed9 2.txt
+  --- a/2.txt	Thu Jan 01 00:00:00 1970 +0000
+  +++ b/2.txt	Thu Jan 01 00:00:00 1970 +0000
+  @@ -1,5 +1,5 @@
+   a
+  -b
+  +b b
+   c
+   d
+   e
+  diff -r 1fd39ab63a33 -r 2c3f66afeed9 dir/a.txt
+  --- a/dir/a.txt	Thu Jan 01 00:00:00 1970 +0000
+  +++ b/dir/a.txt	Thu Jan 01 00:00:00 1970 +0000
+  @@ -1,4 +1,4 @@
+  -hello world
+  +hello world!
+   
+   someone
+   up
+  
+
+After qrefresh 'diff'
+
+  $ hg diff --nodates
--- a/tests/test-mq-qrefresh.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-mq-qrefresh.t	Sat Jun 18 17:03:01 2011 -0500
@@ -502,6 +502,7 @@
   refresh interrupted while patch was popped! (revert --all, qpush to recover)
   abort: username 'foo\nbar' contains a newline!
   [255]
+  $ rm a
   $ cat .hg/patches/a
   # HG changeset patch
   # Parent 0000000000000000000000000000000000000000
--- a/tests/test-mq-strip.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-mq-strip.t	Sat Jun 18 17:03:01 2011 -0500
@@ -410,7 +410,7 @@
   abort: local changes found
   [255]
   $ hg strip tip --keep
-  saved backup bundle to * (glob)
+  saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
   $ hg log --graph
   @  changeset:   0:9ab35a2d17cb
      tag:         tip
--- a/tests/test-mq-symlinks.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-mq-symlinks.t	Sat Jun 18 17:03:01 2011 -0500
@@ -106,16 +106,3 @@
   now at: movelink
   $ $TESTDIR/readlink.py linkb
   linkb -> linkb
-
-check patch does not overwrite untracked symlinks
-
-  $ hg qpop
-  popping movelink
-  now at: link
-  $ ln -s linkbb linkb
-  $ hg qpush
-  applying movelink
-  patch failed, unable to continue (try -v)
-  patch failed, rejects left in working dir
-  errors during apply, please fix and refresh movelink
-  [2]
--- a/tests/test-mq.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-mq.t	Sat Jun 18 17:03:01 2011 -0500
@@ -177,7 +177,7 @@
 
 status --mq with color (issue2096)
 
-  $ hg status --mq --config extensions.color= --color=always
+  $ hg status --mq --config extensions.color= --config color.mode=ansi --color=always
   \x1b[0;32;1mA .hgignore\x1b[0m (esc)
   \x1b[0;32;1mA A\x1b[0m (esc)
   \x1b[0;32;1mA B\x1b[0m (esc)
@@ -460,7 +460,7 @@
   $ hg qguard test1b.patch -- -negguard
   $ hg qguard test2.patch -- +posguard
   $ hg qpush --move test2.patch # can't move guarded patch
-  cannot push 'test2.patch' - guarded by ['+posguard']
+  cannot push 'test2.patch' - guarded by '+posguard'
   [1]
   $ hg qselect posguard
   number of unguarded, unapplied patches has changed from 2 to 3
@@ -843,6 +843,14 @@
   1 foo qbase
   2 bar qtip tip
 
+mq revset
+
+  $ hg log -r 'mq()' --template '{rev}\n'
+  1
+  2
+  $ hg help revsets | grep -i mq
+      "mq()"
+        Changesets managed by MQ.
 
 bad node in status
 
@@ -1251,6 +1259,64 @@
   now at: changea
   $ cd ..
 
+test qpop with local changes, issue2780
+
+  $ hg init forcepop
+  $ cd forcepop
+  $ echo 1 > 1
+  $ hg ci -Am 1
+  adding 1
+  $ hg qnew foo
+  $ echo 2 > 2
+  $ hg add
+  adding 2
+
+unrelated changes
+
+  $ hg qpop
+  popping foo
+  patch queue now empty
+
+related changes
+
+  $ hg forget 2
+  $ rm 2
+  $ hg qpush
+  applying foo
+  patch foo is empty
+  now at: foo
+  $ echo 2 >> 1
+  $ hg qrefresh
+  $ echo 2 >> 1
+  $ hg qpop
+  abort: local changes found, refresh first
+  [255]
+  $ hg st
+  M 1
+
+related changes with force
+  $ hg qpop --force
+  popping foo
+  patch queue now empty
+  $ hg st
+
+related renamed source without change
+  $ hg qpush
+  applying foo
+  now at: foo
+  $ echo 1 > 1
+  $ hg mv 1 2
+  $ hg qref --git
+  $ hg qpop
+  popping foo
+  patch queue now empty
+  $ echo 3 > 1
+  $ hg st
+  M 1
+  $ hg qpush
+  abort: local changes found
+  [255]
+  $ cd ..
 
 test qpush with --force, issue1087
 
@@ -1268,21 +1334,14 @@
   $ echo world >> hello.txt
 
 
-qpush should fail, local changes
+apply, should not discard changes with empty patch
 
   $ hg qpush
-  abort: local changes found, refresh first
-  [255]
-
-
-apply force, should not discard changes with empty patch
-
-  $ hg qpush -f
   applying empty
   patch empty is empty
   now at: empty
   $ hg diff --config diff.nodates=True
-  diff -r bf5fc3f07a0a hello.txt
+  diff -r d58265112590 hello.txt
   --- a/hello.txt
   +++ b/hello.txt
   @@ -1,1 +1,2 @@
@@ -1296,7 +1355,7 @@
    hello
   +world
   $ hg log -l1 -p
-  changeset:   1:bf5fc3f07a0a
+  changeset:   1:d58265112590
   tag:         empty
   tag:         qbase
   tag:         qtip
@@ -1317,7 +1376,7 @@
 qpush should fail, local changes
 
   $ hg qpush
-  abort: local changes found, refresh first
+  abort: local changes found
   [255]
 
 
--- a/tests/test-nested-repo.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-nested-repo.t	Sat Jun 18 17:03:01 2011 -0500
@@ -11,16 +11,16 @@
 Should fail:
 
   $ hg st b/x
-  abort: path 'b/x' is inside repo 'b'
+  abort: path 'b/x' is inside nested repo 'b'
   [255]
   $ hg add b/x
-  abort: path 'b/x' is inside repo 'b'
+  abort: path 'b/x' is inside nested repo 'b'
   [255]
 
 Should fail:
 
   $ hg add b b/x
-  abort: path 'b/x' is inside repo 'b'
+  abort: path 'b/x' is inside nested repo 'b'
   [255]
   $ hg st
 
@@ -34,7 +34,7 @@
 Should fail:
 
   $ hg mv a b
-  abort: path 'b/a' is inside repo 'b'
+  abort: path 'b/a' is inside nested repo 'b'
   [255]
   $ hg st
 
--- a/tests/test-newbranch.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-newbranch.t	Sat Jun 18 17:03:01 2011 -0500
@@ -19,7 +19,8 @@
 Branch shadowing:
 
   $ hg branch default
-  abort: a branch of the same name already exists (use 'hg update' to switch to it)
+  abort: a branch of the same name already exists
+  (use 'hg update' to switch to it)
   [255]
 
   $ hg branch -f default
@@ -31,7 +32,7 @@
 There should be only one default branch head
 
   $ hg heads .
-  changeset:   3:9d567d0b51f9
+  changeset:   3:1c28f494dae6
   tag:         tip
   user:        test
   date:        Thu Jan 01 00:00:00 1970 +0000
@@ -54,34 +55,34 @@
   $ hg ci -m "merge"
 
   $ hg log
-  changeset:   5:dc140083783b
+  changeset:   5:530046499edf
   branch:      foo
   tag:         tip
-  parent:      4:98d14f698afe
-  parent:      3:9d567d0b51f9
+  parent:      4:adf1a74a7f7b
+  parent:      3:1c28f494dae6
   user:        test
   date:        Thu Jan 01 00:00:00 1970 +0000
   summary:     merge
   
-  changeset:   4:98d14f698afe
+  changeset:   4:adf1a74a7f7b
   branch:      foo
-  parent:      1:0079f24813e2
+  parent:      1:6c0e42da283a
   user:        test
   date:        Thu Jan 01 00:00:00 1970 +0000
   summary:     modify a branch
   
-  changeset:   3:9d567d0b51f9
+  changeset:   3:1c28f494dae6
   user:        test
   date:        Thu Jan 01 00:00:00 1970 +0000
   summary:     clear branch name
   
-  changeset:   2:ed2bbf4e0102
+  changeset:   2:c21617b13b22
   branch:      bar
   user:        test
   date:        Thu Jan 01 00:00:00 1970 +0000
   summary:     change branch name
   
-  changeset:   1:0079f24813e2
+  changeset:   1:6c0e42da283a
   branch:      foo
   user:        test
   date:        Thu Jan 01 00:00:00 1970 +0000
@@ -93,9 +94,9 @@
   summary:     initial
   
   $ hg branches
-  foo                            5:dc140083783b
-  default                        3:9d567d0b51f9 (inactive)
-  bar                            2:ed2bbf4e0102 (inactive)
+  foo                            5:530046499edf
+  default                        3:1c28f494dae6 (inactive)
+  bar                            2:c21617b13b22 (inactive)
 
   $ hg branches -q
   foo
@@ -111,10 +112,10 @@
   $ cp $branchcache .hg/bc-invalid
 
   $ hg log -r foo
-  changeset:   4:98d14f698afe
+  changeset:   4:adf1a74a7f7b
   branch:      foo
   tag:         tip
-  parent:      1:0079f24813e2
+  parent:      1:6c0e42da283a
   user:        test
   date:        Thu Jan 01 00:00:00 1970 +0000
   summary:     modify a branch
@@ -123,12 +124,12 @@
 
   $ hg --debug log -r foo
   invalidating branch cache (tip differs)
-  changeset:   4:98d14f698afeaff8cb612dcf215ce95e639effc3
+  changeset:   4:adf1a74a7f7b4cd193d12992f5d0d6a004ed21d6
   branch:      foo
   tag:         tip
-  parent:      1:0079f24813e2b73a891577c243684c5066347bc8
+  parent:      1:6c0e42da283a56b5edc5b4fadb491365ec7f5fa8
   parent:      -1:0000000000000000000000000000000000000000
-  manifest:    4:d01b250baaa05909152f7ae07d7a649deea0df9a
+  manifest:    1:8c342a37dfba0b3d3ce073562a00d8a813c54ffe
   user:        test
   date:        Thu Jan 01 00:00:00 1970 +0000
   files:       a
@@ -141,13 +142,13 @@
   $ echo corrupted > $branchcache
 
   $ hg log -qr foo
-  4:98d14f698afe
+  4:adf1a74a7f7b
 
   $ cat $branchcache
-  98d14f698afeaff8cb612dcf215ce95e639effc3 4
-  9d567d0b51f9e2068b054e1948e1a927f99b5874 default
-  98d14f698afeaff8cb612dcf215ce95e639effc3 foo
-  ed2bbf4e01029020711be82ca905283e883f0e11 bar
+  adf1a74a7f7b4cd193d12992f5d0d6a004ed21d6 4
+  1c28f494dae69a2f8fc815059d257eccf3fcfe75 default
+  adf1a74a7f7b4cd193d12992f5d0d6a004ed21d6 foo
+  c21617b13b220988e7a2e26290fbe4325ffa7139 bar
 
 Push should update the branch cache:
 
@@ -166,22 +167,22 @@
   $ hg push -qf ../target
 
   $ cat ../target/$branchcache
-  98d14f698afeaff8cb612dcf215ce95e639effc3 4
-  9d567d0b51f9e2068b054e1948e1a927f99b5874 default
-  98d14f698afeaff8cb612dcf215ce95e639effc3 foo
-  ed2bbf4e01029020711be82ca905283e883f0e11 bar
+  adf1a74a7f7b4cd193d12992f5d0d6a004ed21d6 4
+  1c28f494dae69a2f8fc815059d257eccf3fcfe75 default
+  adf1a74a7f7b4cd193d12992f5d0d6a004ed21d6 foo
+  c21617b13b220988e7a2e26290fbe4325ffa7139 bar
 
 Update with no arguments: tipmost revision of the current branch:
 
   $ hg up -q -C 0
   $ hg up -q
   $ hg id
-  9d567d0b51f9
+  1c28f494dae6
 
   $ hg up -q 1
   $ hg up -q
   $ hg id
-  98d14f698afe (foo) tip
+  adf1a74a7f7b (foo) tip
 
   $ hg branch foobar
   marked working directory as branch foobar
@@ -210,11 +211,11 @@
   foo
   $ hg commit -m'Merge ff into foo'
   $ hg parents
-  changeset:   6:917eb54e1b4b
+  changeset:   6:185ffbfefa30
   branch:      foo
   tag:         tip
-  parent:      4:98d14f698afe
-  parent:      5:6683a60370cb
+  parent:      4:adf1a74a7f7b
+  parent:      5:1a3c27dc5e11
   user:        test
   date:        Thu Jan 01 00:00:00 1970 +0000
   summary:     Merge ff into foo
Binary file tests/test-no-symlinks.hg has changed
--- a/tests/test-no-symlinks.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-no-symlinks.t	Sat Jun 18 17:03:01 2011 -0500
@@ -16,7 +16,7 @@
 
   $ hg init t
   $ cd t
-  $ hg pull -q "$TESTDIR/test-no-symlinks.hg"
+  $ hg pull -q "$TESTDIR/bundles/test-no-symlinks.hg"
   $ hg update
   4 files updated, 0 files merged, 0 files removed, 0 files unresolved
   $ cat a.lnk && echo
--- a/tests/test-notify.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-notify.t	Sat Jun 18 17:03:01 2011 -0500
@@ -32,6 +32,8 @@
     incoming.notify = python:hgext.notify.hook
     # batch emails when many changesets incoming at one time
     changegroup.notify = python:hgext.notify.hook
+    # batch emails when many changesets outgoing at one time (client side)
+    outgoing.notify = python:hgext.notify.hook
   
     [notify]
     # config items go here
@@ -48,7 +50,8 @@
     style = ...            # style file to use when formatting email
     template = ...         # template to use when formatting email
     incoming = ...         # template to use when run as incoming hook
-    changegroup = ...      # template when run as changegroup hook
+    outgoing = ...         # template to use when run as outgoing hook
+    changegroup = ...      # template to use when run as changegroup hook
     maxdiff = 300          # max lines of diffs to include (0=none, -1=all)
     maxsubject = 67        # truncate subject line longer than this
     diffstat = True        # add a diffstat before the diff content
@@ -298,11 +301,11 @@
   Date: * (glob)
   Subject: merge
   From: test@test.com
-  X-Hg-Notification: changeset 22c88b85aa27
+  X-Hg-Notification: changeset 6a0cf76b2701
   Message-Id: <*> (glob)
   To: baz@test.com, foo@bar
   
-  changeset 22c88b85aa27 in b
+  changeset 6a0cf76b2701 in b
   description: merge
   (run 'hg update' to get a working copy)
 
@@ -330,11 +333,11 @@
   Date: * (glob)
   Subject: \xc3\xa0... (esc)
   From: test@test.com
-  X-Hg-Notification: changeset 4a47f01c1356
+  X-Hg-Notification: changeset 7ea05ad269dc
   Message-Id: <*> (glob)
   To: baz@test.com, foo@bar
   
-  changeset 4a47f01c1356 in b
+  changeset 7ea05ad269dc in b
   description: \xc3\xa0\xc3\xa1\xc3\xa2\xc3\xa3\xc3\xa4 (esc)
   diffstat:
   
@@ -343,7 +346,7 @@
   
   diffs (7 lines):
   
-  diff -r 22c88b85aa27 -r 4a47f01c1356 a
+  diff -r 6a0cf76b2701 -r 7ea05ad269dc a
   --- a/a	Thu Jan 01 00:00:03 1970 +0000
   +++ b/a	Thu Jan 01 00:00:00 1970 +0000
   @@ -1,2 +1,3 @@
--- a/tests/test-parentrevspec.t	Wed Jun 01 16:32:48 2011 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,105 +0,0 @@
-
-  $ commit()
-  > {
-  >     msg=$1
-  >     p1=$2
-  >     p2=$3
-  > 
-  >     if [ "$p1" ]; then
-  >         hg up -qC $p1
-  >     fi
-  > 
-  >     if [ "$p2" ]; then
-  >         HGMERGE=true hg merge -q $p2
-  >     fi
-  > 
-  >     echo >> foo
-  > 
-  >     hg commit -qAm "$msg"
-  > }
-  $ hg init repo
-  $ cd repo
-  $ echo '[extensions]' > .hg/hgrc
-  $ echo 'parentrevspec =' >> .hg/hgrc
-  $ commit '0: add foo'
-  $ commit '1: change foo 1'
-  $ commit '2: change foo 2a'
-  $ commit '3: change foo 3a'
-  $ commit '4: change foo 2b' 1
-  $ commit '5: merge' 3 4
-  $ commit '6: change foo again'
-  $ hg log --template '{rev}:{node|short} {parents}\n'
-  6:755d1e0d79e9 
-  5:9ce2ce29723a 3:a3e00c7dbf11 4:bb4475edb621 
-  4:bb4475edb621 1:5d953a1917d1 
-  3:a3e00c7dbf11 
-  2:befc7d89d081 
-  1:5d953a1917d1 
-  0:837088b6e1d9 
-  $ echo
-  
-  $ lookup()
-  > {
-  >     for rev in "$@"; do
-  >         printf "$rev: "
-  >         hg id -nr $rev
-  >     done
-  >     true
-  > }
-  $ tipnode=`hg id -ir tip`
-
-should work with tag/branch/node/rev
-
-  $ for r in tip default $tipnode 6; do
-  >     lookup "$r^"
-  > done
-  tip^: 5
-  default^: 5
-  755d1e0d79e9^: 5
-  6^: 5
-  $ echo
-  
-
-some random lookups
-
-  $ lookup "6^^" "6^^^" "6^^^^" "6^^^^^" "6^^^^^^" "6^1" "6^2" "6^^2" "6^1^2" "6^^3"
-  6^^: 3
-  6^^^: 2
-  6^^^^: 1
-  6^^^^^: 0
-  6^^^^^^: -1
-  6^1: 5
-  6^2: hg: parse error at 1: syntax error
-  6^^2: 4
-  6^1^2: 4
-  6^^3: hg: parse error at 1: syntax error
-  $ lookup "6~" "6~1" "6~2" "6~3" "6~4" "6~5" "6~42" "6~1^2" "6~1^2~2"
-  6~: hg: parse error at 1: syntax error
-  6~1: 5
-  6~2: 3
-  6~3: 2
-  6~4: 1
-  6~5: 0
-  6~42: -1
-  6~1^2: 4
-  6~1^2~2: 0
-  $ echo
-  
-
-with a tag "6^" pointing to rev 1
-
-  $ hg tag -l -r 1 "6^"
-  $ lookup "6^" "6^1" "6~1" "6^^"
-  6^: 1
-  6^1: 5
-  6~1: 5
-  6^^: 3
-  $ echo
-  
-
-with a tag "foo^bar" pointing to rev 2
-
-  $ hg tag -l -r 2 "foo^bar"
-  $ lookup "foo^bar" "foo^bar^"
-  foo^bar: 2
-  foo^bar^: hg: parse error at 3: syntax error
--- a/tests/test-parse-date.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-parse-date.t	Sat Jun 18 17:03:01 2011 -0500
@@ -96,52 +96,32 @@
 Test date formats with '>' or '<' accompanied by space characters
 
   $ hg log -d '>' --template '{date|date}\n'
-  Sun Jan 15 13:30:00 2006 +0500
-  Sun Jan 15 13:30:00 2006 -0800
-  Sat Jul 15 13:30:00 2006 +0500
-  Sat Jul 15 13:30:00 2006 -0700
-  Sun Jun 11 00:26:40 2006 -0400
-  Sat Apr 15 13:30:00 2006 +0200
-  Sat Apr 15 13:30:00 2006 +0000
-  Wed Feb 01 13:00:30 2006 -0500
-  Wed Feb 01 13:00:30 2006 +0000
+  abort: invalid day spec, use '>DATE'
+  [255]
   $ hg log -d '<' hg log -d '>' --template '{date|date}\n'
+  abort: invalid day spec, use '>DATE'
+  [255]
 
   $ hg log -d ' >' --template '{date|date}\n'
-  Sun Jan 15 13:30:00 2006 +0500
-  Sun Jan 15 13:30:00 2006 -0800
-  Sat Jul 15 13:30:00 2006 +0500
-  Sat Jul 15 13:30:00 2006 -0700
-  Sun Jun 11 00:26:40 2006 -0400
-  Sat Apr 15 13:30:00 2006 +0200
-  Sat Apr 15 13:30:00 2006 +0000
-  Wed Feb 01 13:00:30 2006 -0500
-  Wed Feb 01 13:00:30 2006 +0000
+  abort: invalid day spec, use '>DATE'
+  [255]
   $ hg log -d ' <' --template '{date|date}\n'
+  abort: invalid day spec, use '<DATE'
+  [255]
 
   $ hg log -d '> ' --template '{date|date}\n'
-  Sun Jan 15 13:30:00 2006 +0500
-  Sun Jan 15 13:30:00 2006 -0800
-  Sat Jul 15 13:30:00 2006 +0500
-  Sat Jul 15 13:30:00 2006 -0700
-  Sun Jun 11 00:26:40 2006 -0400
-  Sat Apr 15 13:30:00 2006 +0200
-  Sat Apr 15 13:30:00 2006 +0000
-  Wed Feb 01 13:00:30 2006 -0500
-  Wed Feb 01 13:00:30 2006 +0000
+  abort: invalid day spec, use '>DATE'
+  [255]
   $ hg log -d '< ' --template '{date|date}\n'
+  abort: invalid day spec, use '<DATE'
+  [255]
 
   $ hg log -d ' > ' --template '{date|date}\n'
-  Sun Jan 15 13:30:00 2006 +0500
-  Sun Jan 15 13:30:00 2006 -0800
-  Sat Jul 15 13:30:00 2006 +0500
-  Sat Jul 15 13:30:00 2006 -0700
-  Sun Jun 11 00:26:40 2006 -0400
-  Sat Apr 15 13:30:00 2006 +0200
-  Sat Apr 15 13:30:00 2006 +0000
-  Wed Feb 01 13:00:30 2006 -0500
-  Wed Feb 01 13:00:30 2006 +0000
+  abort: invalid day spec, use '>DATE'
+  [255]
   $ hg log -d ' < ' --template '{date|date}\n'
+  abort: invalid day spec, use '<DATE'
+  [255]
 
   $ hg log -d '>02/01' --template '{date|date}\n'
   $ hg log -d '<02/01' --template '{date|date}\n'
--- a/tests/test-parseindex.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-parseindex.t	Sat Jun 18 17:03:01 2011 -0500
@@ -26,7 +26,7 @@
   summary:     change foo
   
   $ cat >> test.py << EOF
-  > from mercurial import changelog, util
+  > from mercurial import changelog, scmutil
   > from mercurial.node import *
   > 
   > class singlebyteread(object):
@@ -42,7 +42,7 @@
   >         return getattr(self.real, key)
   > 
   > def opener(*args):
-  >     o = util.opener(*args)
+  >     o = scmutil.opener(*args)
   >     def wrapper(*a):
   >         f = o(*a)
   >         return singlebyteread(f)
--- a/tests/test-patchbomb.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-patchbomb.t	Sat Jun 18 17:03:01 2011 -0500
@@ -158,16 +158,30 @@
 
   $ hg email -m test.mbox -f quux -t foo -c bar -s test 0:tip \
   > --config extensions.progress= --config progress.assume-tty=1 \
-  > --config progress.delay=0 --config progress.refresh=0
+  > --config progress.delay=0 --config progress.refresh=0 \
+  > --config progress.width=60 2>&1 | \
+  > python $TESTDIR/filtercr.py
   This patch series consists of 2 patches.
   
   
   Write the introductory message for the patch series.
   
-  \rwriting [                                                                 ] 0/3\rwriting [                                                                 ] 0/3\r                                                                                \r\r                                                                                \r\rwriting [====================>                                            ] 1/3\rwriting [====================>                                            ] 1/3\r                                                                                \r\r                                                                                \r\rwriting [==========================================>                      ] 2/3\rwriting [==========================================>                      ] 2/3\r                                                                                \r (esc)
+  
+  writing [                                             ] 0/3
+  writing [                                             ] 0/3
+                                                              
+                                                              
+  writing [==============>                              ] 1/3
+  writing [==============>                              ] 1/3
+                                                              
+                                                              
+  writing [=============================>               ] 2/3
+  writing [=============================>               ] 2/3
+                                                              \r (esc)
   Writing [PATCH 0 of 2] test ...
   Writing [PATCH 1 of 2] a ...
   Writing [PATCH 2 of 2] b ...
+  
 
   $ cd ..
 
--- a/tests/test-paths.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-paths.t	Sat Jun 18 17:03:01 2011 -0500
@@ -25,3 +25,34 @@
   $ SOMETHING=/foo hg paths
   dupe = $TESTTMP/b
   expand = /foo/bar
+  $ hg paths -q
+  dupe
+  expand
+  $ hg paths dupe
+  $TESTTMP/b
+  $ hg paths -q dupe
+  $ hg paths unknown
+  not found!
+  [1]
+  $ hg paths -q unknown
+  [1]
+  $ cd ..
+
+'file:' disables [paths] entries for clone destination
+
+  $ cat >> $HGRCPATH <<EOF
+  > [paths]
+  > gpath1 = http://hg.example.com
+  > EOF
+
+  $ hg clone a gpath1
+  abort: cannot create new http repository
+  [255]
+
+  $ hg clone a file:gpath1
+  updating to branch default
+  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ cd gpath1
+  $ hg -q id
+  000000000000
+
--- a/tests/test-pull-branch.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-pull-branch.t	Sat Jun 18 17:03:01 2011 -0500
@@ -131,6 +131,81 @@
   adding manifests
   adding file changes
   added 4 changesets with 4 changes to 1 files (+1 heads)
-  not updating, since new heads added
-  (run 'hg heads' to see heads, 'hg merge' to merge)
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+
+Make changes on new branch on tt
+
+  $ hg up 6
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ hg branch branchC
+  marked working directory as branch branchC
+  $ echo b1 > bar 
+  $ hg ci -Am "commit on branchC on tt"
+  adding bar
+
+Make changes on default branch on t
+
+  $ cd ../t
+  $ hg up -C default
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ echo a1 > bar 
+  $ hg ci -Am "commit on default on t"
+  adding bar
+
+Pull branchC from tt
+
+  $ hg pull ../tt
+  pulling from ../tt
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 1 changes to 1 files (+1 heads)
+  (run 'hg heads' to see heads)
+
+Make changes on default and branchC on tt
 
+  $ cd ../tt
+  $ hg pull ../t
+  pulling from ../t
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 1 changes to 1 files (+1 heads)
+  (run 'hg heads' to see heads)
+  $ hg up -C default
+  2 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ echo a1 > bar1
+  $ hg ci -Am "commit on default on tt"
+  adding bar1
+  $ hg up branchC
+  2 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ echo a1 > bar2
+  $ hg ci -Am "commit on branchC on tt"
+  adding bar2
+
+Make changes on default and branchC on t
+
+  $ cd ../t
+  $ hg up default
+  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ echo a1 > bar3
+  $ hg ci -Am "commit on default on t"
+  adding bar3
+  $ hg up branchC
+  2 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ echo a1 > bar4
+  $ hg ci -Am "commit on branchC on tt"
+  adding bar4
+
+Pull from tt
+
+  $ hg pull ../tt
+  pulling from ../tt
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 2 changesets with 2 changes to 2 files (+2 heads)
+  (run 'hg heads .' to see heads, 'hg merge' to merge)
--- a/tests/test-pull-permission.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-pull-permission.t	Sat Jun 18 17:03:01 2011 -0500
@@ -1,6 +1,5 @@
-  $ mkdir a
+  $ hg init a
   $ cd a
-  $ hg init
   $ echo foo > b
   $ hg add b
   $ hg ci -m "b"
--- a/tests/test-pull-r.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-pull-r.t	Sat Jun 18 17:03:01 2011 -0500
@@ -27,6 +27,36 @@
   summary:     add foo
   
   $ cd ..
+
+don't show "(+1 heads)" message when pulling closed head
+
+  $ hg clone -q repo repo2
+  $ hg clone -q repo2 repo3
+  $ cd repo2
+  $ hg up -q 0
+  $ echo hello >> foo
+  $ hg ci -mx1
+  created new head
+  $ hg ci -mx2 --close-branch
+  $ cd ../repo3
+  $ hg heads -q --closed
+  2:effea6de0384
+  1:ed1b79f46b9a
+  $ hg pull
+  pulling from $TESTTMP/repo2
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 2 changesets with 1 changes to 1 files
+  (run 'hg update' to get a working copy)
+  $ hg heads -q --closed
+  4:00cfe9073916
+  2:effea6de0384
+  1:ed1b79f46b9a
+
+  $ cd ..
+
   $ hg init copy
   $ cd copy
 
--- a/tests/test-pull-update.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-pull-update.t	Sat Jun 18 17:03:01 2011 -0500
@@ -25,8 +25,7 @@
   adding manifests
   adding file changes
   added 1 changesets with 1 changes to 1 files (+1 heads)
-  not updating, since new heads added
-  (run 'hg heads' to see heads, 'hg merge' to merge)
+  not updating: crosses branches (merge branches or update --check to force update)
 
   $ cd ../tt
 
@@ -39,8 +38,7 @@
   adding manifests
   adding file changes
   added 1 changesets with 1 changes to 1 files (+1 heads)
-  not updating, since new heads added
-  (run 'hg heads' to see heads, 'hg merge' to merge)
+  not updating: crosses branches (merge branches or update --check to force update)
 
   $ HGMERGE=true hg merge
   merging foo
--- a/tests/test-pull.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-pull.t	Sat Jun 18 17:03:01 2011 -0500
@@ -1,8 +1,7 @@
-  $ mkdir test
+  $ hg init test
   $ cd test
 
   $ echo foo>foo
-  $ hg init
   $ hg addremove
   adding foo
   $ hg commit -m 1
@@ -68,7 +67,11 @@
 Test 'file:' uri handling:
 
   $ hg pull -q file://../test-doesnt-exist
-  abort: repository /test-doesnt-exist not found!
+  abort: file:// URLs can only refer to localhost
+  [255]
+
+  $ hg pull -q file://../test
+  abort: file:// URLs can only refer to localhost
   [255]
 
   $ hg pull -q file:../test
@@ -78,4 +81,8 @@
 
   $ URL=`python -c "import os; print 'file://foobar' + ('/' + os.getcwd().replace(os.sep, '/')).replace('//', '/') + '/../test'"`
   $ hg pull -q "$URL"
+  abort: file:// URLs can only refer to localhost
+  [255]
 
+  $ URL=`python -c "import os; print 'file://localhost' + ('/' + os.getcwd().replace(os.sep, '/')).replace('//', '/') + '/../test'"`
+  $ hg pull -q "$URL"
--- a/tests/test-push-cgi.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-push-cgi.t	Sat Jun 18 17:03:01 2011 -0500
@@ -59,7 +59,7 @@
   adding file changes
   added 0 changesets with 0 changes to 1 files
 
-successful push
+successful push, list of heads
 
   $ QUERY_STRING="cmd=unbundle&heads=f7b1eb17ad24730a1651fccd46c43826d1bbc2ac"; export QUERY_STRING
   $ python hgweb.cgi <bundle.hg >page3 2>&1
@@ -72,3 +72,17 @@
   adding manifests
   adding file changes
   added 0 changesets with 0 changes to 1 files
+
+successful push, SHA1 hash of heads (unbundlehash capability)
+
+  $ QUERY_STRING="cmd=unbundle&heads=686173686564 5a785a5f9e0d433b88ed862b206b011b0c3a9d13"; export QUERY_STRING
+  $ python hgweb.cgi <bundle.hg >page4 2>&1
+  $ cat page4
+  Status: 200 Script output follows\r (esc)
+  Content-Type: application/mercurial-0.1\r (esc)
+  \r (esc)
+  1
+  adding changesets
+  adding manifests
+  adding file changes
+  added 0 changesets with 0 changes to 1 files
--- a/tests/test-push-http.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-push-http.t	Sat Jun 18 17:03:01 2011 -0500
@@ -66,6 +66,40 @@
   repository tip rolled back to revision 0 (undo serve)
   working directory now based on revision 0
 
+expect success, server lacks the httpheader capability
+
+  $ CAP=httpheader
+  $ . "$TESTDIR/notcapable"
+  $ req
+  pushing to http://localhost:$HGPORT/
+  searching for changes
+  remote: adding changesets
+  remote: adding manifests
+  remote: adding file changes
+  remote: added 1 changesets with 1 changes to 1 files
+  remote: changegroup hook: HG_NODE=ba677d0156c1196c1a699fa53f390dcfc3ce3872 HG_SOURCE=serve HG_URL=remote:http:*:  (glob)
+  % serve errors
+  $ hg rollback
+  repository tip rolled back to revision 0 (undo serve)
+  working directory now based on revision 0
+
+expect success, server lacks the unbundlehash capability
+
+  $ CAP=unbundlehash
+  $ . "$TESTDIR/notcapable"
+  $ req
+  pushing to http://localhost:$HGPORT/
+  searching for changes
+  remote: adding changesets
+  remote: adding manifests
+  remote: adding file changes
+  remote: added 1 changesets with 1 changes to 1 files
+  remote: changegroup hook: HG_NODE=ba677d0156c1196c1a699fa53f390dcfc3ce3872 HG_SOURCE=serve HG_URL=remote:http:*:  (glob)
+  % serve errors
+  $ hg rollback
+  repository tip rolled back to revision 0 (undo serve)
+  working directory now based on revision 0
+
 expect authorization error: all users denied
 
   $ echo '[web]' > .hg/hgrc
--- a/tests/test-push-r.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-push-r.t	Sat Jun 18 17:03:01 2011 -0500
@@ -1,95 +1,13 @@
   $ hg init test
   $ cd test
-
-  $ cat >>afile <<EOF
-  > 0
-  > EOF
-  $ hg add afile
-  $ hg commit -m "0.0"
-
-  $ cat >>afile <<EOF
-  > 1
-  > EOF
-  $ hg commit -m "0.1"
-
-  $ cat >>afile <<EOF
-  > 2
-  > EOF
-  $ hg commit -m "0.2"
-
-  $ cat >>afile <<EOF
-  > 3
-  > EOF
-  $ hg commit -m "0.3"
-
-  $ hg update -C 0
+  $ hg unbundle $TESTDIR/bundles/remote.hg
+  adding changesets
+  adding manifests
+  adding file changes
+  added 9 changesets with 7 changes to 4 files (+1 heads)
+  (run 'hg heads' to see heads, 'hg merge' to merge)
+  $ hg up tip
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
-
-  $ cat >>afile <<EOF
-  > 1
-  > EOF
-  $ hg commit -m "1.1"
-  created new head
-
-  $ cat >>afile <<EOF
-  > 2
-  > EOF
-  $ hg commit -m "1.2"
-
-  $ cat >fred <<EOF
-  > a line
-  > EOF
-  $ cat >>afile <<EOF
-  > 3
-  > EOF
-  $ hg add fred
-  $ hg commit -m "1.3"
-
-  $ hg mv afile adifferentfile
-  $ hg commit -m "1.3m"
-
-  $ hg update -C 3
-  1 files updated, 0 files merged, 2 files removed, 0 files unresolved
-
-  $ hg mv afile anotherfile
-  $ hg commit -m "0.3m"
-
-  $ hg debugindex .hg/store/data/afile.i
-     rev    offset  length   base linkrev nodeid       p1           p2
-       0         0       3      0       0 362fef284ce2 000000000000 000000000000
-       1         3       5      1       1 125144f7e028 362fef284ce2 000000000000
-       2         8       7      2       2 4c982badb186 125144f7e028 000000000000
-       3        15       9      3       3 19b1fc555737 4c982badb186 000000000000
-
-  $ hg debugindex .hg/store/data/adifferentfile.i
-     rev    offset  length   base linkrev nodeid       p1           p2
-       0         0      75      0       7 2565f3199a74 000000000000 000000000000
-
-  $ hg debugindex .hg/store/data/anotherfile.i
-     rev    offset  length   base linkrev nodeid       p1           p2
-       0         0      75      0       8 2565f3199a74 000000000000 000000000000
-
-  $ hg debugindex .hg/store/data/fred.i
-     rev    offset  length   base linkrev nodeid       p1           p2
-       0         0       8      0       6 12ab3bcc5ea4 000000000000 000000000000
-
-  $ hg debugindex .hg/store/00manifest.i
-     rev    offset  length   base linkrev nodeid       p1           p2
-       0         0      48      0       0 43eadb1d2d06 000000000000 000000000000
-       1        48      48      1       1 8b89697eba2c 43eadb1d2d06 000000000000
-       2        96      48      2       2 626a32663c2f 8b89697eba2c 000000000000
-       3       144      48      3       3 f54c32f13478 626a32663c2f 000000000000
-       4       192      58      3       6 de68e904d169 626a32663c2f 000000000000
-       5       250      68      3       7 09bb521d218d de68e904d169 000000000000
-       6       318      54      6       8 1fde233dfb0f f54c32f13478 000000000000
-
-  $ hg verify
-  checking changesets
-  checking manifests
-  crosschecking files in changesets and manifests
-  checking files
-  4 files, 9 changesets, 7 total revisions
-
   $ cd ..
 
   $ for i in 0 1 2 3 4 5 6 7 8; do
--- a/tests/test-push-warn.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-push-warn.t	Sat Jun 18 17:03:01 2011 -0500
@@ -1,9 +1,8 @@
   $ echo "[extensions]" >> $HGRCPATH
   $ echo "graphlog=" >> $HGRCPATH
 
-  $ mkdir a
+  $ hg init a
   $ cd a
-  $ hg init
   $ echo foo > t1
   $ hg add t1
   $ hg commit -m "1"
@@ -26,24 +25,21 @@
   $ hg push ../a
   pushing to ../a
   searching for changes
-  abort: push creates new remote heads on branch 'default'!
+  abort: push creates new remote head 1e108cc5548c!
   (you should pull and merge or use push -f to force)
   [255]
 
   $ hg push --debug ../a
   pushing to ../a
+  query 1; heads
   searching for changes
-  examining 1c9246a22a0a:d8d565842d04
-  found incomplete branch 1c9246a22a0a:d8d565842d04
-  searching: 1 queries
-  narrowing 1:1 d8d565842d04
-  found new branch changeset 1c9246a22a0a
-  found new changesets starting at 1c9246a22a0a
-  1 total queries
-  common changesets up to d8d565842d04
+  taking quick initial sample
+  searching: 2 queries
+  query 2; still undecided: 1, sample size is: 1
+  2 total queries
   new remote heads on branch 'default'
   new remote head 1e108cc5548c
-  abort: push creates new remote heads on branch 'default'!
+  abort: push creates new remote head 1e108cc5548c!
   (you should pull and merge or use push -f to force)
   [255]
 
@@ -59,7 +55,7 @@
   $ hg push ../a
   pushing to ../a
   searching for changes
-  abort: push creates new remote heads on branch 'default'!
+  abort: push creates new remote head 1e108cc5548c!
   (did you forget to merge? use push -f to force)
   [255]
 
@@ -112,7 +108,7 @@
   $ hg push ../c
   pushing to ../c
   searching for changes
-  abort: push creates new remote heads on branch 'default'!
+  abort: push creates new remote head 6346d66eb9f5!
   (did you forget to merge? use push -f to force)
   [255]
 
@@ -124,20 +120,26 @@
   $ hg push -r 3 ../c
   pushing to ../c
   searching for changes
-  abort: push creates new remote heads on branch 'default'!
+  abort: push creates new remote head a5dda829a167!
   (did you forget to merge? use push -f to force)
   [255]
 
-  $ hg push -r 3 -r 4 ../c
+  $ hg push -v -r 3 -r 4 ../c
   pushing to ../c
   searching for changes
-  abort: push creates new remote heads on branch 'default'!
+  all remote heads known locally
+  new remote heads on branch 'default'
+  new remote head a5dda829a167
+  new remote head ee8fbc7a0295
+  abort: push creates new remote head a5dda829a167!
   (did you forget to merge? use push -f to force)
   [255]
 
-  $ hg push -f -r 3 -r 4 ../c
+  $ hg push -v -f -r 3 -r 4 ../c
   pushing to ../c
   searching for changes
+  all remote heads known locally
+  2 changesets found
   adding changesets
   adding manifests
   adding file changes
@@ -260,7 +262,7 @@
   $ hg push -r 4 -r 7 ../f
   pushing to ../f
   searching for changes
-  abort: push creates new remote heads on branch 'a'!
+  abort: push creates new remote head 0b715ef6ff8f on branch 'a'!
   (did you forget to merge? use push -f to force)
   [255]
 
@@ -383,7 +385,7 @@
   $ hg -R i push h
   pushing to h
   searching for changes
-  abort: push creates new remote heads on branch 'default'!
+  abort: push creates new remote head 97bd0c84d346!
   (you should pull and merge or use push -f to force)
   [255]
 
@@ -453,7 +455,7 @@
   $ hg push ../l -b b
   pushing to ../l
   searching for changes
-  abort: push creates new remote heads on branch 'a'!
+  abort: push creates new remote head e7e31d71180f on branch 'a'!
   (did you forget to merge? use push -f to force)
   [255]
 
@@ -700,14 +702,14 @@
   $ hg push inner
   pushing to inner
   searching for changes
-  abort: push creates new remote heads on branch 'A'!
+  abort: push creates new remote head 7d0f4fb6cf04 on branch 'A'!
   (did you forget to merge? use push -f to force)
   [255]
 
   $ hg push inner -r4 -r5
   pushing to inner
   searching for changes
-  abort: push creates new remote heads on branch 'A'!
+  abort: push creates new remote head 7d0f4fb6cf04 on branch 'A'!
   (did you forget to merge? use push -f to force)
   [255]
 
--- a/tests/test-qrecord.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-qrecord.t	Sat Jun 18 17:03:01 2011 -0500
@@ -2,41 +2,124 @@
 
   $ echo "[ui]" >> $HGRCPATH
   $ echo "interactive=true" >> $HGRCPATH
+
+help record (no record)
+
+  $ hg help record
+  record extension - commands to interactively select changes for commit/qrefresh
+  
+  use "hg help extensions" for information on enabling extensions
+
+help qrecord (no record)
+
+  $ hg help qrecord
+  'qrecord' is provided by the following extension:
+  
+      record  commands to interactively select changes for commit/qrefresh
+  
+  use "hg help extensions" for information on enabling extensions
+
   $ echo "[extensions]"     >> $HGRCPATH
   $ echo "record="          >> $HGRCPATH
 
+help record (record)
+
+  $ hg help record
+  hg record [OPTION]... [FILE]...
+  
+  interactively select changes to commit
+  
+      If a list of files is omitted, all changes reported by "hg status" will be
+      candidates for recording.
+  
+      See "hg help dates" for a list of formats valid for -d/--date.
+  
+      You will be prompted for whether to record changes to each modified file,
+      and for files with multiple changes, for each change to use. For each
+      query, the following responses are possible:
+  
+        y - record this change
+        n - skip this change
+  
+        s - skip remaining changes to this file
+        f - record remaining changes to this file
+  
+        d - done, skip remaining changes and files
+        a - record all changes to all remaining files
+        q - quit, recording no changes
+  
+        ? - display help
+  
+      This command is not available when committing a merge.
+  
+  options:
+  
+   -A --addremove            mark new/missing files as added/removed before
+                             committing
+      --close-branch         mark a branch as closed, hiding it from the branch
+                             list
+   -I --include PATTERN [+]  include names matching the given patterns
+   -X --exclude PATTERN [+]  exclude names matching the given patterns
+   -m --message TEXT         use text as commit message
+   -l --logfile FILE         read commit message from file
+   -d --date DATE            record the specified date as commit date
+   -u --user USER            record the specified user as committer
+   -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
+  
+  [+] marked option can be specified multiple times
+  
+  use "hg -v help record" to show global options
+
 help (no mq, so no qrecord)
 
   $ hg help qrecord
-  hg: unknown command 'qrecord'
-  Mercurial Distributed SCM
+  hg qrecord [OPTION]... PATCH [FILE]...
+  
+  interactively record a new patch
+  
+      See "hg help qnew" & "hg help record" for more information and usage.
   
-  basic commands:
+  use "hg -v help qrecord" to show global options
+
+  $ hg init a
+
+qrecord (mq not present)
+
+  $ hg -R a qrecord
+  hg qrecord: invalid arguments
+  hg qrecord [OPTION]... PATCH [FILE]...
+  
+  interactively record a new patch
   
-   add        add the specified files on the next commit
-   annotate   show changeset information by line for each file
-   clone      make a copy of an existing repository
-   commit     commit the specified files or all outstanding changes
-   diff       diff repository (or selected files)
-   export     dump the header and diffs for one or more changesets
-   forget     forget the specified files on the next commit
-   init       create a new repository in the given directory
-   log        show revision history of entire repository or files
-   merge      merge working directory with another revision
-   pull       pull changes from the specified source
-   push       push changes to the specified destination
-   remove     remove the specified files on the next commit
-   serve      start stand-alone webserver
-   status     show changed files in the working directory
-   summary    summarize working directory state
-   update     update working directory (or switch revisions)
+  use "hg help qrecord" to show the full help text
+  [255]
+
+qrecord patch (mq not present)
+
+  $ hg -R a qrecord patch
+  abort: 'mq' extension not loaded
+  [255]
+
+help (bad mq)
+
+  $ echo "mq=nonexistant" >> $HGRCPATH
+  $ hg help qrecord
+  *** failed to import extension mq from nonexistant: [Errno 2] No such file or directory
+  hg qrecord [OPTION]... PATCH [FILE]...
   
-  use "hg help" for the full list of commands or "hg -v" for details
-  [255]
+  interactively record a new patch
+  
+      See "hg help qnew" & "hg help record" for more information and usage.
+  
+  use "hg -v help qrecord" to show global options
 
 help (mq present)
 
-  $ echo "mq="              >> $HGRCPATH
+  $ sed 's/mq=nonexistant/mq=/' $HGRCPATH > hgrc.tmp
+  $ mv hgrc.tmp $HGRCPATH
+
   $ hg help qrecord
   hg qrecord [OPTION]... PATCH [FILE]...
   
@@ -56,12 +139,15 @@
    -X --exclude PATTERN [+]  exclude names matching the given patterns
    -m --message TEXT         use text as commit message
    -l --logfile FILE         read commit message from file
+   -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
+      --mq                   operate on patch repository
   
   [+] marked option can be specified multiple times
   
   use "hg -v help qrecord" to show global options
 
-  $ hg init a
   $ cd a
 
 Base commit
@@ -140,6 +226,12 @@
    someone
    up
 
+qrecord with bad patch name, should abort before prompting
+
+  $ hg qrecord .hg
+  abort: patch name cannot begin with ".hg"
+  [255]
+
 qrecord a.patch
 
   $ hg qrecord -d '0 0' -m aaa a.patch <<EOF
--- a/tests/test-rebase-cache.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-rebase-cache.t	Sat Jun 18 17:03:01 2011 -0500
@@ -85,9 +85,9 @@
   o  0: 'A'
   
   $ hg branches
-  branch3                        8:05b64c4ca2d8
-  branch2                        6:b410fbec727a
-  branch1                        2:9d931918fcf7 (inactive)
+  branch3                        8:4666b71e8e32
+  branch2                        6:5097051d331d
+  branch1                        2:0a03079c47fd (inactive)
   default                        0:1994f17a630e (inactive)
 
   $ hg theads
@@ -101,9 +101,9 @@
   saved backup bundle to $TESTTMP/a1/.hg/strip-backup/*-backup.hg (glob)
 
   $ hg branches
-  branch3                        8:c1d4b9719987
-  branch2                        4:1be2b203ae5e
-  branch1                        2:9d931918fcf7
+  branch3                        8:466cdfb14b62
+  branch2                        4:e4fdb121d036
+  branch1                        2:0a03079c47fd
   default                        0:1994f17a630e (inactive)
 
   $ hg theads
@@ -162,9 +162,9 @@
   saved backup bundle to $TESTTMP/a2/.hg/strip-backup/*-backup.hg (glob)
 
   $ hg branches
-  branch2                        8:e1e80ed73210
-  branch3                        7:75fd7b643dce
-  branch1                        2:9d931918fcf7 (inactive)
+  branch2                        8:6b4bdc1b5ac0
+  branch3                        7:653b9feb4616
+  branch1                        2:0a03079c47fd (inactive)
   default                        0:1994f17a630e (inactive)
 
   $ hg theads
@@ -226,8 +226,8 @@
   saved backup bundle to $TESTTMP/a3/.hg/strip-backup/*-backup.hg (glob)
 
   $ hg branches
-  branch2                        7:e1e80ed73210
-  branch1                        2:9d931918fcf7 (inactive)
+  branch2                        7:6b4bdc1b5ac0
+  branch1                        2:0a03079c47fd (inactive)
   default                        0:1994f17a630e (inactive)
 
   $ hg theads
--- a/tests/test-rebase-collapse.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-rebase-collapse.t	Sat Jun 18 17:03:01 2011 -0500
@@ -11,45 +11,14 @@
 
   $ hg init a
   $ cd a
-
-  $ echo A > A
-  $ hg ci -Am A
-  adding A
-  $ echo B > B
-  $ hg ci -Am B
-  adding B
-  $ echo C > C
-  $ hg ci -Am C
-  adding C
-  $ echo D > D
-  $ hg ci -Am D
-  adding D
-
-  $ hg up -q -C 0
-
-  $ echo E > E
-  $ hg ci -Am E
-  adding E
-  created new head
-
-  $ hg up -q -C 0
-
-  $ echo F > F
-  $ hg ci -Am F
-  adding F
-  created new head
-
-  $ hg merge -r 4
-  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
-  (branch merge, don't forget to commit)
-  $ hg ci -m G
-
-  $ hg up -q -C 5
-
-  $ echo H > H
-  $ hg ci -Am H
-  adding H
-  created new head
+  $ hg unbundle $TESTDIR/bundles/rebase.hg
+  adding changesets
+  adding manifests
+  adding file changes
+  added 8 changesets with 7 changes to 7 files (+2 heads)
+  (run 'hg heads' to see heads, 'hg merge' to merge)
+  $ hg up tip
+  3 files updated, 0 files merged, 0 files removed, 0 files unresolved
 
   $ hg tglog
   @  7: 'H'
@@ -137,6 +106,40 @@
 
   $ cd ..
 
+Rebasing G onto H with custom message:
+
+  $ hg clone -q -u . a a3
+  $ cd a3
+
+  $ hg rebase --base 6 -m 'custom message'
+  abort: message can only be specified with collapse
+  [255]
+
+  $ hg rebase --base 6 --collapse -m 'custom message'
+  saved backup bundle to $TESTTMP/a3/.hg/strip-backup/*-backup.hg (glob)
+
+  $ hg tglog
+  @  6: 'custom message'
+  |
+  o  5: 'H'
+  |
+  o  4: 'F'
+  |
+  | o  3: 'D'
+  | |
+  | o  2: 'C'
+  | |
+  | o  1: 'B'
+  |/
+  o  0: 'A'
+  
+  $ hg manifest
+  A
+  E
+  F
+  H
+
+  $ cd ..
 
 Create repo b:
 
--- a/tests/test-rebase-detach.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-rebase-detach.t	Sat Jun 18 17:03:01 2011 -0500
@@ -10,41 +10,32 @@
 
   $ hg init a
   $ cd a
-
-  $ echo A > A
-  $ hg ci -Am A
-  adding A
-
-  $ echo B > B
-  $ hg ci -Am B
-  adding B
-
-  $ echo C > C
-  $ hg ci -Am C
-  adding C
-
-  $ echo D > D
-  $ hg ci -Am D
-  adding D
-
-  $ hg up -q -C 0
-
-  $ echo E > E
-  $ hg ci -Am E
-  adding E
-  created new head
+  $ hg unbundle $TESTDIR/bundles/rebase.hg
+  adding changesets
+  adding manifests
+  adding file changes
+  added 8 changesets with 7 changes to 7 files (+2 heads)
+  (run 'hg heads' to see heads, 'hg merge' to merge)
+  $ hg up tip
+  3 files updated, 0 files merged, 0 files removed, 0 files unresolved
 
   $ cd ..
 
 
-Rebasing D onto E detaching from C:
+Rebasing D onto H detaching from C:
 
   $ hg clone -q -u . a a1
   $ cd a1
 
   $ hg tglog
-  @  4: 'E'
+  @  7: 'H'
   |
+  | o  6: 'G'
+  |/|
+  o |  5: 'F'
+  | |
+  | o  4: 'E'
+  |/
   | o  3: 'D'
   | |
   | o  2: 'C'
@@ -53,14 +44,20 @@
   |/
   o  0: 'A'
   
-  $ hg rebase --detach -s 3 -d 4
+  $ hg rebase --detach -s 3 -d 7
   saved backup bundle to $TESTTMP/a1/.hg/strip-backup/*-backup.hg (glob)
 
   $ hg tglog
-  @  4: 'D'
+  @  7: 'D'
+  |
+  o  6: 'H'
   |
-  o  3: 'E'
-  |
+  | o  5: 'G'
+  |/|
+  o |  4: 'F'
+  | |
+  | o  3: 'E'
+  |/
   | o  2: 'C'
   | |
   | o  1: 'B'
@@ -70,19 +67,26 @@
   $ hg manifest
   A
   D
-  E
+  F
+  H
 
   $ cd ..
 
 
-Rebasing C onto E detaching from B:
+Rebasing C onto H detaching from B:
 
   $ hg clone -q -u . a a2
   $ cd a2
 
   $ hg tglog
-  @  4: 'E'
+  @  7: 'H'
   |
+  | o  6: 'G'
+  |/|
+  o |  5: 'F'
+  | |
+  | o  4: 'E'
+  |/
   | o  3: 'D'
   | |
   | o  2: 'C'
@@ -91,16 +95,22 @@
   |/
   o  0: 'A'
   
-  $ hg rebase --detach -s 2 -d 4
+  $ hg rebase --detach -s 2 -d 7
   saved backup bundle to $TESTTMP/a2/.hg/strip-backup/*-backup.hg (glob)
 
   $ hg tglog
-  @  4: 'D'
+  @  7: 'D'
+  |
+  o  6: 'C'
+  |
+  o  5: 'H'
   |
-  o  3: 'C'
-  |
-  o  2: 'E'
-  |
+  | o  4: 'G'
+  |/|
+  o |  3: 'F'
+  | |
+  | o  2: 'E'
+  |/
   | o  1: 'B'
   |/
   o  0: 'A'
@@ -109,19 +119,26 @@
   A
   C
   D
-  E
+  F
+  H
 
   $ cd ..
 
 
-Rebasing B onto E using detach (same as not using it):
+Rebasing B onto H using detach (same as not using it):
 
   $ hg clone -q -u . a a3
   $ cd a3
 
   $ hg tglog
-  @  4: 'E'
+  @  7: 'H'
   |
+  | o  6: 'G'
+  |/|
+  o |  5: 'F'
+  | |
+  | o  4: 'E'
+  |/
   | o  3: 'D'
   | |
   | o  2: 'C'
@@ -130,18 +147,24 @@
   |/
   o  0: 'A'
   
-  $ hg rebase --detach -s 1 -d 4
+  $ hg rebase --detach -s 1 -d 7
   saved backup bundle to $TESTTMP/a3/.hg/strip-backup/*-backup.hg (glob)
 
   $ hg tglog
-  @  4: 'D'
+  @  7: 'D'
   |
-  o  3: 'C'
+  o  6: 'C'
+  |
+  o  5: 'B'
   |
-  o  2: 'B'
+  o  4: 'H'
   |
-  o  1: 'E'
-  |
+  | o  3: 'G'
+  |/|
+  o |  2: 'F'
+  | |
+  | o  1: 'E'
+  |/
   o  0: 'A'
   
   $ hg manifest
@@ -149,19 +172,26 @@
   B
   C
   D
-  E
+  F
+  H
 
   $ cd ..
 
 
-Rebasing C onto E detaching from B and collapsing:
+Rebasing C onto H detaching from B and collapsing:
 
   $ hg clone -q -u . a a4
   $ cd a4
 
   $ hg tglog
-  @  4: 'E'
+  @  7: 'H'
   |
+  | o  6: 'G'
+  |/|
+  o |  5: 'F'
+  | |
+  | o  4: 'E'
+  |/
   | o  3: 'D'
   | |
   | o  2: 'C'
@@ -170,15 +200,21 @@
   |/
   o  0: 'A'
   
-  $ hg rebase --detach --collapse -s 2 -d 4
+  $ hg rebase --detach --collapse -s 2 -d 7
   saved backup bundle to $TESTTMP/a4/.hg/strip-backup/*-backup.hg (glob)
 
   $ hg tglog
-  @  3: 'Collapsed revision
+  @  6: 'Collapsed revision
   |  * C
   |  * D'
-  o  2: 'E'
+  o  5: 'H'
   |
+  | o  4: 'G'
+  |/|
+  o |  3: 'F'
+  | |
+  | o  2: 'E'
+  |/
   | o  1: 'B'
   |/
   o  0: 'A'
@@ -187,7 +223,8 @@
   A
   C
   D
-  E
+  F
+  H
 
   $ cd ..
 
@@ -204,10 +241,16 @@
   created new head
 
   $ hg tglog
-  @  5: 'extra branch'
+  @  8: 'extra branch'
   
-  o  4: 'E'
+  o  7: 'H'
   |
+  | o  6: 'G'
+  |/|
+  o |  5: 'F'
+  | |
+  | o  4: 'E'
+  |/
   | o  3: 'D'
   | |
   | o  2: 'C'
@@ -220,15 +263,21 @@
   saved backup bundle to $TESTTMP/a5/.hg/strip-backup/*-backup.hg (glob)
 
   $ hg tglog
-  @  5: 'D'
+  @  8: 'D'
   |
-  o  4: 'C'
+  o  7: 'C'
+  |
+  o  6: 'B'
   |
-  o  3: 'B'
+  o  5: 'extra branch'
+  
+  o  4: 'H'
   |
-  o  2: 'extra branch'
-  
-  o  1: 'E'
-  |
+  | o  3: 'G'
+  |/|
+  o |  2: 'F'
+  | |
+  | o  1: 'E'
+  |/
   o  0: 'A'
   
--- a/tests/test-rebase-keep-branch.t	Wed Jun 01 16:32:48 2011 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,71 +0,0 @@
-  $ cat >> $HGRCPATH <<EOF
-  > [extensions]
-  > graphlog=
-  > rebase=
-  > 
-  > [alias]
-  > tglog = log -G --template "{rev}: '{desc}' {branches}\n"
-  > EOF
-
-
-  $ hg init a
-  $ cd a
-
-  $ echo c1 > c1
-  $ hg ci -Am c1
-  adding c1
-
-  $ echo c2 > c2
-  $ hg ci -Am c2
-  adding c2
-
-  $ echo l1 > l1
-  $ hg ci -Am l1
-  adding l1
-
-  $ echo l2 > l2
-  $ hg ci -Am l2
-  adding l2
-
-  $ hg up -q -C 1
-
-  $ hg branch 'notdefault'
-  marked working directory as branch notdefault
-
-  $ echo r1 > r1
-  $ hg ci -Am r1
-  adding r1
-
-  $ hg tglog
-  @  4: 'r1' notdefault
-  |
-  | o  3: 'l2'
-  | |
-  | o  2: 'l1'
-  |/
-  o  1: 'c2'
-  |
-  o  0: 'c1'
-  
-
-Rebase a branch while preserving the branch name:
-
-  $ hg up -q -C 3
-
-  $ hg rebase -b 4 -d 3 --keepbranches
-  saved backup bundle to $TESTTMP/a/.hg/strip-backup/*-backup.hg (glob)
-
-  $ hg tglog
-  @  4: 'r1' notdefault
-  |
-  o  3: 'l2'
-  |
-  o  2: 'l1'
-  |
-  o  1: 'c2'
-  |
-  o  0: 'c1'
-  
-  $ hg branch
-  notdefault
-
--- a/tests/test-rebase-mq.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-rebase-mq.t	Sat Jun 18 17:03:01 2011 -0500
@@ -250,6 +250,7 @@
   $ hg qnew foo
   $ hg qguard foo +baz
   $ echo foo > foo
+  $ hg add foo
   $ hg qref
   $ hg qpop
   popping foo
@@ -258,6 +259,7 @@
   $ hg qnew bar
   $ hg qguard bar +baz
   $ echo bar > bar
+  $ hg add bar
   $ hg qref
 
   $ hg qguard -l
@@ -272,13 +274,13 @@
 Create new head to rebase bar onto:
 
   $ hg up -C 0
-  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
   $ echo b > b
   $ hg add b
   $ hg ci -m b
   created new head
   $ hg up -C 1
-  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  1 files updated, 0 files merged, 1 files removed, 0 files unresolved
   $ echo a >> a
   $ hg qref
 
@@ -290,13 +292,19 @@
   o  0:* 'a' tags: qparent (glob)
   
 
-Rebase bar:
+Rebase bar (make sure series order is preserved):
 
+  $ hg qseries
+  bar
+  foo
   $ hg -q rebase -d 1
+  $ hg qseries
+  bar
+  foo
 
   $ hg qguard -l
+  bar: +baz
   foo: +baz
-  bar: +baz
 
   $ hg tglog
   @  2:* '[mq]: bar' tags: bar qbase qtip tip (glob)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-rebase-named-branches.t	Sat Jun 18 17:03:01 2011 -0500
@@ -0,0 +1,107 @@
+  $ cat >> $HGRCPATH <<EOF
+  > [extensions]
+  > graphlog=
+  > rebase=
+  > 
+  > [alias]
+  > tglog = log -G --template "{rev}: '{desc}' {branches}\n"
+  > EOF
+
+  $ hg init a
+  $ cd a
+  $ hg unbundle $TESTDIR/bundles/rebase.hg
+  adding changesets
+  adding manifests
+  adding file changes
+  added 8 changesets with 7 changes to 7 files (+2 heads)
+  (run 'hg heads' to see heads, 'hg merge' to merge)
+  $ hg up tip
+  3 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ cd ..
+
+
+Rebasing descendant onto ancestor across different named branches
+
+  $ hg clone -q -u . a a1
+
+  $ cd a1
+
+  $ hg branch dev
+  marked working directory as branch dev
+
+  $ echo x > x
+
+  $ hg add x
+
+  $ hg ci -m 'extra named branch'
+
+  $ hg tglog
+  @  8: 'extra named branch' dev
+  |
+  o  7: 'H'
+  |
+  | o  6: 'G'
+  |/|
+  o |  5: 'F'
+  | |
+  | o  4: 'E'
+  |/
+  | o  3: 'D'
+  | |
+  | o  2: 'C'
+  | |
+  | o  1: 'B'
+  |/
+  o  0: 'A'
+  
+
+
+  $ hg rebase -s 1 -d 8 --keepbranches
+  saved backup bundle to $TESTTMP/a1/.hg/strip-backup/*-backup.hg (glob)
+
+  $ hg tglog
+  @  8: 'D'
+  |
+  o  7: 'C'
+  |
+  o  6: 'B'
+  |
+  o  5: 'extra named branch' dev
+  |
+  o  4: 'H'
+  |
+  | o  3: 'G'
+  |/|
+  o |  2: 'F'
+  | |
+  | o  1: 'E'
+  |/
+  o  0: 'A'
+  
+  $ hg rebase -s 4 -d 5
+  abort: source is ancestor of destination
+  [255]
+
+  $ hg rebase -s 5 -d 4
+  saved backup bundle to $TESTTMP/a1/.hg/strip-backup/*-backup.hg (glob)
+
+  $ hg tglog
+  @  8: 'D'
+  |
+  o  7: 'C'
+  |
+  o  6: 'B'
+  |
+  o  5: 'extra named branch'
+  |
+  o  4: 'H'
+  |
+  | o  3: 'G'
+  |/|
+  o |  2: 'F'
+  | |
+  | o  1: 'E'
+  |/
+  o  0: 'A'
+  
+  $ cd ..
--- a/tests/test-rebase-parameters.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-rebase-parameters.t	Sat Jun 18 17:03:01 2011 -0500
@@ -10,60 +10,37 @@
 
   $ hg init a
   $ cd a
-
-  $ echo c1 > c1
-  $ hg ci -Am c1
-  adding c1
-
-  $ echo c2 > c2
-  $ hg ci -Am c2
-  adding c2
-
-  $ echo c3 > c3
-  $ hg ci -Am c3
-  adding c3
-
-  $ hg up -q -C 1
+  $ hg unbundle $TESTDIR/bundles/rebase.hg
+  adding changesets
+  adding manifests
+  adding file changes
+  added 8 changesets with 7 changes to 7 files (+2 heads)
+  (run 'hg heads' to see heads, 'hg merge' to merge)
+  $ hg up tip
+  3 files updated, 0 files merged, 0 files removed, 0 files unresolved
 
-  $ echo l1 > l1
-  $ hg ci -Am l1
-  adding l1
-  created new head
-
-  $ echo l2 > l2
-  $ hg ci -Am l2
-  adding l2
-
-  $ echo l3 > l3
-  $ hg ci -Am l3
-  adding l3
-
-  $ hg up -q -C 2
-
-  $ echo r1 > r1
-  $ hg ci -Am r1
-  adding r1
-
-  $ echo r2 > r2
-  $ hg ci -Am r2
-  adding r2
+  $ echo I > I
+  $ hg ci -AmI
+  adding I
 
   $ hg tglog
-  @  7: 'r2'
+  @  8: 'I'
   |
-  o  6: 'r1'
+  o  7: 'H'
   |
-  | o  5: 'l3'
-  | |
-  | o  4: 'l2'
+  | o  6: 'G'
+  |/|
+  o |  5: 'F'
   | |
-  | o  3: 'l1'
-  | |
-  o |  2: 'c3'
+  | o  4: 'E'
   |/
-  o  1: 'c2'
-  |
-  o  0: 'c1'
+  | o  3: 'D'
+  | |
+  | o  2: 'C'
+  | |
+  | o  1: 'B'
+  |/
+  o  0: 'A'
   
   $ cd ..
 
@@ -73,6 +50,10 @@
   $ hg clone -q -u . a a1
   $ cd a1
 
+  $ hg rebase -s 8 -d 7
+  abort: source is descendant of destination
+  [255]
+
   $ hg rebase --continue --abort
   abort: cannot use both abort and continue
   [255]
@@ -93,7 +74,7 @@
   nothing to rebase
   [1]
 
-  $ hg up -q 6
+  $ hg up -q 7
 
   $ hg rebase
   nothing to rebase
@@ -102,29 +83,31 @@
 
 These work:
 
-Rebase with no arguments (from 3 onto 7):
+Rebase with no arguments (from 3 onto 8):
 
-  $ hg up -q -C 5
+  $ hg up -q -C 3
 
   $ hg rebase
   saved backup bundle to $TESTTMP/a1/.hg/strip-backup/*-backup.hg (glob)
 
   $ hg tglog
-  @  7: 'l3'
+  @  8: 'D'
   |
-  o  6: 'l2'
+  o  7: 'C'
   |
-  o  5: 'l1'
+  o  6: 'B'
   |
-  o  4: 'r2'
+  o  5: 'I'
   |
-  o  3: 'r1'
-  |
-  o  2: 'c3'
+  o  4: 'H'
   |
-  o  1: 'c2'
-  |
-  o  0: 'c1'
+  | o  3: 'G'
+  |/|
+  o |  2: 'F'
+  | |
+  | o  1: 'E'
+  |/
+  o  0: 'A'
   
 Try to rollback after a rebase (fail):
 
@@ -135,198 +118,272 @@
   $ cd ..
 
 
-Rebase with base == '.' => same as no arguments (from 3 onto 7):
+Rebase with base == '.' => same as no arguments (from 3 onto 8):
 
-  $ hg clone -q -u 5 a a2
+  $ hg clone -q -u 3 a a2
   $ cd a2
 
   $ hg rebase --base .
   saved backup bundle to $TESTTMP/a2/.hg/strip-backup/*-backup.hg (glob)
 
   $ hg tglog
-  @  7: 'l3'
+  @  8: 'D'
   |
-  o  6: 'l2'
+  o  7: 'C'
   |
-  o  5: 'l1'
+  o  6: 'B'
   |
-  o  4: 'r2'
+  o  5: 'I'
   |
-  o  3: 'r1'
-  |
-  o  2: 'c3'
+  o  4: 'H'
   |
-  o  1: 'c2'
-  |
-  o  0: 'c1'
+  | o  3: 'G'
+  |/|
+  o |  2: 'F'
+  | |
+  | o  1: 'E'
+  |/
+  o  0: 'A'
   
   $ cd ..
 
 
-Rebase with dest == `hg branch` => same as no arguments (from 3 onto 7):
+Rebase with dest == `hg branch` => same as no arguments (from 3 onto 8):
 
-  $ hg clone -q -u 5 a a3
+  $ hg clone -q -u 3 a a3
   $ cd a3
 
   $ hg rebase --dest `hg branch`
   saved backup bundle to $TESTTMP/a3/.hg/strip-backup/*-backup.hg (glob)
 
   $ hg tglog
-  @  7: 'l3'
+  @  8: 'D'
   |
-  o  6: 'l2'
+  o  7: 'C'
   |
-  o  5: 'l1'
+  o  6: 'B'
   |
-  o  4: 'r2'
+  o  5: 'I'
   |
-  o  3: 'r1'
-  |
-  o  2: 'c3'
+  o  4: 'H'
   |
-  o  1: 'c2'
-  |
-  o  0: 'c1'
+  | o  3: 'G'
+  |/|
+  o |  2: 'F'
+  | |
+  | o  1: 'E'
+  |/
+  o  0: 'A'
   
   $ cd ..
 
 
-Specify only source (from 4 onto 7):
+Specify only source (from 2 onto 8):
 
   $ hg clone -q -u . a a4
   $ cd a4
 
-  $ hg rebase --source 4
+  $ hg rebase --source 2
   saved backup bundle to $TESTTMP/a4/.hg/strip-backup/*-backup.hg (glob)
 
   $ hg tglog
-  @  7: 'l3'
+  @  8: 'D'
   |
-  o    6: 'l2'
+  o    7: 'C'
   |\
-  | o  5: 'r2'
+  | o  6: 'I'
   | |
-  | o  4: 'r1'
+  | o  5: 'H'
   | |
-  o |  3: 'l1'
-  | |
-  | o  2: 'c3'
+  | | o  4: 'G'
+  | |/|
+  | o |  3: 'F'
+  | | |
+  | | o  2: 'E'
+  | |/
+  o |  1: 'B'
   |/
-  o  1: 'c2'
-  |
-  o  0: 'c1'
+  o  0: 'A'
   
   $ cd ..
 
 
 Specify only dest (from 3 onto 6):
 
-  $ hg clone -q -u 5 a a5
+  $ hg clone -q -u 3 a a5
   $ cd a5
 
   $ hg rebase --dest 6
   saved backup bundle to $TESTTMP/a5/.hg/strip-backup/*-backup.hg (glob)
 
   $ hg tglog
-  @  7: 'l3'
+  @  8: 'D'
   |
-  o  6: 'l2'
+  o  7: 'C'
+  |
+  o  6: 'B'
   |
-  o  5: 'l1'
-  |
-  | o  4: 'r2'
+  | o  5: 'I'
+  | |
+  | o  4: 'H'
+  | |
+  o |  3: 'G'
+  |\|
+  | o  2: 'F'
+  | |
+  o |  1: 'E'
   |/
-  o  3: 'r1'
-  |
-  o  2: 'c3'
-  |
-  o  1: 'c2'
-  |
-  o  0: 'c1'
+  o  0: 'A'
   
   $ cd ..
 
 
-Specify only base (from 3 onto 7):
+Specify only base (from 1 onto 8):
 
   $ hg clone -q -u . a a6
   $ cd a6
 
-  $ hg rebase --base 5
+  $ hg rebase --base 3
   saved backup bundle to $TESTTMP/a6/.hg/strip-backup/*-backup.hg (glob)
 
   $ hg tglog
-  @  7: 'l3'
+  @  8: 'D'
   |
-  o  6: 'l2'
+  o  7: 'C'
   |
-  o  5: 'l1'
+  o  6: 'B'
   |
-  o  4: 'r2'
+  o  5: 'I'
+  |
+  o  4: 'H'
   |
-  o  3: 'r1'
-  |
-  o  2: 'c3'
+  | o  3: 'G'
+  |/|
+  o |  2: 'F'
+  | |
+  | o  1: 'E'
+  |/
+  o  0: 'A'
+  
+  $ cd ..
+
+
+Specify source and dest (from 2 onto 7):
+
+  $ hg clone -q -u . a a7
+  $ cd a7
+
+  $ hg rebase --detach --source 2 --dest 7
+  saved backup bundle to $TESTTMP/a7/.hg/strip-backup/*-backup.hg (glob)
+
+  $ hg tglog
+  @  8: 'D'
   |
-  o  1: 'c2'
+  o  7: 'C'
+  |
+  | o  6: 'I'
+  |/
+  o  5: 'H'
   |
-  o  0: 'c1'
+  | o  4: 'G'
+  |/|
+  o |  3: 'F'
+  | |
+  | o  2: 'E'
+  |/
+  | o  1: 'B'
+  |/
+  o  0: 'A'
   
   $ cd ..
 
 
-Specify source and dest (from 4 onto 6):
-
-  $ hg clone -q -u . a a7
-  $ cd a7
-
-  $ hg rebase --source 4 --dest 6
-  saved backup bundle to $TESTTMP/a7/.hg/strip-backup/*-backup.hg (glob)
-
-  $ hg tglog
-  @  7: 'l3'
-  |
-  o    6: 'l2'
-  |\
-  | | o  5: 'r2'
-  | |/
-  | o  4: 'r1'
-  | |
-  o |  3: 'l1'
-  | |
-  | o  2: 'c3'
-  |/
-  o  1: 'c2'
-  |
-  o  0: 'c1'
-  
-  $ cd ..
-
-
-Specify base and dest (from 3 onto 6):
+Specify base and dest (from 1 onto 7):
 
   $ hg clone -q -u . a a8
   $ cd a8
 
-  $ hg rebase --base 4 --dest 6
+  $ hg rebase --base 3 --dest 7
   saved backup bundle to $TESTTMP/a8/.hg/strip-backup/*-backup.hg (glob)
 
   $ hg tglog
-  @  7: 'l3'
+  @  8: 'D'
   |
-  o  6: 'l2'
+  o  7: 'C'
   |
-  o  5: 'l1'
+  o  6: 'B'
   |
-  | o  4: 'r2'
+  | o  5: 'I'
   |/
-  o  3: 'r1'
-  |
-  o  2: 'c3'
+  o  4: 'H'
   |
-  o  1: 'c2'
-  |
-  o  0: 'c1'
+  | o  3: 'G'
+  |/|
+  o |  2: 'F'
+  | |
+  | o  1: 'E'
+  |/
+  o  0: 'A'
   
   $ cd ..
 
+Test --tool parameter:
+
+  $ hg init b
+  $ cd b
+
+  $ echo c1 > c1
+  $ hg ci -Am c1
+  adding c1
+
+  $ echo c2 > c2
+  $ hg ci -Am c2
+  adding c2
+
+  $ hg up -q 0
+  $ echo c2b > c2
+  $ hg ci -Am c2b
+  adding c2
+  created new head
+
+  $ cd ..
+
+  $ hg clone -q -u . b b1
+  $ cd b1
+
+  $ hg rebase -s 2 -d 1 --tool internal:local
+  saved backup bundle to $TESTTMP/b1/.hg/strip-backup/*-backup.hg (glob)
+
+  $ hg cat c2
+  c2
+
+  $ cd ..
+
+
+  $ hg clone -q -u . b b2
+  $ cd b2
+
+  $ hg rebase -s 2 -d 1 --tool internal:other
+  saved backup bundle to $TESTTMP/b2/.hg/strip-backup/*-backup.hg (glob)
+
+  $ hg cat c2
+  c2b
+
+  $ cd ..
+
+
+  $ hg clone -q -u . b b3
+  $ cd b3
+
+  $ hg rebase -s 2 -d 1 --tool internal:fail
+  abort: unresolved conflicts (see hg resolve, then hg rebase --continue)
+  [255]
+
+  $ hg resolve -l
+  U c2
+
+  $ hg resolve -m c2
+  $ hg rebase -c --tool internal:fail
+  tool option will be ignored
+  saved backup bundle to $TESTTMP/b3/.hg/strip-backup/*-backup.hg (glob)
+
--- a/tests/test-rebase-scenario-global.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-rebase-scenario-global.t	Sat Jun 18 17:03:01 2011 -0500
@@ -10,122 +10,111 @@
 
   $ hg init a
   $ cd a
-
-  $ echo A > A
-  $ hg ci -Am A
-  adding A
-
-  $ echo B > B
-  $ hg ci -Am B
-  adding B
-
-  $ hg up -q -C 0
-
-  $ echo C > C
-  $ hg ci -Am C
-  adding C
-  created new head
-
-  $ hg up -q -C 0
-
-  $ echo D > D
-  $ hg ci -Am D
-  adding D
-  created new head
-
-  $ hg merge -r 2
-  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
-  (branch merge, don't forget to commit)
-
-  $ hg ci -m E
-
-  $ hg up -q -C 3
-
-  $ echo F > F
-  $ hg ci -Am F
-  adding F
-  created new head
-
+  $ hg unbundle $TESTDIR/bundles/rebase.hg
+  adding changesets
+  adding manifests
+  adding file changes
+  added 8 changesets with 7 changes to 7 files (+2 heads)
+  (run 'hg heads' to see heads, 'hg merge' to merge)
+  $ hg up tip
+  3 files updated, 0 files merged, 0 files removed, 0 files unresolved
   $ cd ..
 
 
 Rebasing
-B onto F - simple rebase:
+D onto H - simple rebase:
 
   $ hg clone -q -u . a a1
   $ cd a1
 
   $ hg tglog
-  @  5: 'F'
+  @  7: 'H'
   |
+  | o  6: 'G'
+  |/|
+  o |  5: 'F'
+  | |
   | o  4: 'E'
-  |/|
-  o |  3: 'D'
+  |/
+  | o  3: 'D'
   | |
   | o  2: 'C'
-  |/
+  | |
   | o  1: 'B'
   |/
   o  0: 'A'
   
-  $ hg rebase -s 1 -d 5
+
+  $ hg rebase -s 3 -d 7
   saved backup bundle to $TESTTMP/a1/.hg/strip-backup/*-backup.hg (glob)
 
   $ hg tglog
-  @  5: 'B'
-  |
-  o  4: 'F'
-  |
-  | o  3: 'E'
-  |/|
-  o |  2: 'D'
+  @    7: 'D'
+  |\
+  | o  6: 'H'
   | |
-  | o  1: 'C'
+  | | o  5: 'G'
+  | |/|
+  | o |  4: 'F'
+  | | |
+  | | o  3: 'E'
+  | |/
+  o |  2: 'C'
+  | |
+  o |  1: 'B'
   |/
   o  0: 'A'
   
   $ cd ..
 
 
-B onto D - intermediate point:
+D onto F - intermediate point:
 
   $ hg clone -q -u . a a2
   $ cd a2
 
-  $ hg rebase -s 1 -d 3
+  $ hg rebase -s 3 -d 5
   saved backup bundle to $TESTTMP/a2/.hg/strip-backup/*-backup.hg (glob)
 
   $ hg tglog
-  @  5: 'B'
-  |
-  | o  4: 'F'
-  |/
-  | o  3: 'E'
-  |/|
-  o |  2: 'D'
+  @    7: 'D'
+  |\
+  | | o  6: 'H'
+  | |/
+  | | o  5: 'G'
+  | |/|
+  | o |  4: 'F'
+  | | |
+  | | o  3: 'E'
+  | |/
+  o |  2: 'C'
   | |
-  | o  1: 'C'
+  o |  1: 'B'
   |/
   o  0: 'A'
   
   $ cd ..
 
 
-C onto F - skip of E:
+E onto H - skip of G:
 
   $ hg clone -q -u . a a3
   $ cd a3
 
-  $ hg rebase -s 2 -d 5
+  $ hg rebase -s 4 -d 7
   saved backup bundle to $TESTTMP/a3/.hg/strip-backup/*-backup.hg (glob)
 
   $ hg tglog
-  @  4: 'C'
+  @  6: 'E'
+  |
+  o  5: 'H'
   |
-  o  3: 'F'
+  o  4: 'F'
   |
-  o  2: 'D'
-  |
+  | o  3: 'D'
+  | |
+  | o  2: 'C'
+  | |
   | o  1: 'B'
   |/
   o  0: 'A'
@@ -133,21 +122,25 @@
   $ cd ..
 
 
-D onto C - rebase of a branching point (skip E):
+F onto E - rebase of a branching point (skip G):
 
   $ hg clone -q -u . a a4
   $ cd a4
 
-  $ hg rebase -s 3 -d 2
+  $ hg rebase -s 5 -d 4
   saved backup bundle to $TESTTMP/a4/.hg/strip-backup/*-backup.hg (glob)
 
   $ hg tglog
-  @  4: 'F'
+  @  6: 'H'
+  |
+  o  5: 'F'
   |
-  o  3: 'D'
+  o  4: 'E'
   |
-  o  2: 'C'
-  |
+  | o  3: 'D'
+  | |
+  | o  2: 'C'
+  | |
   | o  1: 'B'
   |/
   o  0: 'A'
@@ -155,23 +148,27 @@
   $ cd ..
 
 
-E onto F - merged revision having a parent in ancestors of target:
+G onto H - merged revision having a parent in ancestors of target:
 
   $ hg clone -q -u . a a5
   $ cd a5
 
-  $ hg rebase -s 4 -d 5
+  $ hg rebase -s 6 -d 7
   saved backup bundle to $TESTTMP/a5/.hg/strip-backup/*-backup.hg (glob)
 
   $ hg tglog
-  @    5: 'E'
+  @    7: 'G'
   |\
-  | o  4: 'F'
+  | o  6: 'H'
   | |
+  | o  5: 'F'
+  | |
+  o |  4: 'E'
+  |/
   | o  3: 'D'
   | |
-  o |  2: 'C'
-  |/
+  | o  2: 'C'
+  | |
   | o  1: 'B'
   |/
   o  0: 'A'
@@ -179,22 +176,26 @@
   $ cd ..
 
 
-D onto B - E maintains C as parent:
+F onto B - G maintains E as parent:
 
   $ hg clone -q -u . a a6
   $ cd a6
 
-  $ hg rebase -s 3 -d 1
+  $ hg rebase -s 5 -d 1
   saved backup bundle to $TESTTMP/a6/.hg/strip-backup/*-backup.hg (glob)
 
   $ hg tglog
-  @  5: 'F'
+  @  7: 'H'
   |
-  | o  4: 'E'
+  | o  6: 'G'
   |/|
-  o |  3: 'D'
+  o |  5: 'F'
+  | |
+  | o  4: 'E'
   | |
-  | o  2: 'C'
+  | | o  3: 'D'
+  | | |
+  +---o  2: 'C'
   | |
   o |  1: 'B'
   |/
@@ -205,45 +206,45 @@
 
 These will fail (using --source):
 
-E onto D - rebase onto an ancestor:
+G onto F - rebase onto an ancestor:
 
   $ hg clone -q -u . a a7
   $ cd a7
 
-  $ hg rebase -s 4 -d 3
+  $ hg rebase -s 6 -d 5
   abort: source is descendant of destination
   [255]
 
-D onto E - rebase onto a descendant:
+F onto G - rebase onto a descendant:
 
-  $ hg rebase -s 3 -d 4
+  $ hg rebase -s 5 -d 6
   abort: source is ancestor of destination
   [255]
 
-E onto B - merge revision with both parents not in ancestors of target:
+G onto B - merge revision with both parents not in ancestors of target:
 
-  $ hg rebase -s 4 -d 1
-  abort: cannot use revision 4 as base, result would have 3 parents
+  $ hg rebase -s 6 -d 1
+  abort: cannot use revision 6 as base, result would have 3 parents
   [255]
 
 
 These will abort gracefully (using --base):
 
-E onto E - rebase onto same changeset:
+G onto G - rebase onto same changeset:
 
-  $ hg rebase -b 4 -d 4
+  $ hg rebase -b 6 -d 6
   nothing to rebase
   [1]
 
-E onto D - rebase onto an ancestor:
+G onto F - rebase onto an ancestor:
 
-  $ hg rebase -b 4 -d 3
+  $ hg rebase -b 6 -d 5
   nothing to rebase
   [1]
 
-D onto E - rebase onto a descendant:
+F onto G - rebase onto a descendant:
 
-  $ hg rebase -b 3 -d 4
+  $ hg rebase -b 5 -d 6
   nothing to rebase
   [1]
 
--- a/tests/test-relink.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-relink.t	Sat Jun 18 17:03:01 2011 -0500
@@ -20,23 +20,29 @@
 
   $ hg init repo
   $ cd repo
-  $ echo '[ui]' > .hg/hgrc
-  $ echo 'username= A. Foo <a.foo@bar.com>' >> .hg/hgrc
   $ echo a > a
   $ echo b > b
   $ hg ci -Am addfile
   adding a
   adding b
-  $ echo a >> a
-  $ echo a >> b
+  $ cat $TESTDIR/binfile.bin >> a
+  $ cat $TESTDIR/binfile.bin >> b
   $ hg ci -Am changefiles
 
+make another commit to create files larger than 1 KB to test
+formatting of final byte count
+
+  $ cat $TESTDIR/binfile.bin >> a
+  $ cat $TESTDIR/binfile.bin >> b
+  $ hg ci -m anotherchange
+
 don't sit forever trying to double-lock the source repo
 
   $ hg relink .
   relinking $TESTTMP/repo/.hg/store to $TESTTMP/repo/.hg/store
   there is nothing to relink
 
+
 Test files are read in binary mode
 
   $ python -c "file('.hg/store/data/dummy.i', 'wb').write('a\r\nb\n')"
@@ -53,8 +59,6 @@
   updating to branch default
   2 files updated, 0 files merged, 0 files removed, 0 files unresolved
   $ cd clone
-  $ echo '[ui]' >> .hg/hgrc
-  $ echo 'username= A. Baz <a.baz@bar.com>' >> .hg/hgrc
   $ hg pull -q
   $ echo b >> b
   $ hg ci -m changeb
@@ -81,7 +85,7 @@
   pruned down to 2 probably relinkable files
   relinking: data/a.i 1/2 files (50.00%)
   not linkable: data/dummy.i
-  relinked 1 files (136 bytes reclaimed)
+  relinked 1 files (1.37 KB reclaimed)
   $ cd ..
 
 
--- a/tests/test-rename-dir-merge.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-rename-dir-merge.t	Sat Jun 18 17:03:01 2011 -0500
@@ -1,6 +1,5 @@
-  $ mkdir t
+  $ hg init t
   $ cd t
-  $ hg init
 
   $ mkdir a
   $ echo foo > a/a
@@ -118,9 +117,8 @@
 Second scenario with two repos:
 
   $ cd ..
-  $ mkdir r1
+  $ hg init r1
   $ cd r1
-  $ hg init
   $ mkdir a
   $ echo foo > a/f
   $ hg add a
--- a/tests/test-rename-merge1.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-rename-merge1.t	Sat Jun 18 17:03:01 2011 -0500
@@ -67,7 +67,7 @@
 
   $ hg ci -m "merge"
 
-  $ hg debugindex .hg/store/data/b.i
+  $ hg debugindex b
      rev    offset  length   base linkrev nodeid       p1           p2
        0         0      67      0       1 57eacc201a7f 000000000000 000000000000
        1        67      72      1       3 4727ba907962 000000000000 57eacc201a7f
@@ -131,27 +131,27 @@
   $ hg init repo2089
   $ cd repo2089
 
-  $ echo 0 > A
-  $ hg -q ci -Am 0
+  $ echo c0 > f1
+  $ hg ci -Aqm0
 
-  $ hg -q up -C null
-  $ echo 1 > A
-  $ hg -q ci -Am 1
+  $ hg up null -q
+  $ echo c1 > f1
+  $ hg ci -Aqm1
 
-  $ hg -q up -C 0
+  $ hg up 0 -q
   $ hg merge 1 -q --tool internal:local
-  $ echo 2 > A
-  $ hg -q ci -m 2
+  $ echo c2 > f1
+  $ hg ci -qm2
 
-  $ hg -q up -C 1
-  $ hg mv A a
-  $ hg -q ci -Am 3
+  $ hg up 1 -q
+  $ hg mv f1 f2
+  $ hg ci -Aqm3
 
-  $ hg -q up -C 2
+  $ hg up 2 -q
   $ hg merge 3
-  merging A and a to a
+  merging f1 and f2 to f2
   0 files updated, 1 files merged, 0 files removed, 0 files unresolved
   (branch merge, don't forget to commit)
 
-  $ cat a
-  2
+  $ cat f2
+  c2
--- a/tests/test-rename-merge2.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-rename-merge2.t	Sat Jun 18 17:03:01 2011 -0500
@@ -17,9 +17,8 @@
 
   $ tm()
   > {
-  >     mkdir t
+  >     hg init t
   >     cd t
-  >     hg init
   >     echo "[merge]" >> .hg/hgrc
   >     echo "followcopies = 1" >> .hg/hgrc
   > 
--- a/tests/test-rename.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-rename.t	Sat Jun 18 17:03:01 2011 -0500
@@ -11,6 +11,9 @@
 rename a single file
 
   $ hg rename d1/d11/a1 d2/c
+  $ hg --config ui.portablefilenames=abort rename d1/a d1/con.xml
+  abort: filename contains 'con', which is reserved on Windows: 'd1/con.xml'
+  [255]
   $ hg sum
   parent: 0:9b4b6e7b2c26 tip
    1
--- a/tests/test-repair-strip	Wed Jun 01 16:32:48 2011 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,44 +0,0 @@
-#!/bin/sh
-
-echo "[extensions]" >> $HGRCPATH
-echo "mq=">> $HGRCPATH
-
-teststrip() {
-    hg -q up -C $1
-    echo % before update $1, strip $2
-    hg parents
-    chmod -$3 $4
-    hg strip $2 2>&1 | sed 's/\(bundle\).*/\1/' | sed 's/Permission denied.*\.hg\/store\/\(.*\)/Permission denied \.hg\/store\/\1/'
-    echo % after update $1, strip $2
-    chmod +$3 $4
-    hg verify
-    echo % journal contents
-    if [ -f .hg/store/journal ]; then
-        sed -e 's/\.i[^\n]*/\.i/' .hg/store/journal
-    else
-        echo "(no journal)"
-    fi
-    ls .hg/store/journal >/dev/null 2>&1 && hg recover
-    ls .hg/strip-backup/* >/dev/null 2>&1 && hg unbundle -q .hg/strip-backup/*
-    rm -rf .hg/strip-backup
-}
-
-hg init test
-cd test
-
-echo a > a
-hg -q ci -m "a" -A
-
-echo b > b
-hg -q ci -m "b" -A
-
-echo b2 >> b
-hg -q ci -m "b2" -A
-
-echo c > c
-hg -q ci -m "c" -A
- 
-teststrip 0 2 w .hg/store/data/b.i
-teststrip 0 2 r .hg/store/data/b.i
-teststrip 0 2 w .hg/store/00manifest.i
-
--- a/tests/test-repair-strip.out	Wed Jun 01 16:32:48 2011 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,92 +0,0 @@
-% before update 0, strip 2
-changeset:   0:cb9a9f314b8b
-user:        test
-date:        Thu Jan 01 00:00:00 1970 +0000
-summary:     a
-
-saved backup bundle
-transaction abort!
-failed to truncate data/b.i
-rollback failed - please run hg recover
-strip failed, full bundle
-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
-checking files
- b@?: rev 1 points to nonexistent changeset 2
- (expected 1)
- b@?: 736c29771fba not in manifests
-warning: orphan revlog 'data/c.i'
-2 files, 2 changesets, 3 total revisions
-2 warnings encountered!
-2 integrity errors encountered!
-% journal contents
-00changelog.i
-00manifest.i
-data/b.i
-data/c.i
-rolling back interrupted transaction
-checking changesets
-checking manifests
-crosschecking files in changesets and manifests
-checking files
-2 files, 2 changesets, 2 total revisions
-% before update 0, strip 2
-changeset:   0:cb9a9f314b8b
-user:        test
-date:        Thu Jan 01 00:00:00 1970 +0000
-summary:     a
-
-abort: Permission denied .hg/store/data/b.i
-% after update 0, strip 2
-checking changesets
-checking manifests
-crosschecking files in changesets and manifests
-checking files
-3 files, 4 changesets, 4 total revisions
-% journal contents
-(no journal)
-% before update 0, strip 2
-changeset:   0:cb9a9f314b8b
-user:        test
-date:        Thu Jan 01 00:00:00 1970 +0000
-summary:     a
-
-saved backup bundle
-transaction abort!
-failed to truncate 00manifest.i
-rollback failed - please run hg recover
-strip failed, full bundle
-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
- manifest@?: 3362547cdf64 not in changesets
- manifest@?: rev 3 points to nonexistent changeset 3
- manifest@?: 265a85892ecb not in changesets
-crosschecking files in changesets and manifests
- c@3: in manifest but not in changeset
-checking files
- b@?: rev 1 points to nonexistent changeset 2
- (expected 1)
- c@?: rev 0 points to nonexistent changeset 3
-3 files, 2 changesets, 4 total revisions
-1 warnings encountered!
-7 integrity errors encountered!
-(first damaged changeset appears to be 3)
-% journal contents
-00changelog.i
-00manifest.i
-data/b.i
-data/c.i
-rolling back interrupted transaction
-checking changesets
-checking manifests
-crosschecking files in changesets and manifests
-checking files
-2 files, 2 changesets, 2 total revisions
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-repair-strip.t	Sat Jun 18 17:03:01 2011 -0500
@@ -0,0 +1,130 @@
+
+  $ echo "[extensions]" >> $HGRCPATH
+  $ echo "mq=">> $HGRCPATH
+
+  $ teststrip() {
+  >   hg -q up -C $1
+  >   echo % before update $1, strip $2
+  >   hg parents
+  >   chmod -$3 $4
+  >   hg strip $2 2>&1 | sed 's/\(bundle\).*/\1/' | sed 's/Permission denied.*\.hg\/store\/\(.*\)/Permission denied \.hg\/store\/\1/'
+  >   echo % after update $1, strip $2
+  >   chmod +$3 $4
+  >   hg verify
+  >   echo % journal contents
+  >   if [ -f .hg/store/journal ]; then
+  >       sed -e 's/\.i[^\n]*/\.i/' .hg/store/journal
+  >   else
+  >       echo "(no journal)"
+  >   fi
+  >   ls .hg/store/journal >/dev/null 2>&1 && hg recover
+  >   ls .hg/strip-backup/* >/dev/null 2>&1 && hg unbundle -q .hg/strip-backup/*
+  >   rm -rf .hg/strip-backup
+  > }
+
+  $ hg init test
+  $ cd test
+  $ echo a > a
+  $ hg -q ci -m "a" -A
+  $ echo b > b
+  $ hg -q ci -m "b" -A
+  $ echo b2 >> b
+  $ hg -q ci -m "b2" -A
+  $ echo c > c
+  $ hg -q ci -m "c" -A
+  $ teststrip 0 2 w .hg/store/data/b.i
+  % before update 0, strip 2
+  changeset:   0:cb9a9f314b8b
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     a
+  
+  saved backup bundle
+  transaction abort!
+  failed to truncate data/b.i
+  rollback failed - please run hg recover
+  strip failed, full bundle
+  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
+  checking files
+   b@?: rev 1 points to nonexistent changeset 2
+   (expected 1)
+   b@?: 736c29771fba not in manifests
+  warning: orphan revlog 'data/c.i'
+  2 files, 2 changesets, 3 total revisions
+  2 warnings encountered!
+  2 integrity errors encountered!
+  % journal contents
+  00changelog.i
+  00manifest.i
+  data/b.i
+  data/c.i
+  rolling back interrupted transaction
+  checking changesets
+  checking manifests
+  crosschecking files in changesets and manifests
+  checking files
+  2 files, 2 changesets, 2 total revisions
+  $ teststrip 0 2 r .hg/store/data/b.i
+  % before update 0, strip 2
+  changeset:   0:cb9a9f314b8b
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     a
+  
+  abort: Permission denied .hg/store/data/b.i
+  % after update 0, strip 2
+  checking changesets
+  checking manifests
+  crosschecking files in changesets and manifests
+  checking files
+  3 files, 4 changesets, 4 total revisions
+  % journal contents
+  (no journal)
+  $ teststrip 0 2 w .hg/store/00manifest.i
+  % before update 0, strip 2
+  changeset:   0:cb9a9f314b8b
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     a
+  
+  saved backup bundle
+  transaction abort!
+  failed to truncate 00manifest.i
+  rollback failed - please run hg recover
+  strip failed, full bundle
+  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
+   manifest@?: 3362547cdf64 not in changesets
+   manifest@?: rev 3 points to nonexistent changeset 3
+   manifest@?: 265a85892ecb not in changesets
+  crosschecking files in changesets and manifests
+   c@3: in manifest but not in changeset
+  checking files
+   b@?: rev 1 points to nonexistent changeset 2
+   (expected 1)
+   c@?: rev 0 points to nonexistent changeset 3
+  3 files, 2 changesets, 4 total revisions
+  1 warnings encountered!
+  7 integrity errors encountered!
+  (first damaged changeset appears to be 3)
+  % journal contents
+  00changelog.i
+  00manifest.i
+  data/b.i
+  data/c.i
+  rolling back interrupted transaction
+  checking changesets
+  checking manifests
+  crosschecking files in changesets and manifests
+  checking files
+  2 files, 2 changesets, 2 total revisions
+
--- a/tests/test-requires.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-requires.t	Sat Jun 18 17:03:01 2011 -0500
@@ -1,6 +1,5 @@
-  $ mkdir t
+  $ hg init t
   $ cd t
-  $ hg init
   $ echo a > a
   $ hg add a
   $ hg commit -m test
@@ -10,5 +9,5 @@
   [255]
   $ echo indoor-pool > .hg/requires
   $ hg tip
-  abort: requirement 'indoor-pool' not supported!
+  abort: unknown repository format: requires feature 'indoor-pool' (upgrade Mercurial)!
   [255]
--- a/tests/test-revert.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-revert.t	Sat Jun 18 17:03:01 2011 -0500
@@ -185,7 +185,8 @@
 should fail - no arguments
 
   $ hg revert -rtip
-  abort: no files or directories specified; use --all to revert the whole repo
+  abort: no files or directories specified
+  (use --all to revert all files)
   [255]
 
 should succeed
--- a/tests/test-revlog-packentry.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-revlog-packentry.t	Sat Jun 18 17:03:01 2011 -0500
@@ -15,7 +15,7 @@
   adding foo
   created new head
 
-  $ hg debugindex .hg/store/data/foo.i
+  $ hg debugindex foo
      rev    offset  length   base linkrev nodeid       p1           p2
        0         0       0      0       0 b80de5d13875 000000000000 000000000000
        1         0      24      0       1 0376abec49b8 000000000000 000000000000
--- a/tests/test-revset-outgoing.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-revset-outgoing.t	Sat Jun 18 17:03:01 2011 -0500
@@ -39,7 +39,7 @@
   $ cd b
   $ cat .hg/hgrc
   [paths]
-  default = */a#stable (glob)
+  default = $TESTTMP/a#stable
 
   $ echo red >> a
   $ hg ci -qm3
@@ -60,7 +60,7 @@
   
 
   $ hg tout
-  comparing with */a (glob)
+  comparing with $TESTTMP/a
   searching for changes
   2:1d4099801a4e: '3' stable
 
@@ -79,11 +79,11 @@
 
   $ cat .hg/hgrc
   [paths]
-  default = */a#stable (glob)
+  default = $TESTTMP/a#stable
   green = ../a#default
 
   $ hg tout green
-  comparing with */a (glob)
+  comparing with $TESTTMP/a
   searching for changes
   3:f0461977a3db: '4' 
 
--- a/tests/test-revset.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-revset.t	Sat Jun 18 17:03:01 2011 -0500
@@ -2,7 +2,7 @@
   $ export HGENCODING
 
   $ try() {
-  >   hg debugrevspec --debug $@
+  >   hg debugrevspec --debug "$@"
   > }
 
   $ log() {
@@ -190,6 +190,8 @@
   1
   3
   5
+  $ log 'desc(B)'
+  5
   $ log 'descendants(2 or 3)'
   2
   3
@@ -297,6 +299,12 @@
   6
   $ log 'tag(tip)'
   9
+  $ log 'tag(unknown)'
+  abort: tag 'unknown' does not exist
+  [255]
+  $ log 'branch(unknown)'
+  abort: unknown revision 'unknown'!
+  [255]
   $ log 'user(bob)'
   2
 
@@ -363,3 +371,77 @@
   hg: parse error at 2: invalid token
   [255]
 
+or operator should preserve ordering:
+  $ log 'reverse(2::4) or tip'
+  4
+  2
+  9
+
+parentrevspec
+
+  $ log 'merge()^0'
+  6
+  $ log 'merge()^'
+  5
+  $ log 'merge()^1'
+  5
+  $ log 'merge()^2'
+  4
+  $ log 'merge()^^'
+  3
+  $ log 'merge()^1^'
+  3
+  $ log 'merge()^^^'
+  1
+
+  $ log 'merge()~0'
+  6
+  $ log 'merge()~1'
+  5
+  $ log 'merge()~2'
+  3
+  $ log 'merge()~2^1'
+  1
+  $ log 'merge()~3'
+  1
+
+  $ log '(-3:tip)^'
+  4
+  6
+  8
+
+  $ log 'tip^foo'
+  hg: parse error: ^ expects a number 0, 1, or 2
+  [255]
+
+aliases:
+
+  $ echo '[revsetalias]' >> .hg/hgrc
+  $ echo 'm = merge()' >> .hg/hgrc
+  $ echo 'd($1) = reverse(sort($1, date))' >> .hg/hgrc
+  $ echo 'rs(ARG1, ARG2) = reverse(sort(ARG1, ARG2))' >> .hg/hgrc
+
+  $ try m
+  ('symbol', 'm')
+  ('func', ('symbol', 'merge'), None)
+  6
+  $ try 'd(2:5)'
+  ('func', ('symbol', 'd'), ('range', ('symbol', '2'), ('symbol', '5')))
+  ('func', ('symbol', 'reverse'), ('func', ('symbol', 'sort'), ('list', ('range', ('symbol', '2'), ('symbol', '5')), ('symbol', 'date'))))
+  4
+  5
+  3
+  2
+  $ try 'rs(2 or 3, date)'
+  ('func', ('symbol', 'rs'), ('list', ('or', ('symbol', '2'), ('symbol', '3')), ('symbol', 'date')))
+  ('func', ('symbol', 'reverse'), ('func', ('symbol', 'sort'), ('list', ('or', ('symbol', '2'), ('symbol', '3')), ('symbol', 'date'))))
+  3
+  2
+
+issue2549 - correct optimizations
+
+  $ log 'limit(1 or 2 or 3, 2) and not 2'
+  1
+  $ log 'max(1 or 2) and not 2'
+  $ log 'min(1 or 2) and not 1'
+  $ log 'last(1 or 2, 1) and not 2'
--- a/tests/test-rollback.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-rollback.t	Sat Jun 18 17:03:01 2011 -0500
@@ -1,7 +1,6 @@
 
-  $ mkdir t
+  $ hg init t
   $ cd t
-  $ hg init
   $ echo a > a
   $ hg add a
   $ hg commit -m "test"
--- a/tests/test-schemes.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-schemes.t	Sat Jun 18 17:03:01 2011 -0500
@@ -25,10 +25,12 @@
 
   $ hg incoming --debug parts://localhost
   using http://localhost:$HGPORT/
-  sending between command
-  comparing with parts://localhost
-  sending heads command
+  sending capabilities command
+  comparing with parts://localhost/
+  query 1; heads
+  sending batch command
   searching for changes
+  all remote heads known locally
   no changes found
   [1]
 
--- a/tests/test-serve	Wed Jun 01 16:32:48 2011 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,58 +0,0 @@
-#!/bin/sh
-
-hgserve()
-{
-    hg serve -a localhost -d --pid-file=hg.pid -E errors.log -v $@ \
-        | sed -e "s/:$HGPORT1\\([^0-9]\\)/:HGPORT1\1/g" \
-              -e "s/:$HGPORT2\\([^0-9]\\)/:HGPORT2\1/g" \
-              -e 's/http:\/\/[^/]*\//http:\/\/localhost\//'
-    cat hg.pid >> "$DAEMON_PIDS"
-    echo % errors
-    cat errors.log
-    sleep 1
-    if [ "$KILLQUIETLY" = "Y" ]; then
-        kill `cat hg.pid` 2>/dev/null
-    else
-        kill `cat hg.pid`
-    fi
-    sleep 1
-}
-
-hg init test
-cd test
-
-echo '[web]' > .hg/hgrc
-echo 'accesslog = access.log' >> .hg/hgrc
-echo "port = $HGPORT1" >> .hg/hgrc
-
-echo % Without -v
-hg serve -a localhost -p $HGPORT -d --pid-file=hg.pid -E errors.log
-cat hg.pid >> "$DAEMON_PIDS"
-if [ -f access.log ]; then
-    echo 'access log created - .hg/hgrc respected'
-fi
-echo % errors
-cat errors.log
-
-echo % With -v
-hgserve
-
-echo % With -v and -p HGPORT2
-hgserve -p "$HGPORT2"
-
-echo '% With -v and -p daytime (should fail because low port)'
-KILLQUIETLY=Y
-hgserve -p daytime
-KILLQUIETLY=N
-
-echo % With --prefix foo
-hgserve --prefix foo
-
-echo % With --prefix /foo
-hgserve --prefix /foo
-
-echo % With --prefix foo/
-hgserve --prefix foo/
-
-echo % With --prefix /foo/
-hgserve --prefix /foo/
--- a/tests/test-serve.out	Wed Jun 01 16:32:48 2011 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,25 +0,0 @@
-% Without -v
-access log created - .hg/hgrc respected
-% errors
-% With -v
-listening at http://localhost/ (bound to 127.0.0.1:HGPORT1)
-% errors
-% With -v and -p HGPORT2
-listening at http://localhost/ (bound to 127.0.0.1:HGPORT2)
-% errors
-% With -v and -p daytime (should fail because low port)
-abort: cannot start server at 'localhost:13': Permission denied
-abort: child process failed to start
-% errors
-% With --prefix foo
-listening at http://localhost/foo/ (bound to 127.0.0.1:HGPORT1)
-% errors
-% With --prefix /foo
-listening at http://localhost/foo/ (bound to 127.0.0.1:HGPORT1)
-% errors
-% With --prefix foo/
-listening at http://localhost/foo/ (bound to 127.0.0.1:HGPORT1)
-% errors
-% With --prefix /foo/
-listening at http://localhost/foo/ (bound to 127.0.0.1:HGPORT1)
-% errors
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-serve.t	Sat Jun 18 17:03:01 2011 -0500
@@ -0,0 +1,82 @@
+
+  $ hgserve()
+  > {
+  >    hg serve -a localhost -d --pid-file=hg.pid -E errors.log -v $@ \
+  >        | sed -e "s/:$HGPORT1\\([^0-9]\\)/:HGPORT1\1/g" \
+  >              -e "s/:$HGPORT2\\([^0-9]\\)/:HGPORT2\1/g" \
+  >              -e 's/http:\/\/[^/]*\//http:\/\/localhost\//'
+  >    cat hg.pid >> "$DAEMON_PIDS"
+  >    echo % errors
+  >    cat errors.log
+  >    sleep 1
+  >    if [ "$KILLQUIETLY" = "Y" ]; then
+  >        kill `cat hg.pid` 2>/dev/null
+  >    else
+  >        kill `cat hg.pid`
+  >    fi
+  >    sleep 1
+  > }
+
+  $ hg init test
+  $ cd test
+  $ echo '[web]' > .hg/hgrc
+  $ echo 'accesslog = access.log' >> .hg/hgrc
+  $ echo "port = $HGPORT1" >> .hg/hgrc
+
+Without -v
+
+  $ hg serve -a localhost -p $HGPORT -d --pid-file=hg.pid -E errors.log
+  $ cat hg.pid >> "$DAEMON_PIDS"
+  $ if [ -f access.log ]; then
+  $     echo 'access log created - .hg/hgrc respected'
+  access log created - .hg/hgrc respected
+  $ fi
+
+errors
+
+  $ cat errors.log
+
+With -v
+
+  $ hgserve
+  listening at http://localhost/ (bound to 127.0.0.1:HGPORT1)
+  % errors
+
+With -v and -p HGPORT2
+
+  $ hgserve -p "$HGPORT2"
+  listening at http://localhost/ (bound to 127.0.0.1:HGPORT2)
+  % errors
+
+With -v and -p daytime (should fail because low port)
+
+  $ KILLQUIETLY=Y
+  $ hgserve -p daytime
+  abort: cannot start server at 'localhost:13': Permission denied
+  abort: child process failed to start
+  % errors
+  $ KILLQUIETLY=N
+
+With --prefix foo
+
+  $ hgserve --prefix foo
+  listening at http://localhost/foo/ (bound to 127.0.0.1:HGPORT1)
+  % errors
+
+With --prefix /foo
+
+  $ hgserve --prefix /foo
+  listening at http://localhost/foo/ (bound to 127.0.0.1:HGPORT1)
+  % errors
+
+With --prefix foo/
+
+  $ hgserve --prefix foo/
+  listening at http://localhost/foo/ (bound to 127.0.0.1:HGPORT1)
+  % errors
+
+With --prefix /foo/
+
+  $ hgserve --prefix /foo/
+  listening at http://localhost/foo/ (bound to 127.0.0.1:HGPORT1)
+  % errors
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-setdiscovery.t	Sat Jun 18 17:03:01 2011 -0500
@@ -0,0 +1,268 @@
+
+Function to test discovery between two repos in both directions, using both the local shortcut
+(which is currently not activated by default) and the full remotable protocol:
+
+  $ testdesc() { # revs_a, revs_b, dagdesc
+  >     if [ -e foo ]; then rm -rf foo; fi
+  >     hg init foo
+  >     cd foo
+  >     hg debugbuilddag "$3"
+  >     hg clone . a $1 --quiet
+  >     hg clone . b $2 --quiet
+  >     echo
+  >     echo "% -- a -> b tree"
+  >     hg -R a debugdiscovery b --verbose --old
+  >     echo
+  >     echo "% -- a -> b set"
+  >     hg -R a debugdiscovery b --verbose --debug
+  >     echo
+  >     echo "% -- b -> a tree"
+  >     hg -R b debugdiscovery a --verbose --old
+  >     echo
+  >     echo "% -- b -> a set"
+  >     hg -R b debugdiscovery a --verbose --debug
+  >     cd ..
+  > }
+
+
+Small superset:
+
+  $ testdesc '-ra1 -ra2' '-rb1 -rb2 -rb3' '
+  > +2:f +1:a1:b1
+  > <f +4 :a2
+  > +5 :b2
+  > <f +3 :b3'
+  
+  % -- a -> b tree
+  comparing with b
+  searching for changes
+  unpruned common: b5714e113bc0 66f7d451a68b 01241442b3c2
+  common heads: b5714e113bc0 01241442b3c2
+  local is subset
+  
+  % -- a -> b set
+  comparing with b
+  query 1; heads
+  searching for changes
+  all local heads known remotely
+  common heads: b5714e113bc0 01241442b3c2
+  local is subset
+  
+  % -- b -> a tree
+  comparing with a
+  searching for changes
+  unpruned common: b5714e113bc0 01241442b3c2
+  common heads: b5714e113bc0 01241442b3c2
+  remote is subset
+  
+  % -- b -> a set
+  comparing with a
+  query 1; heads
+  searching for changes
+  all remote heads known locally
+  common heads: b5714e113bc0 01241442b3c2
+  remote is subset
+
+
+Many new:
+
+  $ testdesc '-ra1 -ra2' '-rb' '
+  > +2:f +3:a1 +3:b
+  > <f +30 :a2'
+  
+  % -- a -> b tree
+  comparing with b
+  searching for changes
+  unpruned common: bebd167eb94d
+  common heads: bebd167eb94d
+  
+  % -- a -> b set
+  comparing with b
+  query 1; heads
+  searching for changes
+  taking initial sample
+  searching: 2 queries
+  query 2; still undecided: 29, sample size is: 29
+  2 total queries
+  common heads: bebd167eb94d
+  
+  % -- b -> a tree
+  comparing with a
+  searching for changes
+  unpruned common: bebd167eb94d 66f7d451a68b
+  common heads: bebd167eb94d
+  
+  % -- b -> a set
+  comparing with a
+  query 1; heads
+  searching for changes
+  taking initial sample
+  searching: 2 queries
+  query 2; still undecided: 2, sample size is: 2
+  2 total queries
+  common heads: bebd167eb94d
+
+
+Both sides many new with stub:
+
+  $ testdesc '-ra1 -ra2' '-rb' '
+  > +2:f +2:a1 +30 :b
+  > <f +30 :a2'
+  
+  % -- a -> b tree
+  comparing with b
+  searching for changes
+  unpruned common: 2dc09a01254d
+  common heads: 2dc09a01254d
+  
+  % -- a -> b set
+  comparing with b
+  query 1; heads
+  searching for changes
+  taking initial sample
+  searching: 2 queries
+  query 2; still undecided: 29, sample size is: 29
+  2 total queries
+  common heads: 2dc09a01254d
+  
+  % -- b -> a tree
+  comparing with a
+  searching for changes
+  unpruned common: 66f7d451a68b 2dc09a01254d
+  common heads: 2dc09a01254d
+  
+  % -- b -> a set
+  comparing with a
+  query 1; heads
+  searching for changes
+  taking initial sample
+  searching: 2 queries
+  query 2; still undecided: 29, sample size is: 29
+  2 total queries
+  common heads: 2dc09a01254d
+
+
+Both many new:
+
+  $ testdesc '-ra' '-rb' '
+  > +2:f +30 :b
+  > <f +30 :a'
+  
+  % -- a -> b tree
+  comparing with b
+  searching for changes
+  unpruned common: 66f7d451a68b
+  common heads: 66f7d451a68b
+  
+  % -- a -> b set
+  comparing with b
+  query 1; heads
+  searching for changes
+  taking quick initial sample
+  searching: 2 queries
+  query 2; still undecided: 31, sample size is: 31
+  2 total queries
+  common heads: 66f7d451a68b
+  
+  % -- b -> a tree
+  comparing with a
+  searching for changes
+  unpruned common: 66f7d451a68b
+  common heads: 66f7d451a68b
+  
+  % -- b -> a set
+  comparing with a
+  query 1; heads
+  searching for changes
+  taking quick initial sample
+  searching: 2 queries
+  query 2; still undecided: 31, sample size is: 31
+  2 total queries
+  common heads: 66f7d451a68b
+
+
+Both many new skewed:
+
+  $ testdesc '-ra' '-rb' '
+  > +2:f +30 :b
+  > <f +50 :a'
+  
+  % -- a -> b tree
+  comparing with b
+  searching for changes
+  unpruned common: 66f7d451a68b
+  common heads: 66f7d451a68b
+  
+  % -- a -> b set
+  comparing with b
+  query 1; heads
+  searching for changes
+  taking quick initial sample
+  searching: 2 queries
+  query 2; still undecided: 51, sample size is: 51
+  2 total queries
+  common heads: 66f7d451a68b
+  
+  % -- b -> a tree
+  comparing with a
+  searching for changes
+  unpruned common: 66f7d451a68b
+  common heads: 66f7d451a68b
+  
+  % -- b -> a set
+  comparing with a
+  query 1; heads
+  searching for changes
+  taking quick initial sample
+  searching: 2 queries
+  query 2; still undecided: 31, sample size is: 31
+  2 total queries
+  common heads: 66f7d451a68b
+
+
+Both many new on top of long history:
+
+  $ testdesc '-ra' '-rb' '
+  > +1000:f +30 :b
+  > <f +50 :a'
+  
+  % -- a -> b tree
+  comparing with b
+  searching for changes
+  unpruned common: 7ead0cba2838
+  common heads: 7ead0cba2838
+  
+  % -- a -> b set
+  comparing with b
+  query 1; heads
+  searching for changes
+  taking quick initial sample
+  searching: 2 queries
+  query 2; still undecided: 1049, sample size is: 11
+  sampling from both directions
+  searching: 3 queries
+  query 3; still undecided: 31, sample size is: 31
+  3 total queries
+  common heads: 7ead0cba2838
+  
+  % -- b -> a tree
+  comparing with a
+  searching for changes
+  unpruned common: 7ead0cba2838
+  common heads: 7ead0cba2838
+  
+  % -- b -> a set
+  comparing with a
+  query 1; heads
+  searching for changes
+  taking quick initial sample
+  searching: 2 queries
+  query 2; still undecided: 1029, sample size is: 11
+  sampling from both directions
+  searching: 3 queries
+  query 3; still undecided: 16, sample size is: 16
+  3 total queries
+  common heads: 7ead0cba2838
+
+
+
--- a/tests/test-simple-update.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-simple-update.t	Sat Jun 18 17:03:01 2011 -0500
@@ -1,7 +1,6 @@
-  $ mkdir test
+  $ hg init test
   $ cd test
   $ echo foo>foo
-  $ hg init
   $ hg addremove
   adding foo
   $ hg commit -m "1"
@@ -50,3 +49,8 @@
   $ hg manifest --debug
   6f4310b00b9a147241b071a60c28a650827fb03d 644   foo
 
+update to rev 0 with a date
+
+  $ hg upd -d foo 0
+  abort: you can't specify a revision and a date
+  [255]
--- a/tests/test-simplemerge-cmd.t	Wed Jun 01 16:32:48 2011 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,172 +0,0 @@
-
-  $ cp "$TESTDIR"/../contrib/simplemerge .
-  $ echo base > base
-  $ echo local > local
-  $ cat base >> local
-  $ cp local orig
-  $ cat base > other
-  $ echo other >> other
-
-changing local directly
-
-  $ python simplemerge local base other && echo "merge succeeded"
-  merge succeeded
-  $ cat local
-  local
-  base
-  other
-  $ cp orig local
-
-printing to stdout
-
-  $ python simplemerge -p local base other
-  local
-  base
-  other
-
-local:
-
-  $ cat local
-  local
-  base
-
-conflicts
-
-  $ cp base conflict-local
-  $ cp other conflict-other
-  $ echo not other >> conflict-local
-  $ echo end >> conflict-local
-  $ echo end >> conflict-other
-  $ python simplemerge -p conflict-local base conflict-other
-  base
-  <<<<<<< conflict-local
-  not other
-  =======
-  other
-  >>>>>>> conflict-other
-  end
-  warning: conflicts during merge.
-  [1]
-
---no-minimal
-
-  $ python simplemerge -p --no-minimal conflict-local base conflict-other
-  base
-  <<<<<<< conflict-local
-  not other
-  end
-  =======
-  other
-  end
-  >>>>>>> conflict-other
-  warning: conflicts during merge.
-  [1]
-
-1 label
-
-  $ python simplemerge -p -L foo conflict-local base conflict-other
-  base
-  <<<<<<< foo
-  not other
-  =======
-  other
-  >>>>>>> conflict-other
-  end
-  warning: conflicts during merge.
-  [1]
-
-2 labels
-
-  $ python simplemerge -p -L foo -L bar conflict-local base conflict-other
-  base
-  <<<<<<< foo
-  not other
-  =======
-  other
-  >>>>>>> bar
-  end
-  warning: conflicts during merge.
-  [1]
-
-too many labels
-
-  $ python simplemerge -p -L foo -L bar -L baz conflict-local base conflict-other
-  abort: can only specify two labels.
-  [255]
-
-binary file
-
-  $ python -c "f = file('binary-local', 'w'); f.write('\x00'); f.close()"
-  $ cat orig >> binary-local
-  $ python simplemerge -p binary-local base other
-  warning: binary-local looks like a binary file.
-  [1]
-
-binary file --text
-
-  $ python simplemerge -a -p binary-local base other 2>&1
-  warning: binary-local looks like a binary file.
-  \x00local (esc)
-  base
-  other
-
-help
-
-  $ python simplemerge --help
-  simplemerge [OPTS] LOCAL BASE OTHER
-  
-      Simple three-way file merge utility with a minimal feature set.
-  
-      Apply to LOCAL the changes necessary to go from BASE to OTHER.
-  
-      By default, LOCAL is overwritten with the results of this operation.
-  
-  options:
-   -L --label       labels to use on conflict markers
-   -a --text        treat all files as text
-   -p --print       print results instead of overwriting LOCAL
-      --no-minimal  do not try to minimize conflict regions
-   -h --help        display help and exit
-   -q --quiet       suppress output
-
-wrong number of arguments
-
-  $ python simplemerge
-  simplemerge: wrong number of arguments
-  simplemerge [OPTS] LOCAL BASE OTHER
-  
-      Simple three-way file merge utility with a minimal feature set.
-  
-      Apply to LOCAL the changes necessary to go from BASE to OTHER.
-  
-      By default, LOCAL is overwritten with the results of this operation.
-  
-  options:
-   -L --label       labels to use on conflict markers
-   -a --text        treat all files as text
-   -p --print       print results instead of overwriting LOCAL
-      --no-minimal  do not try to minimize conflict regions
-   -h --help        display help and exit
-   -q --quiet       suppress output
-  [1]
-
-bad option
-
-  $ python simplemerge --foo -p local base other
-  simplemerge: option --foo not recognized
-  simplemerge [OPTS] LOCAL BASE OTHER
-  
-      Simple three-way file merge utility with a minimal feature set.
-  
-      Apply to LOCAL the changes necessary to go from BASE to OTHER.
-  
-      By default, LOCAL is overwritten with the results of this operation.
-  
-  options:
-   -L --label       labels to use on conflict markers
-   -a --text        treat all files as text
-   -p --print       print results instead of overwriting LOCAL
-      --no-minimal  do not try to minimize conflict regions
-   -h --help        display help and exit
-   -q --quiet       suppress output
-  [1]
--- a/tests/test-ssh-clone-r.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-ssh-clone-r.t	Sat Jun 18 17:03:01 2011 -0500
@@ -1,110 +1,23 @@
 This test tries to exercise the ssh functionality with a dummy script
 
-  $ cat <<EOF > dummyssh
-  > import sys
-  > import os
-  > 
-  > os.chdir(os.path.dirname(sys.argv[0]))
-  > if sys.argv[1] != "user@dummy":
-  >     sys.exit(-1)
-  > 
-  > if not os.path.exists("dummyssh"):
-  >     sys.exit(-1)
-  > 
-  > os.environ["SSH_CLIENT"] = "127.0.0.1 1 2"
-  > 
-  > log = open("dummylog", "ab")
-  > log.write("Got arguments")
-  > for i, arg in enumerate(sys.argv[1:]):
-  >     log.write(" %d:%s" % (i+1, arg))
-  > log.write("\n")
-  > log.close()
-  > r = os.system(sys.argv[2])
-  > sys.exit(bool(r))
-  > EOF
+creating 'remote' repo
+
   $ hg init remote
   $ cd remote
-
-creating 'remote
-
-  $ cat >>afile <<EOF
-  > 0
-  > EOF
-  $ hg add afile
-  $ hg commit -m "0.0"
-  $ cat >>afile <<EOF
-  > 1
-  > EOF
-  $ hg commit -m "0.1"
-  $ cat >>afile <<EOF
-  > 2
-  > EOF
-  $ hg commit -m "0.2"
-  $ cat >>afile <<EOF
-  > 3
-  > EOF
-  $ hg commit -m "0.3"
-  $ hg update -C 0
+  $ hg unbundle $TESTDIR/bundles/remote.hg
+  adding changesets
+  adding manifests
+  adding file changes
+  added 9 changesets with 7 changes to 4 files (+1 heads)
+  (run 'hg heads' to see heads, 'hg merge' to merge)
+  $ hg up tip
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
-  $ cat >>afile <<EOF
-  > 1
-  > EOF
-  $ hg commit -m "1.1"
-  created new head
-  $ cat >>afile <<EOF
-  > 2
-  > EOF
-  $ hg commit -m "1.2"
-  $ cat >fred <<EOF
-  > a line
-  > EOF
-  $ cat >>afile <<EOF
-  > 3
-  > EOF
-  $ hg add fred
-  $ hg commit -m "1.3"
-  $ hg mv afile adifferentfile
-  $ hg commit -m "1.3m"
-  $ hg update -C 3
-  1 files updated, 0 files merged, 2 files removed, 0 files unresolved
-  $ hg mv afile anotherfile
-  $ hg commit -m "0.3m"
-  $ hg debugindex .hg/store/data/afile.i
-     rev    offset  length   base linkrev nodeid       p1           p2
-       0         0       3      0       0 362fef284ce2 000000000000 000000000000
-       1         3       5      1       1 125144f7e028 362fef284ce2 000000000000
-       2         8       7      2       2 4c982badb186 125144f7e028 000000000000
-       3        15       9      3       3 19b1fc555737 4c982badb186 000000000000
-  $ hg debugindex .hg/store/data/adifferentfile.i
-     rev    offset  length   base linkrev nodeid       p1           p2
-       0         0      75      0       7 2565f3199a74 000000000000 000000000000
-  $ hg debugindex .hg/store/data/anotherfile.i
-     rev    offset  length   base linkrev nodeid       p1           p2
-       0         0      75      0       8 2565f3199a74 000000000000 000000000000
-  $ hg debugindex .hg/store/data/fred.i
-     rev    offset  length   base linkrev nodeid       p1           p2
-       0         0       8      0       6 12ab3bcc5ea4 000000000000 000000000000
-  $ hg debugindex .hg/store/00manifest.i
-     rev    offset  length   base linkrev nodeid       p1           p2
-       0         0      48      0       0 43eadb1d2d06 000000000000 000000000000
-       1        48      48      1       1 8b89697eba2c 43eadb1d2d06 000000000000
-       2        96      48      2       2 626a32663c2f 8b89697eba2c 000000000000
-       3       144      48      3       3 f54c32f13478 626a32663c2f 000000000000
-       4       192      58      3       6 de68e904d169 626a32663c2f 000000000000
-       5       250      68      3       7 09bb521d218d de68e904d169 000000000000
-       6       318      54      6       8 1fde233dfb0f f54c32f13478 000000000000
-  $ hg verify
-  checking changesets
-  checking manifests
-  crosschecking files in changesets and manifests
-  checking files
-  4 files, 9 changesets, 7 total revisions
   $ cd ..
 
 clone remote via stream
 
   $ for i in 0 1 2 3 4 5 6 7 8; do
-  >    hg clone -e "python ./dummyssh" --uncompressed -r "$i" ssh://user@dummy/remote test-"$i"
+  >    hg clone -e "python $TESTDIR/dummyssh" --uncompressed -r "$i" ssh://user@dummy/remote test-"$i"
   >    if cd test-"$i"; then
   >       hg verify
   >       cd ..
@@ -226,13 +139,13 @@
   4 files, 9 changesets, 7 total revisions
   $ cd ..
   $ cd test-1
-  $ hg pull -e "python ../dummyssh" -r 4 ssh://user@dummy/remote
+  $ hg pull -e "python $TESTDIR/dummyssh" -r 4 ssh://user@dummy/remote
   pulling from ssh://user@dummy/remote
   searching for changes
   adding changesets
   adding manifests
   adding file changes
-  added 1 changesets with 0 changes to 1 files (+1 heads)
+  added 1 changesets with 0 changes to 0 files (+1 heads)
   (run 'hg heads' to see heads, 'hg merge' to merge)
   $ hg verify
   checking changesets
@@ -240,7 +153,7 @@
   crosschecking files in changesets and manifests
   checking files
   1 files, 3 changesets, 2 total revisions
-  $ hg pull -e "python ../dummyssh" ssh://user@dummy/remote
+  $ hg pull -e "python $TESTDIR/dummyssh" ssh://user@dummy/remote
   pulling from ssh://user@dummy/remote
   searching for changes
   adding changesets
@@ -250,13 +163,13 @@
   (run 'hg update' to get a working copy)
   $ cd ..
   $ cd test-2
-  $ hg pull -e "python ../dummyssh" -r 5 ssh://user@dummy/remote
+  $ hg pull -e "python $TESTDIR/dummyssh" -r 5 ssh://user@dummy/remote
   pulling from ssh://user@dummy/remote
   searching for changes
   adding changesets
   adding manifests
   adding file changes
-  added 2 changesets with 0 changes to 1 files (+1 heads)
+  added 2 changesets with 0 changes to 0 files (+1 heads)
   (run 'hg heads' to see heads, 'hg merge' to merge)
   $ hg verify
   checking changesets
@@ -264,7 +177,7 @@
   crosschecking files in changesets and manifests
   checking files
   1 files, 5 changesets, 3 total revisions
-  $ hg pull -e "python ../dummyssh" ssh://user@dummy/remote
+  $ hg pull -e "python $TESTDIR/dummyssh" ssh://user@dummy/remote
   pulling from ssh://user@dummy/remote
   searching for changes
   adding changesets
--- a/tests/test-ssh.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-ssh.t	Sat Jun 18 17:03:01 2011 -0500
@@ -2,41 +2,14 @@
 
 This test tries to exercise the ssh functionality with a dummy script
 
-  $ cat <<EOF > dummyssh
-  > import sys
-  > import os
-  > 
-  > os.chdir(os.path.dirname(sys.argv[0]))
-  > if sys.argv[1] != "user@dummy":
-  >     sys.exit(-1)
-  > 
-  > if not os.path.exists("dummyssh"):
-  >     sys.exit(-1)
-  > 
-  > os.environ["SSH_CLIENT"] = "127.0.0.1 1 2"
-  > 
-  > log = open("dummylog", "ab")
-  > log.write("Got arguments")
-  > for i, arg in enumerate(sys.argv[1:]):
-  >     log.write(" %d:%s" % (i+1, arg))
-  > log.write("\n")
-  > log.close()
-  > r = os.system(sys.argv[2])
-  > sys.exit(bool(r))
-  > EOF
-  $ cat <<EOF > badhook
-  > import sys
-  > sys.stdout.write("KABOOM\n")
-  > EOF
-
-creating 'remote
+creating 'remote' repo
 
   $ hg init remote
   $ cd remote
   $ echo this > foo
   $ echo this > fooO
   $ hg ci -A -m "init" foo fooO
-  $ echo <<EOF > .hg/hgrc
+  $ cat <<EOF > .hg/hgrc
   > [server]
   > uncompressed = True
   > 
@@ -47,21 +20,21 @@
 
 repo not found error
 
-  $ hg clone -e "python ./dummyssh" ssh://user@dummy/nonexistent local
+  $ hg clone -e "python $TESTDIR/dummyssh" ssh://user@dummy/nonexistent local
   remote: abort: There is no Mercurial repository here (.hg not found)!
   abort: no suitable response from remote hg!
   [255]
 
 non-existent absolute path
 
-  $ hg clone -e "python ./dummyssh" ssh://user@dummy//`pwd`/nonexistent local
+  $ hg clone -e "python $TESTDIR/dummyssh" ssh://user@dummy//`pwd`/nonexistent local
   remote: abort: There is no Mercurial repository here (.hg not found)!
   abort: no suitable response from remote hg!
   [255]
 
 clone remote via stream
 
-  $ hg clone -e "python ./dummyssh" --uncompressed ssh://user@dummy/remote local-stream
+  $ hg clone -e "python $TESTDIR/dummyssh" --uncompressed ssh://user@dummy/remote local-stream
   streaming all changes
   4 files to transfer, 392 bytes of data
   transferred 392 bytes in * seconds (*/sec) (glob)
@@ -78,7 +51,7 @@
 
 clone remote via pull
 
-  $ hg clone -e "python ./dummyssh" ssh://user@dummy/remote local
+  $ hg clone -e "python $TESTDIR/dummyssh" ssh://user@dummy/remote local
   requesting all changes
   adding changesets
   adding manifests
@@ -103,7 +76,7 @@
 
   $ hg paths
   default = ssh://user@dummy/remote
-  $ hg pull -e "python ../dummyssh"
+  $ hg pull -e "python $TESTDIR/dummyssh"
   pulling from ssh://user@dummy/remote
   searching for changes
   no changes found
@@ -117,7 +90,7 @@
 
   $ echo "default-push = ssh://user@dummy/remote" >> .hg/hgrc
   $ echo "[ui]" >> .hg/hgrc
-  $ echo "ssh = python ../dummyssh" >> .hg/hgrc
+  $ echo "ssh = python $TESTDIR/dummyssh" >> .hg/hgrc
 
 find outgoing
 
@@ -133,7 +106,7 @@
 
 find incoming on the remote side
 
-  $ hg incoming -R ../remote -e "python ../dummyssh" ssh://user@dummy/local
+  $ hg incoming -R ../remote -e "python $TESTDIR/dummyssh" ssh://user@dummy/local
   comparing with ssh://user@dummy/local
   searching for changes
   changeset:   1:a28a9d1a809c
@@ -145,7 +118,7 @@
 
 find incoming on the remote side (using absolute path)
 
-  $ hg incoming -R ../remote -e "python ../dummyssh" "ssh://user@dummy/`pwd`"
+  $ hg incoming -R ../remote -e "python $TESTDIR/dummyssh" "ssh://user@dummy/`pwd`"
   comparing with ssh://user@dummy/$TESTTMP/local
   searching for changes
   changeset:   1:a28a9d1a809c
@@ -190,7 +163,7 @@
 test pushkeys and bookmarks
 
   $ cd ../local
-  $ hg debugpushkey --config ui.ssh="python ../dummyssh" ssh://user@dummy/remote namespaces
+  $ hg debugpushkey --config ui.ssh="python $TESTDIR/dummyssh" ssh://user@dummy/remote namespaces
   bookmarks	
   namespaces	
   $ hg book foo -r 0
@@ -203,7 +176,7 @@
   searching for changes
   no changes found
   exporting bookmark foo
-  $ hg debugpushkey --config ui.ssh="python ../dummyssh" ssh://user@dummy/remote bookmarks
+  $ hg debugpushkey --config ui.ssh="python $TESTDIR/dummyssh" ssh://user@dummy/remote bookmarks
   foo	1160648e36cec0054048a7edc4110c6f84fde594
   $ hg book -f foo
   $ hg push --traceback
@@ -219,7 +192,6 @@
   $ hg book -f -r 0 foo
   $ hg pull -B foo
   pulling from ssh://user@dummy/remote
-  searching for changes
   no changes found
   updating bookmark foo
   importing bookmark foo
@@ -232,8 +204,13 @@
 
 a bad, evil hook that prints to stdout
 
+  $ cat <<EOF > $TESTTMP/badhook
+  > import sys
+  > sys.stdout.write("KABOOM\n")
+  > EOF
+
   $ echo '[hooks]' >> ../remote/.hg/hgrc
-  $ echo 'changegroup.stdout = python ../badhook' >> ../remote/.hg/hgrc
+  $ echo "changegroup.stdout = python $TESTTMP/badhook" >> ../remote/.hg/hgrc
   $ echo r > r
   $ hg ci -A -m z r
 
@@ -263,10 +240,28 @@
   summary:     z
   
 
+clone bookmarks
+
+  $ hg -R ../remote bookmark test
+  $ hg -R ../remote bookmarks
+   * test                      2:6c0482d977a3
+  $ hg clone -e "python $TESTDIR/dummyssh" ssh://user@dummy/remote local-bookmarks
+  requesting all changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 4 changesets with 5 changes to 4 files (+1 heads)
+  updating to branch default
+  3 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ hg -R local-bookmarks bookmarks
+     test                      2:6c0482d977a3
+
 passwords in ssh urls are not supported
+(we use a glob here because different Python versions give different
+results here)
 
   $ hg push ssh://user:erroneouspwd@dummy/remote
-  pushing to ssh://user:***@dummy/remote
+  pushing to ssh://user:*@dummy/remote (glob)
   abort: password in URL not supported!
   [255]
 
@@ -281,6 +276,7 @@
   Got arguments 1:user@dummy 2:hg -R local serve --stdio
   Got arguments 1:user@dummy 2:hg -R $TESTTMP/local serve --stdio
   Got arguments 1:user@dummy 2:hg -R remote serve --stdio
+  changegroup-in-remote hook: HG_NODE=a28a9d1a809cab7d4e2fde4bee738a9ede948b60 HG_SOURCE=serve HG_URL=remote:ssh:127.0.0.1 
   Got arguments 1:user@dummy 2:hg -R remote serve --stdio
   Got arguments 1:user@dummy 2:hg -R remote serve --stdio
   Got arguments 1:user@dummy 2:hg -R remote serve --stdio
@@ -290,3 +286,5 @@
   Got arguments 1:user@dummy 2:hg -R remote serve --stdio
   Got arguments 1:user@dummy 2:hg -R remote serve --stdio
   Got arguments 1:user@dummy 2:hg -R remote serve --stdio
+  changegroup-in-remote hook: HG_NODE=1383141674ec756a6056f6a9097618482fe0f4a6 HG_SOURCE=serve HG_URL=remote:ssh:127.0.0.1 
+  Got arguments 1:user@dummy 2:hg -R remote serve --stdio
--- a/tests/test-static-http.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-static-http.t	Sat Jun 18 17:03:01 2011 -0500
@@ -22,9 +22,8 @@
   > EOF
   $ python dumb.py 2>/dev/null &
   $ echo $! >> $DAEMON_PIDS
-  $ mkdir remote
+  $ hg init remote
   $ cd remote
-  $ hg init
   $ echo foo > bar
   $ echo c2 > '.dotfile with spaces'
   $ hg add
@@ -118,7 +117,7 @@
   adding file changes
   added 1 changesets with 3 changes to 3 files
   updating to branch default
-  pulling subrepo sub from static-http://localhost:$HGPORT/sub
+  cloning subrepo sub from static-http://localhost:$HGPORT/sub
   requesting all changes
   adding changesets
   adding manifests
--- a/tests/test-status-color.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-status-color.t	Sat Jun 18 17:03:01 2011 -0500
@@ -2,6 +2,8 @@
   $ echo "color=" >> $HGRCPATH
   $ echo "[color]" >> $HGRCPATH
   $ echo "mode=ansi" >> $HGRCPATH
+Terminfo codes compatibility fix
+  $ echo "color.none=0" >> $HGRCPATH
 
   $ hg init repo1
   $ cd repo1
@@ -163,6 +165,19 @@
   \x1b[0;0mC .hgignore\x1b[0m (esc)
   \x1b[0;0mC modified\x1b[0m (esc)
 
+hg status -A (with terminfo color):
+
+  $ TERM=xterm hg status --config color.mode=terminfo --color=always -A
+  \x1b[30m\x1b[32m\x1b[1mA added\x1b[30m (esc)
+  \x1b[30m\x1b[32m\x1b[1mA copied\x1b[30m (esc)
+  \x1b[30m\x1b[30m  modified\x1b[30m (esc)
+  \x1b[30m\x1b[31m\x1b[1mR removed\x1b[30m (esc)
+  \x1b[30m\x1b[36m\x1b[1m\x1b[4m! deleted\x1b[30m (esc)
+  \x1b[30m\x1b[35m\x1b[1m\x1b[4m? unknown\x1b[30m (esc)
+  \x1b[30m\x1b[30m\x1b[1mI ignored\x1b[30m (esc)
+  \x1b[30m\x1b[30mC .hgignore\x1b[30m (esc)
+  \x1b[30m\x1b[30mC modified\x1b[30m (esc)
+
 
   $ echo "^ignoreddir$" > .hgignore
   $ mkdir ignoreddir
--- a/tests/test-strip-cross.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-strip-cross.t	Sat Jun 18 17:03:01 2011 -0500
@@ -32,60 +32,62 @@
   $ commit '012' 'manifest-file'
   $ cd ..
   $ hg clone -q -U -r -1 -r -2 -r -3 -r -4 -r -6 orig crossed
-  $ for i in crossed/.hg/store/00manifest.i crossed/.hg/store/data/*.i; do
-  >     echo $i
-  >     hg debugindex $i
-  >     echo
-  > done
-  crossed/.hg/store/00manifest.i
+  $ cd crossed
+  $ hg debugindex --manifest
      rev    offset  length   base linkrev nodeid       p1           p2
        0         0     112      0       0 6f105cbb914d 000000000000 000000000000
        1       112      56      1       3 1b55917b3699 000000000000 000000000000
        2       168     123      1       1 8f3d04e263e5 000000000000 000000000000
        3       291     122      1       2 f0ef8726ac4f 000000000000 000000000000
        4       413      87      4       4 0b76e38b4070 000000000000 000000000000
-  
-  crossed/.hg/store/data/012.i
+
+  $ for i in 012 021 102 120 201 210 manifest-file; do
+  >     echo $i
+  >     hg debugindex $i
+  >     echo
+  > done
+  012
      rev    offset  length   base linkrev nodeid       p1           p2
        0         0       3      0       0 b8e02f643373 000000000000 000000000000
        1         3       3      1       1 5d9299349fc0 000000000000 000000000000
        2         6       3      2       2 2661d26c6496 000000000000 000000000000
   
-  crossed/.hg/store/data/021.i
+  021
      rev    offset  length   base linkrev nodeid       p1           p2
        0         0       3      0       0 b8e02f643373 000000000000 000000000000
        1         3       3      1       2 5d9299349fc0 000000000000 000000000000
        2         6       3      2       1 2661d26c6496 000000000000 000000000000
   
-  crossed/.hg/store/data/102.i
+  102
      rev    offset  length   base linkrev nodeid       p1           p2
        0         0       3      0       1 b8e02f643373 000000000000 000000000000
        1         3       3      1       0 5d9299349fc0 000000000000 000000000000
        2         6       3      2       2 2661d26c6496 000000000000 000000000000
   
-  crossed/.hg/store/data/120.i
+  120
      rev    offset  length   base linkrev nodeid       p1           p2
        0         0       3      0       1 b8e02f643373 000000000000 000000000000
        1         3       3      1       2 5d9299349fc0 000000000000 000000000000
        2         6       3      2       0 2661d26c6496 000000000000 000000000000
   
-  crossed/.hg/store/data/201.i
+  201
      rev    offset  length   base linkrev nodeid       p1           p2
        0         0       3      0       2 b8e02f643373 000000000000 000000000000
        1         3       3      1       0 5d9299349fc0 000000000000 000000000000
        2         6       3      2       1 2661d26c6496 000000000000 000000000000
   
-  crossed/.hg/store/data/210.i
+  210
      rev    offset  length   base linkrev nodeid       p1           p2
        0         0       3      0       2 b8e02f643373 000000000000 000000000000
        1         3       3      1       1 5d9299349fc0 000000000000 000000000000
        2         6       3      2       0 2661d26c6496 000000000000 000000000000
   
-  crossed/.hg/store/data/manifest-file.i
+  manifest-file
      rev    offset  length   base linkrev nodeid       p1           p2
        0         0       3      0       3 b8e02f643373 000000000000 000000000000
        1         3       3      1       4 5d9299349fc0 000000000000 000000000000
   
+  $ cd ..
   $ for i in 0 1 2 3 4; do
   >     hg clone -q -U --pull crossed $i
   >     echo "% Trying to strip revision $i"
--- a/tests/test-subrepo-deep-nested-change.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-subrepo-deep-nested-change.t	Sat Jun 18 17:03:01 2011 -0500
@@ -27,12 +27,7 @@
   $ echo "sub1 = ../sub1" > main/.hgsub
   $ hg clone sub1 main/sub1
   updating to branch default
-  pulling subrepo sub2 from $TESTTMP/sub2
-  requesting all changes
-  adding changesets
-  adding manifests
-  adding file changes
-  added 1 changesets with 1 changes to 1 files
+  cloning subrepo sub2 from $TESTTMP/sub2
   3 files updated, 0 files merged, 0 files removed, 0 files unresolved
   $ hg add -R main
   adding main/.hgsub
@@ -55,18 +50,8 @@
 
   $ hg clone main cloned
   updating to branch default
-  pulling subrepo sub1 from $TESTTMP/sub1
-  requesting all changes
-  adding changesets
-  adding manifests
-  adding file changes
-  added 1 changesets with 3 changes to 3 files
-  pulling subrepo sub1/sub2 from $TESTTMP/sub2
-  requesting all changes
-  adding changesets
-  adding manifests
-  adding file changes
-  added 1 changesets with 1 changes to 1 files
+  cloning subrepo sub1 from $TESTTMP/sub1
+  cloning subrepo sub1/sub2 from $TESTTMP/sub2
   3 files updated, 0 files merged, 0 files removed, 0 files unresolved
 
 Checking cloned repo ids
--- a/tests/test-subrepo-git.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-subrepo-git.t	Sat Jun 18 17:03:01 2011 -0500
@@ -73,7 +73,7 @@
   $ cd t
   $ hg clone . ../tc
   updating to branch default
-  cloning subrepo s
+  cloning subrepo s from $TESTTMP/gitroot
   3 files updated, 0 files merged, 0 files removed, 0 files unresolved
   $ cd ../tc
   $ hg debugsub
@@ -96,7 +96,7 @@
   $ cd ../t
   $ hg clone . ../ta
   updating to branch default
-  cloning subrepo s
+  cloning subrepo s from $TESTTMP/gitroot
   3 files updated, 0 files merged, 0 files removed, 0 files unresolved
 
   $ cd ../ta
@@ -115,7 +115,7 @@
   $ cd ../t
   $ hg clone . ../tb
   updating to branch default
-  cloning subrepo s
+  cloning subrepo s from $TESTTMP/gitroot
   3 files updated, 0 files merged, 0 files removed, 0 files unresolved
 
   $ cd ../tb/s
@@ -155,7 +155,7 @@
   added 1 changesets with 1 changes to 1 files (+1 heads)
   (run 'hg heads' to see heads, 'hg merge' to merge)
   $ hg merge 2>/dev/null
-  pulling subrepo s
+  pulling subrepo s from $TESTTMP/gitroot
   0 files updated, 0 files merged, 0 files removed, 0 files unresolved
   (branch merge, don't forget to commit)
   $ cat s/f
@@ -199,7 +199,7 @@
   $ cd ../t
   $ hg clone . ../td
   updating to branch default
-  cloning subrepo s
+  cloning subrepo s from $TESTTMP/gitroot
   checking out detached HEAD in subrepo s
   check out a git branch if you intend to make changes
   3 files updated, 0 files merged, 0 files removed, 0 files unresolved
@@ -232,7 +232,7 @@
   $ cd ../tb
   $ hg pull -q
   $ hg update 2>/dev/null
-  pulling subrepo s
+  pulling subrepo s from $TESTTMP/gitroot
   2 files updated, 0 files merged, 0 files removed, 0 files unresolved
   $ hg debugsub
   path s
@@ -262,7 +262,7 @@
   $ cd ../tc
   $ hg pull -q
   $ hg archive --subrepos -r 5 ../archive 2>/dev/null
-  pulling subrepo s
+  pulling subrepo s from $TESTTMP/gitroot
   $ cd ../archive
   $ cat s/f
   f
@@ -282,7 +282,7 @@
 
   $ hg clone ../t inner
   updating to branch default
-  cloning subrepo s
+  cloning subrepo s from $TESTTMP/gitroot
   3 files updated, 0 files merged, 0 files removed, 0 files unresolved
   $ echo inner = inner > .hgsub
   $ hg add .hgsub
@@ -311,7 +311,7 @@
   $ mkdir d
   $ hg clone t d/t
   updating to branch default
-  cloning subrepo s
+  cloning subrepo s from $TESTTMP/gitroot
   3 files updated, 0 files merged, 0 files removed, 0 files unresolved
 
 Don't crash if the subrepo is missing
@@ -329,7 +329,7 @@
   abort: subrepo s is missing
   [255]
   $ hg update -C
-  cloning subrepo s
+  cloning subrepo s from $TESTTMP/gitroot
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
   $ hg sum | grep commit
   commit: (clean)
--- a/tests/test-subrepo-paths.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-subrepo-paths.t	Sat Jun 18 17:03:01 2011 -0500
@@ -21,6 +21,15 @@
    source   C:\libs\foo-lib\
    revision 
 
+test cumulative remapping, the $HGRCPATH file is loaded first
+
+  $ echo '[subpaths]' >> $HGRCPATH
+  $ echo 'libfoo = libbar' >> $HGRCPATH
+  $ hg debugsub
+  path sub
+   source   C:\libs\bar-lib\
+   revision 
+
 test bad subpaths pattern
 
   $ cat > .hg/hgrc <<EOF
--- a/tests/test-subrepo-recursion.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-subrepo-recursion.t	Sat Jun 18 17:03:01 2011 -0500
@@ -313,18 +313,8 @@
   $ cd ..
   $ hg clone repo repo2
   updating to branch default
-  pulling subrepo foo from $TESTTMP/repo/foo
-  requesting all changes
-  adding changesets
-  adding manifests
-  adding file changes
-  added 4 changesets with 7 changes to 3 files
-  pulling subrepo foo/bar from $TESTTMP/repo/foo/bar
-  requesting all changes
-  adding changesets
-  adding manifests
-  adding file changes
-  added 3 changesets with 3 changes to 1 files
+  cloning subrepo foo from $TESTTMP/repo/foo
+  cloning subrepo foo/bar from $TESTTMP/repo/foo/bar
   3 files updated, 0 files merged, 0 files removed, 0 files unresolved
   $ cd repo2
   $ hg outgoing -S
--- a/tests/test-subrepo-relative-path.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-subrepo-relative-path.t	Sat Jun 18 17:03:01 2011 -0500
@@ -44,7 +44,7 @@
   adding file changes
   added 1 changesets with 3 changes to 3 files
   updating to branch default
-  pulling subrepo sub from http://localhost:$HGPORT/sub
+  cloning subrepo sub from http://localhost:$HGPORT/sub
   requesting all changes
   adding changesets
   adding manifests
@@ -67,3 +67,37 @@
    revision 863c1745b441bd97a8c4a096e87793073f4fb215
 
   $ "$TESTDIR/killdaemons.py"
+
+subrepo paths with ssh urls
+
+  $ cp $TESTDIR/dummyssh $BINDIR/ssh
+
+  $ hg clone ssh://user@dummy/cloned sshclone
+  requesting all changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 3 changes to 3 files
+  updating to branch default
+  cloning subrepo sub from ssh://user@dummy/sub
+  requesting all changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 1 changes to 1 files
+  3 files updated, 0 files merged, 0 files removed, 0 files unresolved
+
+  $ hg -R sshclone push ssh://user@dummy/$TESTTMP/cloned
+  pushing to ssh://user@dummy/$TESTTMP/cloned
+  pushing subrepo sub to ssh://user@dummy/$TESTTMP/sub
+  searching for changes
+  no changes found
+  searching for changes
+  no changes found
+
+  $ cat dummylog
+  Got arguments 1:user@dummy 2:hg -R cloned serve --stdio
+  Got arguments 1:user@dummy 2:hg -R sub serve --stdio
+  Got arguments 1:user@dummy 2:hg -R $TESTTMP/cloned serve --stdio
+  Got arguments 1:user@dummy 2:hg -R $TESTTMP/sub serve --stdio
+  $ rm $BINDIR/ssh
--- a/tests/test-subrepo-svn.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-subrepo-svn.t	Sat Jun 18 17:03:01 2011 -0500
@@ -225,6 +225,14 @@
   $ cd ..
   $ hg clone t tc | fix_path
   updating to branch default
+  A    tc/s/alpha
+   U   tc/s
+  
+  Fetching external item into 'tc/s/externals'
+  A    tc/s/externals/other
+  Checked out external at revision 1.
+  
+  Checked out revision 3.
   A    tc/subdir/s/alpha
    U   tc/subdir/s
   
@@ -233,14 +241,6 @@
   Checked out external at revision 1.
   
   Checked out revision 2.
-  A    tc/s/alpha
-   U   tc/s
-  
-  Fetching external item into 'tc/s/externals'
-  A    tc/s/externals/other
-  Checked out external at revision 1.
-  
-  Checked out revision 3.
   3 files updated, 0 files merged, 0 files removed, 0 files unresolved
   $ cd tc
 
@@ -489,3 +489,33 @@
   $ if "$TESTDIR/hghave" -q svn15; then
   > hg up 2 >/dev/null 2>&1 || echo update failed
   > fi
+
+Modify one of the externals to point to a different path so we can
+test having obstructions when switching branches on checkout:
+  $ hg checkout tip
+  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ echo "obstruct =        [svn]       $SVNREPO/externals" >> .hgsub
+  $ svn co -r5 --quiet "$SVNREPO"/externals obstruct
+  $ hg commit -m 'Start making obstructed wc'
+  committing subrepository obstruct
+  $ hg book other
+  $ hg co -r 'p1(tip)'
+  2 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ echo "obstruct =        [svn]       $SVNREPO/src" >> .hgsub
+  $ svn co -r5 --quiet "$SVNREPO"/src obstruct
+  $ hg commit -m 'Other branch which will be obstructed'
+  committing subrepository obstruct
+  created new head
+
+Switching back to the head where we have another path mapped to the
+same subrepo should work if the subrepo is clean.
+  $ hg co other
+  A    $TESTTMP/rebaserepo/obstruct/other
+  Checked out revision 1.
+  2 files updated, 0 files merged, 0 files removed, 0 files unresolved
+
+This is surprising, but is also correct based on the current code:
+  $ echo "updating should (maybe) fail" > obstruct/other
+  $ hg co tip
+  abort: crosses branches (merge branches or use --clean to discard changes)
+  [255]
--- a/tests/test-subrepo.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-subrepo.t	Sat Jun 18 17:03:01 2011 -0500
@@ -239,24 +239,9 @@
   $ cd ..
   $ hg clone t tc
   updating to branch default
-  pulling subrepo s from $TESTTMP/sub/t/s
-  requesting all changes
-  adding changesets
-  adding manifests
-  adding file changes
-  added 4 changesets with 5 changes to 3 files
-  pulling subrepo s/ss from $TESTTMP/sub/t/s/ss
-  requesting all changes
-  adding changesets
-  adding manifests
-  adding file changes
-  added 1 changesets with 1 changes to 1 files
-  pulling subrepo t from $TESTTMP/sub/t/t
-  requesting all changes
-  adding changesets
-  adding manifests
-  adding file changes
-  added 4 changesets with 4 changes to 1 files (+1 heads)
+  cloning subrepo s from $TESTTMP/sub/t/s
+  cloning subrepo s/ss from $TESTTMP/sub/t/s/ss
+  cloning subrepo t from $TESTTMP/sub/t/t
   3 files updated, 0 files merged, 0 files removed, 0 files unresolved
   $ cd tc
   $ hg debugsub
@@ -304,7 +289,7 @@
   no changes found
   pushing subrepo s to $TESTTMP/sub/t/s
   searching for changes
-  abort: push creates new remote heads on branch 'default'!
+  abort: push creates new remote head 12a213df6fa9!
   (did you forget to merge? use push -f to force)
   [255]
   $ hg push -f
@@ -515,6 +500,7 @@
   $ hg -R testdelete remove testdelete/.hgsub
   $ hg -R testdelete ci -m ".hgsub deleted"
   $ cat testdelete/.hgsubstate
+  bdf5c9a3103743d900b12ae0db3ffdcfd7b0d878 nested
 
 test repository cloning
 
@@ -563,12 +549,7 @@
   committing subrepository s
   $ hg clone repo repo2
   updating to branch default
-  pulling subrepo s from $TESTTMP/sub/repo/s
-  requesting all changes
-  adding changesets
-  adding manifests
-  adding file changes
-  added 1 changesets with 1 changes to 1 files
+  cloning subrepo s from $TESTTMP/sub/repo/s
   2 files updated, 0 files merged, 0 files removed, 0 files unresolved
   $ hg -q -R repo2 pull -u
   $ echo 1 > repo2/s/a
@@ -582,7 +563,7 @@
   $ hg -R repo2 ci -m3
   committing subrepository s
   $ hg -q -R repo2 push
-  abort: push creates new remote heads on branch 'default'!
+  abort: push creates new remote head 9d66565e64e1!
   (did you forget to merge? use push -f to force)
   [255]
   $ hg -R repo update
@@ -639,12 +620,7 @@
   adding manifests
   adding file changes
   added 1 changesets with 2 changes to 2 files
-  pulling subrepo sub/repo from issue1852a/sub/repo
-  requesting all changes
-  adding changesets
-  adding manifests
-  adding file changes
-  added 2 changesets with 2 changes to 1 files
+  cloning subrepo sub/repo from issue1852a/sub/repo
   2 files updated, 0 files merged, 0 files removed, 0 files unresolved
 
 Try to push from the other side
@@ -848,3 +824,36 @@
   fc627a69481f
   $ hg -R t id 
   e95bcfa18a35
+
+Test that removing .hgsubstate doesn't break anything:
+
+  $ hg rm -f .hgsubstate
+  $ hg ci -mrm
+  committing subrepository s
+  committing subrepository t
+  created new head
+  $ hg log -vr tip
+  changeset:   14:3941e0aa5236
+  tag:         tip
+  parent:      11:365661e5936a
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  description:
+  rm
+  
+  
+
+Test that removing .hgsub removes .hgsubstate:
+
+  $ hg rm .hgsub
+  $ hg ci -mrm2
+  $ hg log -vr tip
+  changeset:   15:8b31de9d13d1
+  tag:         tip
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  files:       .hgsub .hgsubstate
+  description:
+  rm2
+  
+  
--- a/tests/test-symlink-os-yes-fs-no.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-symlink-os-yes-fs-no.py	Sat Jun 18 17:03:01 2011 -0500
@@ -1,7 +1,8 @@
 import os, sys, time
-from mercurial import hg, ui, commands
+from mercurial import hg, ui, commands, util
 
 TESTDIR = os.environ["TESTDIR"]
+BUNDLEPATH = os.path.join(TESTDIR, 'bundles', 'test-no-symlinks.hg')
 
 # only makes sense to test on os which supports symlinks
 if not hasattr(os, "symlink"):
@@ -9,7 +10,7 @@
 
 # clone with symlink support
 u = ui.ui()
-hg.clone(u, os.path.join(TESTDIR, 'test-no-symlinks.hg'), 'test0')
+hg.clone(u, {}, BUNDLEPATH, 'test0')
 
 repo = hg.repository(u, 'test0')
 
@@ -28,7 +29,7 @@
 for f in 'test0/a.lnk', 'test0/d/b.lnk':
     os.unlink(f)
     fp = open(f, 'wb')
-    fp.write(open(f[:-4]).read())
+    fp.write(util.readfile(f[:-4]))
     fp.close()
 
 # reload repository
@@ -38,4 +39,4 @@
 
 # try cloning a repo which contains symlinks
 u = ui.ui()
-hg.clone(u, os.path.join(TESTDIR, 'test-no-symlinks.hg'), 'test1')
+hg.clone(u, {}, BUNDLEPATH, 'test1')
--- a/tests/test-tag.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-tag.t	Sat Jun 18 17:03:01 2011 -0500
@@ -292,7 +292,7 @@
   [255]
   $ hg tag --rev 1 --local t3
   $ hg tags -v
-  tip                                2:8a8f787d0d5c
+  tip                                2:2a156e8887cc
   t3                                 1:c3adabd1a5f4 local
 
   $ cd ..
--- a/tests/test-transplant.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-transplant.t	Sat Jun 18 17:03:01 2011 -0500
@@ -69,6 +69,18 @@
       "transplanted([set])"
         Transplanted changesets in set, or all transplanted changesets.
 
+test tranplanted keyword
+
+  $ hg log --template '{rev} {transplanted}\n'
+  7 a53251cdf717679d1907b289f991534be05c997a
+  6 722f4667af767100cb15b6a79324bf8abbfe1ef4
+  5 37a1297eb21b3ef5c5d2ffac22121a0988ed9f21
+  4 
+  3 
+  2 
+  1 
+  0 
+
   $ hg clone ../t ../prune
   updating to branch default
   4 files updated, 0 files merged, 0 files removed, 0 files unresolved
@@ -331,6 +343,40 @@
   [255]
   $ cd ..
 
+test environment passed to filter
+
+  $ hg init filter-environment
+  $ cd filter-environment
+  $ cat <<'EOF' >test-filter-environment
+  > #!/bin/sh
+  > echo "Transplant by $HGUSER" >> $1
+  > echo "Transplant from rev $HGREVISION" >> $1
+  > EOF
+  $ chmod +x test-filter-environment
+  $ hg transplant -s ../t --filter ./test-filter-environment 0
+  filtering * (glob)
+  applying 17ab29e464c6
+  17ab29e464c6 transplanted to 5190e68026a0
+
+  $ hg log --template '{rev} {parents} {desc}\n'
+  0  r1
+  Transplant by test
+  Transplant from rev 17ab29e464c6ca53e329470efe2a9918ac617a6f
+  $ cd ..
+
+test transplant with filter handles invalid changelog
+
+  $ hg init filter-invalid-log
+  $ cd filter-invalid-log
+  $ cat <<'EOF' >test-filter-invalid-log
+  > #!/bin/sh
+  > echo "" > $1
+  > EOF
+  $ chmod +x test-filter-invalid-log
+  $ hg transplant -s ../t --filter ./test-filter-invalid-log 0
+  filtering * (glob)
+  abort: filter corrupted changeset (no user or date)
+  [255]
 
 test with a win32ext like setup (differing EOLs)
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-treediscovery-legacy.t	Sat Jun 18 17:03:01 2011 -0500
@@ -0,0 +1,310 @@
+Tests discovery against servers without getbundle support:
+
+  $ cat >> $HGRCPATH <<EOF
+  > [ui]
+  > logtemplate="{rev} {node|short}: {desc} {branches}\n"
+  > [extensions]
+  > graphlog=
+  > EOF
+  $ cp $HGRCPATH $HGRCPATH-withcap
+
+  $ CAP="getbundle known changegroupsubset"
+  $ . "$TESTDIR/notcapable"
+  $ cp $HGRCPATH $HGRCPATH-nocap
+  $ cp $HGRCPATH-withcap $HGRCPATH
+
+Setup HTTP server control:
+
+  $ remote=http://localhost:$HGPORT/
+  $ export remote
+  $ start() {
+  >   echo '[web]' > $1/.hg/hgrc
+  >   echo 'push_ssl = false' >> $1/.hg/hgrc
+  >   echo 'allow_push = *' >> $1/.hg/hgrc
+  >   cp $HGRCPATH-nocap $HGRCPATH
+  >   hg serve -R $1 -p $HGPORT -d --pid-file=hg.pid -E errors.log
+  >   cat hg.pid >> $DAEMON_PIDS
+  > }
+  $ stop() {
+  >   "$TESTDIR/killdaemons.py"
+  >   cp $HGRCPATH-withcap $HGRCPATH
+  > }
+
+Both are empty:
+
+  $ hg init empty1
+  $ hg init empty2
+  $ start empty2
+  $ hg incoming -R empty1 $remote
+  comparing with http://localhost:$HGPORT/
+  no changes found
+  [1]
+  $ hg outgoing -R empty1 $remote
+  comparing with http://localhost:$HGPORT/
+  no changes found
+  [1]
+  $ hg pull -R empty1 $remote
+  pulling from http://localhost:$HGPORT/
+  no changes found
+  $ hg push -R empty1 $remote
+  pushing to http://localhost:$HGPORT/
+  no changes found
+  $ stop
+
+Base repo:
+
+  $ hg init main
+  $ cd main
+  $ hg debugbuilddag -mo '+2:tbase @name1 +3:thead1 <tbase @name2 +4:thead2 @both /thead1 +2:tmaintip'
+  $ hg glog
+  o  11 a19bfa7e7328: r11 both
+  |
+  o  10 8b6bad1512e1: r10 both
+  |
+  o    9 025829e08038: r9 both
+  |\
+  | o  8 d8f638ac69e9: r8 name2
+  | |
+  | o  7 b6b4d315a2ac: r7 name2
+  | |
+  | o  6 6c6f5d5f3c11: r6 name2
+  | |
+  | o  5 70314b29987d: r5 name2
+  | |
+  o |  4 e71dbbc70e03: r4 name1
+  | |
+  o |  3 2c8d5d5ec612: r3 name1
+  | |
+  o |  2 a7892891da29: r2 name1
+  |/
+  o  1 0019a3b924fd: r1
+  |
+  o  0 d57206cc072a: r0
+  
+  $ cd ..
+  $ start main
+
+Full clone:
+
+  $ hg clone main full
+  updating to branch default
+  2 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ cd full
+  $ hg incoming $remote
+  comparing with http://localhost:$HGPORT/
+  searching for changes
+  no changes found
+  [1]
+  $ hg outgoing $remote
+  comparing with http://localhost:$HGPORT/
+  searching for changes
+  no changes found
+  [1]
+  $ hg pull $remote
+  pulling from http://localhost:$HGPORT/
+  searching for changes
+  no changes found
+  $ hg push $remote
+  pushing to http://localhost:$HGPORT/
+  searching for changes
+  no changes found
+  $ cd ..
+
+Local is empty:
+
+  $ cd empty1
+  $ hg incoming $remote --rev name1
+  comparing with http://localhost:$HGPORT/
+  abort: cannot look up remote changes; remote repository does not support the 'changegroupsubset' capability!
+  [255]
+  $ hg incoming $remote
+  comparing with http://localhost:$HGPORT/
+  0 d57206cc072a: r0 
+  1 0019a3b924fd: r1 
+  2 a7892891da29: r2 name1
+  3 2c8d5d5ec612: r3 name1
+  4 e71dbbc70e03: r4 name1
+  5 70314b29987d: r5 name2
+  6 6c6f5d5f3c11: r6 name2
+  7 b6b4d315a2ac: r7 name2
+  8 d8f638ac69e9: r8 name2
+  9 025829e08038: r9 both
+  10 8b6bad1512e1: r10 both
+  11 a19bfa7e7328: r11 both
+  $ hg outgoing $remote
+  comparing with http://localhost:$HGPORT/
+  no changes found
+  [1]
+  $ hg push $remote
+  pushing to http://localhost:$HGPORT/
+  no changes found
+  $ hg pull $remote
+  pulling from http://localhost:$HGPORT/
+  requesting all changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 12 changesets with 24 changes to 2 files
+  (run 'hg update' to get a working copy)
+  $ hg incoming $remote
+  comparing with http://localhost:$HGPORT/
+  searching for changes
+  no changes found
+  [1]
+  $ cd ..
+
+Local is subset:
+
+  $ cp $HGRCPATH-withcap $HGRCPATH
+  $ hg clone main subset --rev name2 ; cd subset
+  adding changesets
+  adding manifests
+  adding file changes
+  added 6 changesets with 12 changes to 2 files
+  updating to branch name2
+  2 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ cp $HGRCPATH-nocap $HGRCPATH
+  $ hg incoming $remote
+  comparing with http://localhost:$HGPORT/
+  searching for changes
+  6 a7892891da29: r2 name1
+  7 2c8d5d5ec612: r3 name1
+  8 e71dbbc70e03: r4 name1
+  9 025829e08038: r9 both
+  10 8b6bad1512e1: r10 both
+  11 a19bfa7e7328: r11 both
+  $ hg outgoing $remote
+  comparing with http://localhost:$HGPORT/
+  searching for changes
+  no changes found
+  [1]
+  $ hg push $remote
+  pushing to http://localhost:$HGPORT/
+  searching for changes
+  no changes found
+  $ hg pull $remote
+  pulling from http://localhost:$HGPORT/
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 6 changesets with 12 changes to 2 files
+  (run 'hg update' to get a working copy)
+  $ hg incoming $remote
+  comparing with http://localhost:$HGPORT/
+  searching for changes
+  no changes found
+  [1]
+  $ cd ..
+
+Remote is empty:
+
+  $ stop ; start empty2
+  $ cd main
+  $ hg incoming $remote
+  comparing with http://localhost:$HGPORT/
+  searching for changes
+  no changes found
+  [1]
+  $ hg outgoing $remote
+  comparing with http://localhost:$HGPORT/
+  searching for changes
+  0 d57206cc072a: r0 
+  1 0019a3b924fd: r1 
+  2 a7892891da29: r2 name1
+  3 2c8d5d5ec612: r3 name1
+  4 e71dbbc70e03: r4 name1
+  5 70314b29987d: r5 name2
+  6 6c6f5d5f3c11: r6 name2
+  7 b6b4d315a2ac: r7 name2
+  8 d8f638ac69e9: r8 name2
+  9 025829e08038: r9 both
+  10 8b6bad1512e1: r10 both
+  11 a19bfa7e7328: r11 both
+  $ hg pull $remote
+  pulling from http://localhost:$HGPORT/
+  searching for changes
+  no changes found
+  $ hg push $remote
+  pushing to http://localhost:$HGPORT/
+  searching for changes
+  remote: adding changesets
+  remote: adding manifests
+  remote: adding file changes
+  remote: added 12 changesets with 24 changes to 2 files
+  $ hg outgoing $remote
+  comparing with http://localhost:$HGPORT/
+  searching for changes
+  no changes found
+  [1]
+  $ cd ..
+
+Local is superset:
+
+  $ stop
+  $ hg clone main subset2 --rev name2
+  adding changesets
+  adding manifests
+  adding file changes
+  added 6 changesets with 12 changes to 2 files
+  updating to branch name2
+  2 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ start subset2
+  $ cd main
+  $ hg incoming $remote
+  comparing with http://localhost:$HGPORT/
+  searching for changes
+  no changes found
+  [1]
+  $ hg outgoing $remote
+  comparing with http://localhost:$HGPORT/
+  searching for changes
+  2 a7892891da29: r2 name1
+  3 2c8d5d5ec612: r3 name1
+  4 e71dbbc70e03: r4 name1
+  9 025829e08038: r9 both
+  10 8b6bad1512e1: r10 both
+  11 a19bfa7e7328: r11 both
+  $ hg pull $remote
+  pulling from http://localhost:$HGPORT/
+  searching for changes
+  no changes found
+  $ hg push $remote
+  pushing to http://localhost:$HGPORT/
+  searching for changes
+  abort: push creates new remote branches: both, name1!
+  (use 'hg push --new-branch' to create new remote branches)
+  [255]
+  $ hg push $remote --new-branch
+  pushing to http://localhost:$HGPORT/
+  searching for changes
+  remote: adding changesets
+  remote: adding manifests
+  remote: adding file changes
+  remote: added 6 changesets with 12 changes to 2 files
+  $ hg outgoing $remote
+  comparing with http://localhost:$HGPORT/
+  searching for changes
+  no changes found
+  [1]
+  $ cd ..
+
+Partial pull:
+
+  $ stop ; start main
+  $ hg clone $remote partial --rev name2
+  abort: partial pull cannot be done because other repository doesn't support changegroupsubset.
+  [255]
+  $ hg init partial; cd partial
+  $ hg incoming $remote --rev name2
+  comparing with http://localhost:$HGPORT/
+  abort: cannot look up remote changes; remote repository does not support the 'changegroupsubset' capability!
+  [255]
+  $ hg pull $remote --rev name2
+  pulling from http://localhost:$HGPORT/
+  abort: partial pull cannot be done because other repository doesn't support changegroupsubset.
+  [255]
+  $ cd ..
+
+  $ stop
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-treediscovery.t	Sat Jun 18 17:03:01 2011 -0500
@@ -0,0 +1,323 @@
+Tests discovery against servers without getbundle support:
+
+  $ CAP=getbundle
+  $ . "$TESTDIR/notcapable"
+  $ cat >> $HGRCPATH <<EOF
+  > [ui]
+  > logtemplate="{rev} {node|short}: {desc} {branches}\n"
+  > [extensions]
+  > graphlog=
+  > EOF
+
+Setup HTTP server control:
+
+  $ remote=http://localhost:$HGPORT/
+  $ export remote
+  $ start() {
+  >   echo '[web]' > $1/.hg/hgrc
+  >   echo 'push_ssl = false' >> $1/.hg/hgrc
+  >   echo 'allow_push = *' >> $1/.hg/hgrc
+  >   hg serve -R $1 -p $HGPORT -d --pid-file=hg.pid -E errors.log
+  >   cat hg.pid >> $DAEMON_PIDS
+  > }
+  $ stop() {
+  >   "$TESTDIR/killdaemons.py"
+  > }
+
+Both are empty:
+
+  $ hg init empty1
+  $ hg init empty2
+  $ start empty2
+  $ hg incoming -R empty1 $remote
+  comparing with http://localhost:$HGPORT/
+  no changes found
+  [1]
+  $ hg outgoing -R empty1 $remote
+  comparing with http://localhost:$HGPORT/
+  no changes found
+  [1]
+  $ hg pull -R empty1 $remote
+  pulling from http://localhost:$HGPORT/
+  no changes found
+  $ hg push -R empty1 $remote
+  pushing to http://localhost:$HGPORT/
+  no changes found
+  $ stop
+
+Base repo:
+
+  $ hg init main
+  $ cd main
+  $ hg debugbuilddag -mo '+2:tbase @name1 +3:thead1 <tbase @name2 +4:thead2 @both /thead1 +2:tmaintip'
+  $ hg glog
+  o  11 a19bfa7e7328: r11 both
+  |
+  o  10 8b6bad1512e1: r10 both
+  |
+  o    9 025829e08038: r9 both
+  |\
+  | o  8 d8f638ac69e9: r8 name2
+  | |
+  | o  7 b6b4d315a2ac: r7 name2
+  | |
+  | o  6 6c6f5d5f3c11: r6 name2
+  | |
+  | o  5 70314b29987d: r5 name2
+  | |
+  o |  4 e71dbbc70e03: r4 name1
+  | |
+  o |  3 2c8d5d5ec612: r3 name1
+  | |
+  o |  2 a7892891da29: r2 name1
+  |/
+  o  1 0019a3b924fd: r1
+  |
+  o  0 d57206cc072a: r0
+  
+  $ cd ..
+  $ start main
+
+Full clone:
+
+  $ hg clone main full
+  updating to branch default
+  2 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ cd full
+  $ hg incoming $remote
+  comparing with http://localhost:$HGPORT/
+  searching for changes
+  no changes found
+  [1]
+  $ hg outgoing $remote
+  comparing with http://localhost:$HGPORT/
+  searching for changes
+  no changes found
+  [1]
+  $ hg pull $remote
+  pulling from http://localhost:$HGPORT/
+  searching for changes
+  no changes found
+  $ hg push $remote
+  pushing to http://localhost:$HGPORT/
+  searching for changes
+  no changes found
+  $ cd ..
+
+Local is empty:
+
+  $ cd empty1
+  $ hg incoming $remote
+  comparing with http://localhost:$HGPORT/
+  0 d57206cc072a: r0 
+  1 0019a3b924fd: r1 
+  2 a7892891da29: r2 name1
+  3 2c8d5d5ec612: r3 name1
+  4 e71dbbc70e03: r4 name1
+  5 70314b29987d: r5 name2
+  6 6c6f5d5f3c11: r6 name2
+  7 b6b4d315a2ac: r7 name2
+  8 d8f638ac69e9: r8 name2
+  9 025829e08038: r9 both
+  10 8b6bad1512e1: r10 both
+  11 a19bfa7e7328: r11 both
+  $ hg outgoing $remote
+  comparing with http://localhost:$HGPORT/
+  no changes found
+  [1]
+  $ hg push $remote
+  pushing to http://localhost:$HGPORT/
+  no changes found
+  $ hg pull $remote
+  pulling from http://localhost:$HGPORT/
+  requesting all changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 12 changesets with 24 changes to 2 files
+  (run 'hg update' to get a working copy)
+  $ hg incoming $remote
+  comparing with http://localhost:$HGPORT/
+  searching for changes
+  no changes found
+  [1]
+  $ cd ..
+
+Local is subset:
+
+  $ hg clone main subset --rev name2 ; cd subset
+  adding changesets
+  adding manifests
+  adding file changes
+  added 6 changesets with 12 changes to 2 files
+  updating to branch name2
+  2 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ hg incoming $remote
+  comparing with http://localhost:$HGPORT/
+  searching for changes
+  6 a7892891da29: r2 name1
+  7 2c8d5d5ec612: r3 name1
+  8 e71dbbc70e03: r4 name1
+  9 025829e08038: r9 both
+  10 8b6bad1512e1: r10 both
+  11 a19bfa7e7328: r11 both
+  $ hg outgoing $remote
+  comparing with http://localhost:$HGPORT/
+  searching for changes
+  no changes found
+  [1]
+  $ hg push $remote
+  pushing to http://localhost:$HGPORT/
+  searching for changes
+  no changes found
+  $ hg pull $remote
+  pulling from http://localhost:$HGPORT/
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 6 changesets with 12 changes to 2 files
+  (run 'hg update' to get a working copy)
+  $ hg incoming $remote
+  comparing with http://localhost:$HGPORT/
+  searching for changes
+  no changes found
+  [1]
+  $ cd ..
+
+Remote is empty:
+
+  $ stop ; start empty2
+  $ cd main
+  $ hg incoming $remote
+  comparing with http://localhost:$HGPORT/
+  searching for changes
+  no changes found
+  [1]
+  $ hg outgoing $remote
+  comparing with http://localhost:$HGPORT/
+  searching for changes
+  0 d57206cc072a: r0 
+  1 0019a3b924fd: r1 
+  2 a7892891da29: r2 name1
+  3 2c8d5d5ec612: r3 name1
+  4 e71dbbc70e03: r4 name1
+  5 70314b29987d: r5 name2
+  6 6c6f5d5f3c11: r6 name2
+  7 b6b4d315a2ac: r7 name2
+  8 d8f638ac69e9: r8 name2
+  9 025829e08038: r9 both
+  10 8b6bad1512e1: r10 both
+  11 a19bfa7e7328: r11 both
+  $ hg pull $remote
+  pulling from http://localhost:$HGPORT/
+  searching for changes
+  no changes found
+  $ hg push $remote
+  pushing to http://localhost:$HGPORT/
+  searching for changes
+  remote: adding changesets
+  remote: adding manifests
+  remote: adding file changes
+  remote: added 12 changesets with 24 changes to 2 files
+  $ hg outgoing $remote
+  comparing with http://localhost:$HGPORT/
+  searching for changes
+  no changes found
+  [1]
+  $ cd ..
+
+Local is superset:
+
+  $ stop
+  $ hg clone main subset2 --rev name2
+  adding changesets
+  adding manifests
+  adding file changes
+  added 6 changesets with 12 changes to 2 files
+  updating to branch name2
+  2 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ start subset2
+  $ cd main
+  $ hg incoming $remote
+  comparing with http://localhost:$HGPORT/
+  searching for changes
+  no changes found
+  [1]
+  $ hg outgoing $remote
+  comparing with http://localhost:$HGPORT/
+  searching for changes
+  2 a7892891da29: r2 name1
+  3 2c8d5d5ec612: r3 name1
+  4 e71dbbc70e03: r4 name1
+  9 025829e08038: r9 both
+  10 8b6bad1512e1: r10 both
+  11 a19bfa7e7328: r11 both
+  $ hg pull $remote
+  pulling from http://localhost:$HGPORT/
+  searching for changes
+  no changes found
+  $ hg push $remote
+  pushing to http://localhost:$HGPORT/
+  searching for changes
+  abort: push creates new remote branches: both, name1!
+  (use 'hg push --new-branch' to create new remote branches)
+  [255]
+  $ hg push $remote --new-branch
+  pushing to http://localhost:$HGPORT/
+  searching for changes
+  remote: adding changesets
+  remote: adding manifests
+  remote: adding file changes
+  remote: added 6 changesets with 12 changes to 2 files
+  $ hg outgoing $remote
+  comparing with http://localhost:$HGPORT/
+  searching for changes
+  no changes found
+  [1]
+  $ cd ..
+
+Partial pull:
+
+  $ stop ; start main
+  $ hg clone $remote partial --rev name2
+  adding changesets
+  adding manifests
+  adding file changes
+  added 6 changesets with 12 changes to 2 files
+  updating to branch name2
+  2 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ cd partial
+  $ hg incoming $remote
+  comparing with http://localhost:$HGPORT/
+  searching for changes
+  6 a7892891da29: r2 name1
+  7 2c8d5d5ec612: r3 name1
+  8 e71dbbc70e03: r4 name1
+  9 025829e08038: r9 both
+  10 8b6bad1512e1: r10 both
+  11 a19bfa7e7328: r11 both
+  $ hg incoming $remote --rev name1
+  comparing with http://localhost:$HGPORT/
+  searching for changes
+  6 a7892891da29: r2 name1
+  7 2c8d5d5ec612: r3 name1
+  8 e71dbbc70e03: r4 name1
+  $ hg pull $remote --rev name1
+  pulling from http://localhost:$HGPORT/
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 3 changesets with 6 changes to 2 files (+1 heads)
+  (run 'hg heads' to see heads)
+  $ hg incoming $remote
+  comparing with http://localhost:$HGPORT/
+  searching for changes
+  9 025829e08038: r9 both
+  10 8b6bad1512e1: r10 both
+  11 a19bfa7e7328: r11 both
+  $ cd ..
+
+  $ stop
+
--- a/tests/test-ui-color.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-ui-color.py	Sat Jun 18 17:03:01 2011 -0500
@@ -1,4 +1,6 @@
+import os, sys
 from hgext import color
+from mercurial import dispatch, ui
 
 # ensure errors aren't buffered
 testui = color.colorui()
@@ -7,3 +9,25 @@
 testui.warn('warning\n')
 testui.write_err('error\n')
 print repr(testui.popbuffer())
+
+# test dispatch.dispatch with the same ui object
+hgrc = open(os.environ["HGRCPATH"], 'w')
+hgrc.write('[extensions]\n')
+hgrc.write('color=\n')
+hgrc.close()
+
+ui_ = ui.ui()
+ui_.setconfig('ui', 'formatted', 'True')
+
+# we're not interested in the output, so write that to devnull
+ui_.fout = open(os.devnull, 'w')
+
+# call some arbitrary command just so we go through
+# color's wrapped _runcommand twice.
+def runcmd():
+    dispatch.dispatch(dispatch.request(['version', '-q'], ui_))
+
+runcmd()
+print "colored? " + str(issubclass(ui_.__class__, color.colorui))
+runcmd()
+print "colored? " + str(issubclass(ui_.__class__, color.colorui))
--- a/tests/test-ui-color.py.out	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-ui-color.py.out	Sat Jun 18 17:03:01 2011 -0500
@@ -1,3 +1,5 @@
 warning
 error
 'buffered\n'
+colored? True
+colored? True
--- a/tests/test-ui-config.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-ui-config.py	Sat Jun 18 17:03:01 2011 -0500
@@ -5,6 +5,10 @@
     'values.string=string value',
     'values.bool1=true',
     'values.bool2=false',
+    'values.boolinvalid=foo',
+    'values.int1=42',
+    'values.int2=-42',
+    'values.intinvalid=foo',
     'lists.list1=foo',
     'lists.list2=foo bar baz',
     'lists.list3=alice, bob',
@@ -23,7 +27,7 @@
     'lists.list16="longer quotation" with "no ending quotation',
     'lists.list17=this is \\" "not a quotation mark"',
     'lists.list18=\n \n\nding\ndong',
-])
+    ])
 
 print repr(testui.configitems('values'))
 print repr(testui.configitems('lists'))
@@ -43,6 +47,9 @@
 print repr(testui.configbool('values', 'unknown'))
 print repr(testui.configbool('values', 'unknown', True))
 print "---"
+print repr(testui.configint('values', 'int1'))
+print repr(testui.configint('values', 'int2'))
+print "---"
 print repr(testui.configlist('lists', 'list1'))
 print repr(testui.configlist('lists', 'list2'))
 print repr(testui.configlist('lists', 'list3'))
@@ -79,3 +86,13 @@
 # values that aren't strings should work
 testui.setconfig('hook', 'commit', function)
 print function == testui.config('hook', 'commit')
+
+# invalid values
+try:
+    testui.configbool('values', 'boolinvalid')
+except error.ConfigError:
+    print 'boolinvalid'
+try:
+    testui.configint('values', 'intinvalid')
+except error.ConfigError:
+    print 'intinvalid'
--- a/tests/test-ui-config.py.out	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-ui-config.py.out	Sat Jun 18 17:03:01 2011 -0500
@@ -1,4 +1,4 @@
-[('string', 'string value'), ('bool1', 'true'), ('bool2', 'false')]
+[('string', 'string value'), ('bool1', 'true'), ('bool2', 'false'), ('boolinvalid', 'foo'), ('int1', '42'), ('int2', '-42'), ('intinvalid', 'foo')]
 [('list1', 'foo'), ('list2', 'foo bar baz'), ('list3', 'alice, bob'), ('list4', 'foo bar baz alice, bob'), ('list5', 'abc d"ef"g "hij def"'), ('list6', '"hello world", "how are you?"'), ('list7', 'Do"Not"Separate'), ('list8', '"Do"Separate'), ('list9', '"Do\\"NotSeparate"'), ('list10', 'string "with extraneous" quotation mark"'), ('list11', 'x, y'), ('list12', '"x", "y"'), ('list13', '""" key = "x", "y" """'), ('list14', ',,,,     '), ('list15', '" just with starting quotation'), ('list16', '"longer quotation" with "no ending quotation'), ('list17', 'this is \\" "not a quotation mark"'), ('list18', '\n \n\nding\ndong')]
 ---
 'string value'
@@ -6,13 +6,16 @@
 'false'
 None
 ---
-values.string not a boolean ('string value')
+values.string is not a boolean ('string value')
 True
 False
 False
 False
 True
 ---
+42
+-42
+---
 ['foo']
 ['foo', 'bar', 'baz']
 ['alice', 'bob']
@@ -42,3 +45,5 @@
 ['foo', 'bar']
 None
 True
+boolinvalid
+intinvalid
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-unbundlehash.t	Sat Jun 18 17:03:01 2011 -0500
@@ -0,0 +1,31 @@
+
+Test wire protocol unbundle with hashed heads (capability: unbundlehash)
+
+Create a remote repository.
+
+  $ hg init remote
+  $ hg serve -R remote --config web.push_ssl=False --config web.allow_push=* -p $HGPORT -d --pid-file=hg1.pid -E error.log -A access.log
+  $ cat hg1.pid >> $DAEMON_PIDS
+
+Clone the repository and push a change.
+
+  $ hg clone http://localhost:$HGPORT/ local
+  no changes found
+  updating to branch default
+  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ touch local/README
+  $ hg ci -R local -A -m hoge
+  adding README
+  $ hg push -R local
+  pushing to http://localhost:$HGPORT/
+  searching for changes
+  remote: adding changesets
+  remote: adding manifests
+  remote: adding file changes
+  remote: added 1 changesets with 1 changes to 1 files
+
+Ensure hashed heads format is used.
+The hash here is always the same since the remote repository only has the null head.
+
+  $ cat access.log | grep unbundle
+  * - - [*] "POST /?cmd=unbundle HTTP/1.1" 200 - x-hgarg-1:heads=686173686564+6768033e216468247bd031a0a2d9876d79818f8f (glob)
--- a/tests/test-unrelated-pull.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-unrelated-pull.t	Sat Jun 18 17:03:01 2011 -0500
@@ -1,14 +1,12 @@
-  $ mkdir a
+  $ hg init a
   $ cd a
-  $ hg init
   $ echo 123 > a
   $ hg add a
   $ hg commit -m "a" -u a
 
   $ cd ..
-  $ mkdir b
+  $ hg init b
   $ cd b
-  $ hg init
   $ echo 321 > b
   $ hg add b
   $ hg commit -m "b" -u b
@@ -23,6 +21,7 @@
   pulling from ../a
   searching for changes
   warning: repository is unrelated
+  requesting all changes
   adding changesets
   adding manifests
   adding file changes
--- a/tests/test-up-local-change.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-up-local-change.t	Sat Jun 18 17:03:01 2011 -0500
@@ -1,8 +1,7 @@
   $ HGMERGE=true; export HGMERGE
 
-  $ mkdir r1
+  $ hg init r1
   $ cd r1
-  $ hg init
   $ echo a > a
   $ hg addremove
   adding a
--- a/tests/test-update-branches.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-update-branches.t	Sat Jun 18 17:03:01 2011 -0500
@@ -77,7 +77,7 @@
   parent=5
 
   $ norevtest 'none clean same'   clean 2
-  abort: crosses branches (merge branches or use --check to force update)
+  abort: crosses branches (merge branches or update --check to force update)
   parent=2
 
 
--- a/tests/test-url.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-url.py	Sat Jun 18 17:03:01 2011 -0500
@@ -7,7 +7,7 @@
 def cert(cn):
     return dict(subject=((('commonName', cn),),))
 
-from mercurial.url import _verifycert
+from mercurial.sslutil import _verifycert
 
 # Test non-wildcard certificates
 check(_verifycert(cert('example.com'), 'example.com'),
@@ -33,9 +33,13 @@
       None)
 check(_verifycert(san_cert, 'foo.example.net'),
       None)
-# subject is only checked when subjectAltName is empty
+# no fallback to subject commonName when subjectAltName has DNS
 check(_verifycert(san_cert, 'example.com'),
       'certificate is for *.example.net, example.net')
+# fallback to subject commonName when no DNS in subjectAltName
+san_cert = {'subject': ((('commonName', 'example.com'),),),
+            'subjectAltName': (('IP Address', '8.8.8.8'),)}
+check(_verifycert(san_cert, 'example.com'), None)
 
 # Avoid some pitfalls
 check(_verifycert(cert('*.foo'), 'foo'),
@@ -52,3 +56,166 @@
 # Unicode (IDN) certname isn't supported
 check(_verifycert(cert(u'\u4f8b.jp'), 'example.jp'),
       'IDN in certificate not supported')
+
+import doctest
+
+def test_url():
+    """
+    >>> from mercurial.util import url
+
+    This tests for edge cases in url.URL's parsing algorithm. Most of
+    these aren't useful for documentation purposes, so they aren't
+    part of the class's doc tests.
+
+    Query strings and fragments:
+
+    >>> url('http://host/a?b#c')
+    <url scheme: 'http', host: 'host', path: 'a', query: 'b', fragment: 'c'>
+    >>> url('http://host/a?')
+    <url scheme: 'http', host: 'host', path: 'a'>
+    >>> url('http://host/a#b#c')
+    <url scheme: 'http', host: 'host', path: 'a', fragment: 'b#c'>
+    >>> url('http://host/a#b?c')
+    <url scheme: 'http', host: 'host', path: 'a', fragment: 'b?c'>
+    >>> url('http://host/?a#b')
+    <url scheme: 'http', host: 'host', path: '', query: 'a', fragment: 'b'>
+    >>> url('http://host/?a#b', parsequery=False)
+    <url scheme: 'http', host: 'host', path: '?a', fragment: 'b'>
+    >>> url('http://host/?a#b', parsefragment=False)
+    <url scheme: 'http', host: 'host', path: '', query: 'a#b'>
+    >>> url('http://host/?a#b', parsequery=False, parsefragment=False)
+    <url scheme: 'http', host: 'host', path: '?a#b'>
+
+    IPv6 addresses:
+
+    >>> url('ldap://[2001:db8::7]/c=GB?objectClass?one')
+    <url scheme: 'ldap', host: '[2001:db8::7]', path: 'c=GB',
+         query: 'objectClass?one'>
+    >>> url('ldap://joe:xxx@[2001:db8::7]:80/c=GB?objectClass?one')
+    <url scheme: 'ldap', user: 'joe', passwd: 'xxx', host: '[2001:db8::7]',
+         port: '80', path: 'c=GB', query: 'objectClass?one'>
+
+    Missing scheme, host, etc.:
+
+    >>> url('://192.0.2.16:80/')
+    <url path: '://192.0.2.16:80/'>
+    >>> url('http://mercurial.selenic.com')
+    <url scheme: 'http', host: 'mercurial.selenic.com'>
+    >>> url('/foo')
+    <url path: '/foo'>
+    >>> url('bundle:/foo')
+    <url scheme: 'bundle', path: '/foo'>
+    >>> url('a?b#c')
+    <url path: 'a?b', fragment: 'c'>
+    >>> url('http://x.com?arg=/foo')
+    <url scheme: 'http', host: 'x.com', query: 'arg=/foo'>
+    >>> url('http://joe:xxx@/foo')
+    <url scheme: 'http', user: 'joe', passwd: 'xxx', path: 'foo'>
+
+    Just a scheme and a path:
+
+    >>> url('mailto:John.Doe@example.com')
+    <url scheme: 'mailto', path: 'John.Doe@example.com'>
+    >>> url('a:b:c:d')
+    <url path: 'a:b:c:d'>
+    >>> url('aa:bb:cc:dd')
+    <url scheme: 'aa', path: 'bb:cc:dd'>
+
+    SSH examples:
+
+    >>> url('ssh://joe@host//home/joe')
+    <url scheme: 'ssh', user: 'joe', host: 'host', path: '/home/joe'>
+    >>> url('ssh://joe:xxx@host/src')
+    <url scheme: 'ssh', user: 'joe', passwd: 'xxx', host: 'host', path: 'src'>
+    >>> url('ssh://joe:xxx@host')
+    <url scheme: 'ssh', user: 'joe', passwd: 'xxx', host: 'host'>
+    >>> url('ssh://joe@host')
+    <url scheme: 'ssh', user: 'joe', host: 'host'>
+    >>> url('ssh://host')
+    <url scheme: 'ssh', host: 'host'>
+    >>> url('ssh://')
+    <url scheme: 'ssh'>
+    >>> url('ssh:')
+    <url scheme: 'ssh'>
+
+    Non-numeric port:
+
+    >>> url('http://example.com:dd')
+    <url scheme: 'http', host: 'example.com', port: 'dd'>
+    >>> url('ssh://joe:xxx@host:ssh/foo')
+    <url scheme: 'ssh', user: 'joe', passwd: 'xxx', host: 'host', port: 'ssh',
+         path: 'foo'>
+
+    Bad authentication credentials:
+
+    >>> url('http://joe@joeville:123@4:@host/a?b#c')
+    <url scheme: 'http', user: 'joe@joeville', passwd: '123@4:',
+         host: 'host', path: 'a', query: 'b', fragment: 'c'>
+    >>> url('http://!*#?/@!*#?/:@host/a?b#c')
+    <url scheme: 'http', host: '!*', fragment: '?/@!*#?/:@host/a?b#c'>
+    >>> url('http://!*#?@!*#?:@host/a?b#c')
+    <url scheme: 'http', host: '!*', fragment: '?@!*#?:@host/a?b#c'>
+    >>> url('http://!*@:!*@@host/a?b#c')
+    <url scheme: 'http', user: '!*@', passwd: '!*@', host: 'host',
+         path: 'a', query: 'b', fragment: 'c'>
+
+    File paths:
+
+    >>> url('a/b/c/d.g.f')
+    <url path: 'a/b/c/d.g.f'>
+    >>> url('/x///z/y/')
+    <url path: '/x///z/y/'>
+    >>> url('/foo:bar')
+    <url path: '/foo:bar'>
+    >>> url('\\\\foo:bar')
+    <url path: '\\\\foo:bar'>
+    >>> url('./foo:bar')
+    <url path: './foo:bar'>
+
+    Non-localhost file URL:
+
+    >>> u = url('file://mercurial.selenic.com/foo')
+    Traceback (most recent call last):
+      File "<stdin>", line 1, in ?
+    Abort: file:// URLs can only refer to localhost
+
+    Empty URL:
+
+    >>> u = url('')
+    >>> u
+    <url path: ''>
+    >>> str(u)
+    ''
+
+    Empty path with query string:
+
+    >>> str(url('http://foo/?bar'))
+    'http://foo/?bar'
+
+    Invalid path:
+
+    >>> u = url('http://foo/bar')
+    >>> u.path = 'bar'
+    >>> str(u)
+    'http://foo/bar'
+
+    >>> u = url('file:/foo/bar/baz')
+    >>> u
+    <url scheme: 'file', path: '/foo/bar/baz'>
+    >>> str(u)
+    'file:///foo/bar/baz'
+
+    >>> u = url('file:///foo/bar/baz')
+    >>> u
+    <url scheme: 'file', path: '/foo/bar/baz'>
+    >>> str(u)
+    'file:///foo/bar/baz'
+
+    >>> u = url('file:foo/bar/baz')
+    >>> u
+    <url scheme: 'file', path: 'foo/bar/baz'>
+    >>> str(u)
+    'file:foo/bar/baz'
+    """
+
+doctest.testmod(optionflags=doctest.NORMALIZE_WHITESPACE)
--- a/tests/test-walk.t	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-walk.t	Sat Jun 18 17:03:01 2011 -0500
@@ -1,6 +1,5 @@
-  $ mkdir t
+  $ hg init t
   $ cd t
-  $ hg init
   $ mkdir -p beans
   $ for b in kidney navy turtle borlotti black pinto; do
   >     echo $b > beans/$b
@@ -29,6 +28,7 @@
   adding mammals/Procyonidae/coatimundi
   adding mammals/Procyonidae/raccoon
   adding mammals/skunk
+  warning: filename contains ':', which is reserved on Windows: 'glob:glob'
   $ hg commit -m "commit #0"
 
   $ hg debugwalk
@@ -159,7 +159,7 @@
   f  mammals/Procyonidae/raccoon     Procyonidae/raccoon
   f  mammals/skunk                   skunk
   $ hg debugwalk .hg
-  abort: path 'mammals/.hg' is inside repo 'mammals'
+  abort: path 'mammals/.hg' is inside nested repo 'mammals'
   [255]
   $ hg debugwalk ../.hg
   abort: path contains illegal component: .hg
@@ -203,7 +203,7 @@
   abort: path contains illegal component: .hg/data
   [255]
   $ hg debugwalk beans/.hg
-  abort: path 'beans/.hg' is inside repo 'beans'
+  abort: path 'beans/.hg' is inside nested repo 'beans'
   [255]
 
 Test absolute paths:
@@ -295,6 +295,18 @@
   $ hg debugwalk ignored/file
   f  ignored/file  ignored/file  exact
 
+Test listfile and listfile0
+
+  $ python -c "file('../listfile0', 'wb').write('fenugreek\0new\0')"
+  $ hg debugwalk -I 'listfile0:../listfile0'
+  f  fenugreek  fenugreek
+  f  new        new
+  $ python -c "file('../listfile', 'wb').write('fenugreek\nnew\r\nmammals/skunk\n')"
+  $ hg debugwalk -I 'listfile:../listfile'
+  f  fenugreek      fenugreek
+  f  mammals/skunk  mammals/skunk
+  f  new            new
+
   $ cd ..
   $ hg debugwalk -R t t/mammals/skunk
   f  mammals/skunk  t/mammals/skunk  exact
--- a/tests/test-walkrepo.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/test-walkrepo.py	Sat Jun 18 17:03:01 2011 -0500
@@ -1,6 +1,6 @@
 import os
 from mercurial import hg, ui
-from mercurial.util import walkrepos
+from mercurial.scmutil import walkrepos
 from os import mkdir, chdir
 from os.path import join as pjoin
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-wireproto.t	Sat Jun 18 17:03:01 2011 -0500
@@ -0,0 +1,112 @@
+
+Test wire protocol argument passing
+
+Setup repo:
+
+  $ hg init repo
+
+Local:
+
+  $ hg debugwireargs repo eins zwei --three drei --four vier
+  eins zwei drei vier None
+  $ hg debugwireargs repo eins zwei --four vier
+  eins zwei None vier None
+  $ hg debugwireargs repo eins zwei
+  eins zwei None None None
+  $ hg debugwireargs repo eins zwei --five fuenf
+  eins zwei None None fuenf
+
+HTTP:
+
+  $ hg serve -R repo -p $HGPORT -d --pid-file=hg1.pid -E error.log -A access.log
+  $ cat hg1.pid >> $DAEMON_PIDS
+
+  $ hg debugwireargs http://localhost:$HGPORT/ un deux trois quatre
+  un deux trois quatre None
+  $ hg debugwireargs http://localhost:$HGPORT/ \ un deux trois\  qu\ \ atre
+   un deux trois  qu  atre None
+  $ hg debugwireargs http://localhost:$HGPORT/ eins zwei --four vier
+  eins zwei None vier None
+  $ hg debugwireargs http://localhost:$HGPORT/ eins zwei
+  eins zwei None None None
+  $ hg debugwireargs http://localhost:$HGPORT/ eins zwei --five fuenf
+  eins zwei None None None
+  $ hg debugwireargs http://localhost:$HGPORT/ un deux trois onethousandcharactersxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+  un deux trois onethousandcharactersxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx None
+  $ cat error.log
+  $ cat access.log
+  * - - [*] "GET /?cmd=capabilities HTTP/1.1" 200 - (glob)
+  * - - [*] "GET /?cmd=debugwireargs HTTP/1.1" 200 - x-hgarg-1:four=quatre&one=un&three=trois&two=deux (glob)
+  * - - [*] "GET /?cmd=debugwireargs HTTP/1.1" 200 - x-hgarg-1:four=quatre&one=un&three=trois&two=deux (glob)
+  * - - [*] "GET /?cmd=capabilities HTTP/1.1" 200 - (glob)
+  * - - [*] "GET /?cmd=debugwireargs HTTP/1.1" 200 - x-hgarg-1:four=qu++atre&one=+un&three=trois+&two=deux (glob)
+  * - - [*] "GET /?cmd=debugwireargs HTTP/1.1" 200 - x-hgarg-1:four=qu++atre&one=+un&three=trois+&two=deux (glob)
+  * - - [*] "GET /?cmd=capabilities HTTP/1.1" 200 - (glob)
+  * - - [*] "GET /?cmd=debugwireargs HTTP/1.1" 200 - x-hgarg-1:four=vier&one=eins&two=zwei (glob)
+  * - - [*] "GET /?cmd=debugwireargs HTTP/1.1" 200 - x-hgarg-1:four=vier&one=eins&two=zwei (glob)
+  * - - [*] "GET /?cmd=capabilities HTTP/1.1" 200 - (glob)
+  * - - [*] "GET /?cmd=debugwireargs HTTP/1.1" 200 - x-hgarg-1:one=eins&two=zwei (glob)
+  * - - [*] "GET /?cmd=debugwireargs HTTP/1.1" 200 - x-hgarg-1:one=eins&two=zwei (glob)
+  * - - [*] "GET /?cmd=capabilities HTTP/1.1" 200 - (glob)
+  * - - [*] "GET /?cmd=debugwireargs HTTP/1.1" 200 - x-hgarg-1:one=eins&two=zwei (glob)
+  * - - [*] "GET /?cmd=debugwireargs HTTP/1.1" 200 - x-hgarg-1:one=eins&two=zwei (glob)
+  * - - [*] "GET /?cmd=capabilities HTTP/1.1" 200 - (glob)
+  * - - [*] "GET /?cmd=debugwireargs HTTP/1.1" 200 - x-hgarg-1:four=onethousandcharactersxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx&one x-hgarg-2:=un&three=trois&two=deux (glob)
+  * - - [*] "GET /?cmd=debugwireargs HTTP/1.1" 200 - x-hgarg-1:four=onethousandcharactersxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx&one x-hgarg-2:=un&three=trois&two=deux (glob)
+
+HTTP without the httpheader capability:
+
+  $ HGRCPATH="`pwd`/repo/.hgrc"
+  $ CAP=httpheader
+  $ . "$TESTDIR/notcapable"
+
+  $ hg serve -R repo -p $HGPORT2 -d --pid-file=hg2.pid -E error2.log -A access2.log
+  $ cat hg2.pid >> $DAEMON_PIDS
+
+  $ hg debugwireargs http://localhost:$HGPORT2/ un deux trois quatre
+  un deux trois quatre None
+  $ hg debugwireargs http://localhost:$HGPORT2/ eins zwei --four vier
+  eins zwei None vier None
+  $ hg debugwireargs http://localhost:$HGPORT2/ eins zwei
+  eins zwei None None None
+  $ hg debugwireargs http://localhost:$HGPORT2/ eins zwei --five fuenf
+  eins zwei None None None
+  $ cat error2.log
+  $ cat access2.log
+  * - - [*] "GET /?cmd=capabilities HTTP/1.1" 200 - (glob)
+  * - - [*] "GET /?cmd=debugwireargs&four=quatre&one=un&three=trois&two=deux HTTP/1.1" 200 - (glob)
+  * - - [*] "GET /?cmd=debugwireargs&four=quatre&one=un&three=trois&two=deux HTTP/1.1" 200 - (glob)
+  * - - [*] "GET /?cmd=capabilities HTTP/1.1" 200 - (glob)
+  * - - [*] "GET /?cmd=debugwireargs&four=vier&one=eins&two=zwei HTTP/1.1" 200 - (glob)
+  * - - [*] "GET /?cmd=debugwireargs&four=vier&one=eins&two=zwei HTTP/1.1" 200 - (glob)
+  * - - [*] "GET /?cmd=capabilities HTTP/1.1" 200 - (glob)
+  * - - [*] "GET /?cmd=debugwireargs&one=eins&two=zwei HTTP/1.1" 200 - (glob)
+  * - - [*] "GET /?cmd=debugwireargs&one=eins&two=zwei HTTP/1.1" 200 - (glob)
+  * - - [*] "GET /?cmd=capabilities HTTP/1.1" 200 - (glob)
+  * - - [*] "GET /?cmd=debugwireargs&one=eins&two=zwei HTTP/1.1" 200 - (glob)
+  * - - [*] "GET /?cmd=debugwireargs&one=eins&two=zwei HTTP/1.1" 200 - (glob)
+
+SSH (try to exercise the ssh functionality with a dummy script):
+
+  $ cat <<EOF > dummyssh
+  > import sys
+  > import os
+  > os.chdir(os.path.dirname(sys.argv[0]))
+  > if sys.argv[1] != "user@dummy":
+  >     sys.exit(-1)
+  > if not os.path.exists("dummyssh"):
+  >     sys.exit(-1)
+  > os.environ["SSH_CLIENT"] = "127.0.0.1 1 2"
+  > r = os.system(sys.argv[2])
+  > sys.exit(bool(r))
+  > EOF
+
+  $ hg debugwireargs --ssh "python ./dummyssh" ssh://user@dummy/repo uno due tre quattro
+  uno due tre quattro None
+  $ hg debugwireargs --ssh "python ./dummyssh" ssh://user@dummy/repo eins zwei --four vier
+  eins zwei None vier None
+  $ hg debugwireargs --ssh "python ./dummyssh" ssh://user@dummy/repo eins zwei
+  eins zwei None None None
+  $ hg debugwireargs --ssh "python ./dummyssh" ssh://user@dummy/repo eins zwei --five fuenf
+  eins zwei None None None
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-wireprotocol.py	Sat Jun 18 17:03:01 2011 -0500
@@ -0,0 +1,45 @@
+from mercurial import wireproto
+
+class proto():
+    def __init__(self, args):
+        self.args = args
+    def getargs(self, spec):
+        args = self.args
+        args.setdefault('*', {})
+        names = spec.split()
+        return [args[n] for n in names]
+
+class clientrepo(wireproto.wirerepository):
+    def __init__(self, serverrepo):
+        self.serverrepo = serverrepo
+    def _call(self, cmd, **args):
+        return wireproto.dispatch(self.serverrepo, proto(args), cmd)
+
+    @wireproto.batchable
+    def greet(self, name):
+        f = wireproto.future()
+        yield wireproto.todict(name=mangle(name)), f
+        yield unmangle(f.value)
+
+class serverrepo():
+    def greet(self, name):
+        return "Hello, " + name
+
+def mangle(s):
+    return ''.join(chr(ord(c) + 1) for c in s)
+def unmangle(s):
+    return ''.join(chr(ord(c) - 1) for c in s)
+
+def greet(repo, proto, name):
+    return mangle(repo.greet(unmangle(name)))
+
+wireproto.commands['greet'] = (greet, 'name',)
+
+srv = serverrepo()
+clt = clientrepo(srv)
+
+print clt.greet("Foobar")
+b = clt.batch()
+fs = [b.greet(s) for s in ["Fo, =;o", "Bar"]]
+b.submit()
+print [f.value for f in fs]
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-wireprotocol.py.out	Sat Jun 18 17:03:01 2011 -0500
@@ -0,0 +1,2 @@
+Hello, Foobar
+['Hello, Fo, =;o', 'Hello, Bar']
--- a/tests/tinyproxy.py	Wed Jun 01 16:32:48 2011 -0500
+++ b/tests/tinyproxy.py	Sat Jun 18 17:03:01 2011 -0500
@@ -30,6 +30,12 @@
         else:
             self.__base_handle()
 
+    def log_request(self, code='-', size='-'):
+        xheaders = [h for h in self.headers.items() if h[0].startswith('x-')]
+        self.log_message('"%s" %s %s%s',
+                         self.requestline, str(code), str(size),
+                         ''.join([' %s:%s' % h for h in sorted(xheaders)]))
+
     def _connect_to(self, netloc, soc):
         i = netloc.find(':')
         if i >= 0:
@@ -89,7 +95,7 @@
         iw = [self.connection, soc]
         ow = []
         count = 0
-        while 1:
+        while True:
             count += 1
             (ins, _, exs) = select.select(iw, ow, iw, 3)
             if exs: