merge with stable
authorMartin Geisler <mg@lazybytes.net>
Tue, 22 Nov 2011 18:16:59 +0100
changeset 15549 1fd126cd2d91
parent 15547 7f1d263a1bcb (diff)
parent 15548 f76584098c88 (current diff)
child 15555 cea62936b39a
merge with stable
tests/test-largefiles.t
--- a/contrib/check-code.py	Tue Nov 22 17:51:43 2011 +0100
+++ b/contrib/check-code.py	Tue Nov 22 18:16:59 2011 +0100
@@ -131,7 +131,8 @@
     (r'[^\n]\Z', "no trailing newline"),
     (r'(\S[ \t]+|^[ \t]+)\n', "trailing whitespace"),
 #    (r'^\s+[^_ \n][^_. \n]+_[^_\n]+\s*=', "don't use underbars in identifiers"),
-#    (r'\w*[a-z][A-Z]\w*\s*=', "don't use camelcase in identifiers"),
+    (r'^\s+(self\.)?[A-za-z][a-z0-9]+[A-Z]\w* = ',
+     "don't use camelcase in identifiers"),
     (r'^\s*(if|while|def|class|except|try)\s[^[\n]*:\s*[^\\n]#\s]+',
      "linebreak after :"),
     (r'class\s[^( \n]+:', "old-style class, use class foo(object)"),
@@ -301,7 +302,7 @@
     return lines
 
 def checkfile(f, logfunc=_defaultlogger.log, maxerr=None, warnings=False,
-              blame=False, debug=False):
+              blame=False, debug=False, lineno=True):
     """checks style and portability of a given file
 
     :f: filepath
@@ -384,7 +385,7 @@
                         bl, bu, br = blamecache[n]
                         if bl == l:
                             bd = '%s@%s' % (bu, br)
-                errors.append((f, n + 1, l, msg, bd))
+                errors.append((f, lineno and n + 1, l, msg, bd))
                 result = False
 
         errors.sort()
@@ -407,8 +408,11 @@
                       help="use annotate to generate blame info")
     parser.add_option("", "--debug", action="store_true",
                       help="show debug information")
+    parser.add_option("", "--nolineno", action="store_false",
+                      dest='lineno', help="don't show line numbers")
 
-    parser.set_defaults(per_file=15, warnings=False, blame=False, debug=False)
+    parser.set_defaults(per_file=15, warnings=False, blame=False, debug=False,
+                        lineno=True)
     (options, args) = parser.parse_args()
 
     if len(args) == 0:
@@ -416,9 +420,10 @@
     else:
         check = args
 
+    ret = 0
     for f in check:
-        ret = 0
         if not checkfile(f, maxerr=options.per_file, warnings=options.warnings,
-                         blame=options.blame, debug=options.debug):
+                         blame=options.blame, debug=options.debug,
+                         lineno=options.lineno):
             ret = 1
     sys.exit(ret)
--- a/hgext/convert/darcs.py	Tue Nov 22 17:51:43 2011 +0100
+++ b/hgext/convert/darcs.py	Tue Nov 22 18:16:59 2011 +0100
@@ -24,7 +24,7 @@
             try:
                 from elementtree.ElementTree import ElementTree, XMLParser
             except ImportError:
-                ElementTree = None
+                pass
 
 class darcs_source(converter_source, commandline):
     def __init__(self, ui, path, rev=None):
@@ -42,7 +42,7 @@
             raise util.Abort(_('darcs version 2.1 or newer needed (found %r)') %
                              version)
 
-        if ElementTree is None:
+        if "ElementTree" not in globals():
             raise util.Abort(_("Python ElementTree module is not available"))
 
         self.path = os.path.realpath(path)
--- a/hgext/mq.py	Tue Nov 22 17:51:43 2011 +0100
+++ b/hgext/mq.py	Tue Nov 22 18:16:59 2011 +0100
@@ -2915,6 +2915,9 @@
         return 0
 
     revs = scmutil.revrange(repo, revrange)
+    if repo['.'].rev() in revs and repo[None].files():
+        ui.warn(_('warning: uncommitted changes in the working directory\n'))
+
     q.finish(repo, revs)
     q.savedirty()
     return 0
--- a/hgext/rebase.py	Tue Nov 22 17:51:43 2011 +0100
+++ b/hgext/rebase.py	Tue Nov 22 18:16:59 2011 +0100
@@ -185,21 +185,19 @@
                 dest = repo[destf]
 
             if revf:
-                revgen = repo.set('%lr', revf)
+                rebaseset = repo.revs('%lr', revf)
             elif srcf:
-                revgen = repo.set('(%r)::', srcf)
+                rebaseset = repo.revs('(%r)::', srcf)
             else:
                 base = basef or '.'
-                revgen = repo.set('(children(ancestor(%r, %d)) and ::(%r))::',
-                                  base, dest, base)
-
-            rebaseset = [c.rev() for c in revgen]
+                rebaseset = repo.revs('(children(ancestor(%r, %d)) & ::%r)::',
+                    base, dest, base)
 
             if not rebaseset:
                 repo.ui.debug('base is ancestor of destination')
                 result = None
-            elif not keepf and list(repo.set('first(children(%ld) - %ld)',
-                                            rebaseset, rebaseset)):
+            elif not keepf and list(repo.revs('first(children(%ld) - %ld)',
+                                              rebaseset, rebaseset)):
                 raise util.Abort(
                     _("can't remove original changesets with"
                       " unrebased descendants"),
@@ -589,8 +587,7 @@
         # rebase on ancestor, force detach
         detach = True
     if detach:
-        detachset = [c.rev() for c in repo.set('::%d - ::%d - %d',
-                                                root, commonbase, root)]
+        detachset = repo.revs('::%d - ::%d - %d', root, commonbase, root)
 
     repo.ui.debug('rebase onto %d starting from %d\n' % (dest, root))
     state = dict.fromkeys(rebaseset, nullrev)
--- a/mercurial/bdiff.c	Tue Nov 22 17:51:43 2011 +0100
+++ b/mercurial/bdiff.c	Tue Nov 22 18:16:59 2011 +0100
@@ -425,11 +425,55 @@
 	return result ? result : PyErr_NoMemory();
 }
 
+/*
+ * If allws != 0, remove all whitespace (' ', \t and \r). Otherwise,
+ * reduce whitespace sequences to a single space and trim remaining whitespace
+ * from end of lines.
+ */
+static PyObject *fixws(PyObject *self, PyObject *args)
+{
+	PyObject *s, *result = NULL;
+	char allws, c;
+	const char *r;
+	int i, rlen, wlen = 0;
+	char *w;
+
+	if (!PyArg_ParseTuple(args, "Sb:fixws", &s, &allws))
+		return NULL;
+	r = PyBytes_AsString(s);
+	rlen = PyBytes_Size(s);
+
+	w = (char *)malloc(rlen);
+	if (!w)
+		goto nomem;
+
+	for (i = 0; i != rlen; i++) {
+		c = r[i];
+		if (c == ' ' || c == '\t' || c == '\r') {
+			if (!allws && (wlen == 0 || w[wlen - 1] != ' '))
+				w[wlen++] = ' ';
+		} else if (c == '\n' && !allws
+			  && wlen > 0 && w[wlen - 1] == ' ') {
+			w[wlen - 1] = '\n';
+		} else {
+			w[wlen++] = c;
+		}
+	}
+
+	result = PyBytes_FromStringAndSize(w, wlen);
+
+nomem:
+	free(w);
+	return result ? result : PyErr_NoMemory();
+}
+
+
 static char mdiff_doc[] = "Efficient binary diff.";
 
 static PyMethodDef methods[] = {
 	{"bdiff", bdiff, METH_VARARGS, "calculate a binary diff\n"},
 	{"blocks", blocks, METH_VARARGS, "find a list of matching lines\n"},
+	{"fixws", fixws, METH_VARARGS, "normalize diff whitespaces\n"},
 	{NULL, NULL}
 };
 
--- a/mercurial/cmdutil.py	Tue Nov 22 17:51:43 2011 +0100
+++ b/mercurial/cmdutil.py	Tue Nov 22 18:16:59 2011 +0100
@@ -1165,15 +1165,19 @@
             if ui.verbose or not exact:
                 ui.status(_('adding %s\n') % match.rel(join(f)))
 
-    if listsubrepos:
-        for subpath in wctx.substate:
-            sub = wctx.sub(subpath)
-            try:
-                submatch = matchmod.narrowmatcher(subpath, match)
+    for subpath in wctx.substate:
+        sub = wctx.sub(subpath)
+        try:
+            submatch = matchmod.narrowmatcher(subpath, match)
+            if listsubrepos:
                 bad.extend(sub.add(ui, submatch, dryrun, prefix))
-            except error.LookupError:
-                ui.status(_("skipping missing subrepository: %s\n")
-                               % join(subpath))
+            else:
+                for f in sub.walk(submatch):
+                    if submatch.exact(f):
+                        bad.extend(sub.add(ui, submatch, dryrun, prefix))
+        except error.LookupError:
+            ui.status(_("skipping missing subrepository: %s\n")
+                           % join(subpath))
 
     if not dryrun:
         rejected = wctx.add(names, prefix)
--- a/mercurial/commands.py	Tue Nov 22 17:51:43 2011 +0100
+++ b/mercurial/commands.py	Tue Nov 22 18:16:59 2011 +0100
@@ -13,6 +13,7 @@
 import patch, help, url, encoding, templatekw, discovery
 import archival, changegroup, cmdutil, hbisect
 import sshserver, hgweb, hgweb.server, commandserver
+import match as matchmod
 import merge as mergemod
 import minirst, revset, fileset
 import dagparser, context, simplemerge
@@ -105,15 +106,19 @@
     ('', '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')),
+diffwsopts = [
     ('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')),
+    ]
+
+diffopts2 = [
+    ('p', 'show-function', None, _('show which function each change is in')),
+    ('', 'reverse', None, _('produce a diff that undoes the changes')),
+    ] + diffwsopts + [
     ('U', 'unified', '',
      _('number of lines of context to show'), _('NUM')),
     ('', 'stat', None, _('output diffstat-style summary of changes')),
@@ -214,7 +219,7 @@
     ('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,
+    ] + diffwsopts + 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
@@ -269,13 +274,15 @@
     m = scmutil.match(ctx, pats, opts)
     m.bad = bad
     follow = not opts.get('no_follow')
+    diffopts = patch.diffopts(ui, opts, section='annotate')
     for abs in ctx.walk(m):
         fctx = ctx[abs]
         if not opts.get('text') and util.binary(fctx.data()):
             ui.write(_("%s: binary file\n") % ((pats and m.rel(abs)) or abs))
             continue
 
-        lines = fctx.annotate(follow=follow, linenumber=linenumber)
+        lines = fctx.annotate(follow=follow, linenumber=linenumber,
+                              diffopts=diffopts)
         pieces = []
 
         for f, sep in funcmap:
@@ -738,6 +745,17 @@
     marks = repo._bookmarks
     cur   = repo.changectx('.').node()
 
+    if delete:
+        if mark is None:
+            raise util.Abort(_("bookmark name required"))
+        if mark not in marks:
+            raise util.Abort(_("bookmark '%s' does not exist") % mark)
+        if mark == repo._bookmarkcurrent:
+            bookmarks.setcurrent(repo, None)
+        del marks[mark]
+        bookmarks.write(repo)
+        return
+
     if rename:
         if rename not in marks:
             raise util.Abort(_("bookmark '%s' does not exist") % rename)
@@ -753,17 +771,6 @@
         bookmarks.write(repo)
         return
 
-    if delete:
-        if mark is None:
-            raise util.Abort(_("bookmark name required"))
-        if mark not in marks:
-            raise util.Abort(_("bookmark '%s' does not exist") % mark)
-        if mark == repo._bookmarkcurrent:
-            bookmarks.setcurrent(repo, None)
-        del marks[mark]
-        bookmarks.write(repo)
-        return
-
     if mark is not None:
         if "\n" in mark:
             raise util.Abort(_("bookmark name cannot contain newlines"))
@@ -784,8 +791,8 @@
         if rev:
             marks[mark] = repo.lookup(rev)
         else:
-            marks[mark] = repo.changectx('.').node()
-        if not inactive and repo.changectx('.').node() == marks[mark]:
+            marks[mark] = cur
+        if not inactive and cur == marks[mark]:
             bookmarks.setcurrent(repo, mark)
         bookmarks.write(repo)
         return
@@ -2189,7 +2196,7 @@
         if ent[1] & 020000:
             mode = 'lnk'
         else:
-            mode = '%3o' % (ent[1] & 0777)
+            mode = '%3o' % (ent[1] & 0777 & ~util.umask)
         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))
@@ -2432,23 +2439,45 @@
     if not pats:
         raise util.Abort(_('no files specified'))
 
-    m = scmutil.match(repo[None], pats, opts)
+    wctx = repo[None]
+    m = scmutil.match(wctx, pats, opts)
     s = repo.status(match=m, clean=True)
     forget = sorted(s[0] + s[1] + s[3] + s[6])
+    subforget = {}
     errs = 0
 
+    for subpath in wctx.substate:
+        sub = wctx.sub(subpath)
+        try:
+            submatch = matchmod.narrowmatcher(subpath, m)
+            for fsub in sub.walk(submatch):
+                if submatch.exact(fsub):
+                    subforget[subpath + '/' + fsub] = (fsub, sub)
+        except error.LookupError:
+            ui.status(_("skipping missing subrepository: %s\n") % subpath)
+
     for f in m.files():
         if f not in repo.dirstate and not os.path.isdir(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
+            if f not in subforget:
+                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].forget(forget)
+    if ui.verbose:
+        for f in sorted(subforget.keys()):
+            ui.status(_('removing %s\n') % m.rel(f))
+
+    wctx.forget(forget)
+
+    for f in sorted(subforget.keys()):
+        fsub, sub = subforget[f]
+        sub.forget([fsub])
+
     return errs
 
 @command(
@@ -2534,16 +2563,16 @@
         revs = scmutil.revrange(repo, revs)
 
     # check for merges
-    for ctx in repo.set('%ld and merge()', revs):
-        ui.warn(_('skipping ungraftable merge revision %s\n') % ctx.rev())
-        revs.remove(ctx.rev())
+    for rev in repo.revs('%ld and merge()', revs):
+        ui.warn(_('skipping ungraftable merge revision %s\n') % rev)
+        revs.remove(rev)
     if not revs:
         return -1
 
     # check for ancestors of dest branch
-    for ctx in repo.set('::. and %ld', revs):
-        ui.warn(_('skipping ancestor revision %s\n') % ctx.rev())
-        revs.remove(ctx.rev())
+    for rev in repo.revs('::. and %ld', revs):
+        ui.warn(_('skipping ancestor revision %s\n') % rev)
+        revs.remove(rev)
     if not revs:
         return -1
 
@@ -3734,14 +3763,14 @@
     [('f', 'follow', None,
      _('follow changeset history, or file history across copies and renames')),
     ('', 'follow-first', None,
-     _('only follow the first parent of merge changesets')),
+     _('only follow the first parent of merge changesets (DEPRECATED)')),
     ('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')),
+    ('m', 'only-merges', None, _('show only merges (DEPRECATED)')),
     ('u', 'user', [], _('revisions committed by user'), _('USER')),
     ('', 'only-branch', [],
      _('show only changesets within the given named branch (DEPRECATED)'),
@@ -3750,7 +3779,7 @@
      _('show changesets within the given named branch'), _('BRANCH')),
     ('P', 'prune', [],
      _('do not display revision or any of its ancestors'), _('REV')),
-    ('', 'hidden', False, _('show hidden changesets')),
+    ('', 'hidden', False, _('show hidden changesets (DEPRECATED)')),
     ] + logopts + walkopts,
     _('[OPTION]... [FILE]'))
 def log(ui, repo, *pats, **opts):
--- a/mercurial/context.py	Tue Nov 22 17:51:43 2011 +0100
+++ b/mercurial/context.py	Tue Nov 22 18:16:59 2011 +0100
@@ -7,7 +7,7 @@
 
 from node import nullid, nullrev, short, hex
 from i18n import _
-import ancestor, bdiff, error, util, scmutil, subrepo, patch, encoding
+import ancestor, mdiff, error, util, scmutil, subrepo, patch, encoding
 import match as matchmod
 import os, errno, stat
 
@@ -117,6 +117,13 @@
         return self._repo.nodetags(self._node)
     def bookmarks(self):
         return self._repo.nodebookmarks(self._node)
+    def phase(self):
+        if self._rev == -1:
+            return 0
+        if self._rev >= len(self._repo._phaserev):
+            # outdated cache
+            del self._repo._phaserev
+        return self._repo._phaserev[self._rev]
     def hidden(self):
         return self._rev in self._repo.changelog.hiddenrevs
 
@@ -426,7 +433,7 @@
         return [filectx(self._repo, self._path, fileid=x,
                         filelog=self._filelog) for x in c]
 
-    def annotate(self, follow=False, linenumber=None):
+    def annotate(self, follow=False, linenumber=None, diffopts=None):
         '''returns a list of tuples of (ctx, line) for each line
         in the file, where ctx is the filectx of the node where
         that line was last changed.
@@ -453,8 +460,13 @@
                     without_linenumber)
 
         def pair(parent, child):
-            for a1, a2, b1, b2 in bdiff.blocks(parent[1], child[1]):
-                child[0][b1:b2] = parent[0][a1:a2]
+            blocks = mdiff.allblocks(parent[1], child[1], opts=diffopts,
+                                     refine=True)
+            for (a1, a2, b1, b2), t in blocks:
+                # Changed blocks ('!') or blocks made only of blank lines ('~')
+                # belong to the child.
+                if t == '=':
+                    child[0][b1:b2] = parent[0][a1:a2]
             return child
 
         getlog = util.lrucachefunc(lambda x: self._repo.file(x))
--- a/mercurial/discovery.py	Tue Nov 22 17:51:43 2011 +0100
+++ b/mercurial/discovery.py	Tue Nov 22 18:16:59 2011 +0100
@@ -67,14 +67,18 @@
     on circumstances:
 
     If we are not going to push anything, return a tuple (None,
-    outgoing) where outgoing is 0 if there are no outgoing
+    outgoing, common) where outgoing is 0 if there are no outgoing
     changesets and 1 if there are, but we refuse to push them
-    (e.g. would create new remote heads).
+    (e.g. would create new remote heads). The third element "common"
+    is the list of heads of the common set between local and remote.
 
-    Otherwise, return a tuple (changegroup, remoteheads), where
-    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.'''
+    Otherwise, return a tuple (changegroup, remoteheads, futureheads),
+    where changegroup is a readable file-like object whose read()
+    returns successive changegroup chunks ready to be sent over the
+    wire, remoteheads is the list of remote heads and futureheads is
+    the list of heads of the common set between local and remote to
+    be after push completion.
+    '''
     commoninc = findcommonincoming(repo, remote, force=force)
     common, revs = findcommonoutgoing(repo, remote, onlyheads=revs,
                                       commoninc=commoninc, force=force)
@@ -85,7 +89,7 @@
 
     if not outg:
         repo.ui.status(_("no changes found\n"))
-        return None, 1
+        return None, 1, common
 
     if not force and remoteheads != [nullid]:
         if remote.capable('branchmap'):
@@ -189,4 +193,10 @@
         cg = repo._changegroup(outg, 'push')
     else:
         cg = repo.getbundle('push', heads=revs, common=common)
-    return cg, remoteheads
+    # no need to compute outg ancestor. All node in outg have either:
+    # - parents in outg
+    # - parents in common
+    # - nullid parent
+    rset = repo.set('heads(%ln + %ln)', common, outg)
+    futureheads = [ctx.node() for ctx in rset]
+    return cg, remoteheads, futureheads
--- a/mercurial/dispatch.py	Tue Nov 22 17:51:43 2011 +0100
+++ b/mercurial/dispatch.py	Tue Nov 22 18:16:59 2011 +0100
@@ -24,7 +24,7 @@
 
 def run():
     "run the command in sys.argv"
-    sys.exit(dispatch(request(sys.argv[1:])))
+    sys.exit((dispatch(request(sys.argv[1:])) or 0) & 255)
 
 def dispatch(req):
     "run the command specified in req.args"
--- a/mercurial/filemerge.py	Tue Nov 22 17:51:43 2011 +0100
+++ b/mercurial/filemerge.py	Tue Nov 22 18:16:59 2011 +0100
@@ -262,7 +262,11 @@
         _matcheol(repo.wjoin(fd), back)
 
     if r:
-        ui.warn(_("merging %s failed!\n") % fd)
+        if tool == "internal:merge":
+            ui.warn(_("merging %s incomplete! "
+                      "(edit conflicts, then use 'hg resolve --mark')\n") % fd)
+        else:
+            ui.warn(_("merging %s failed!\n") % fd)
     else:
         os.unlink(back)
 
--- a/mercurial/hbisect.py	Tue Nov 22 17:51:43 2011 +0100
+++ b/mercurial/hbisect.py	Tue Nov 22 18:16:59 2011 +0100
@@ -179,7 +179,7 @@
         # that's because the bisection can go either way
         range = '( bisect(bad)::bisect(good) | bisect(good)::bisect(bad) )'
 
-        _t = [c.rev() for c in repo.set('bisect(good)::bisect(bad)')]
+        _t = repo.revs('bisect(good)::bisect(bad)')
         # The sets of topologically good or bad csets
         if len(_t) == 0:
             # Goods are topologically after bads
@@ -206,22 +206,21 @@
         ignored = '( ( (%s) | (%s) ) - (%s) )' % (iba, iga, range)
 
         if status == 'range':
-            return [c.rev() for c in repo.set(range)]
+            return repo.revs(range)
         elif status == 'pruned':
-            return [c.rev() for c in repo.set(pruned)]
+            return repo.revs(pruned)
         elif status == 'untested':
-            return [c.rev() for c in repo.set(untested)]
+            return repo.revs(untested)
         elif status == 'ignored':
-            return [c.rev() for c in repo.set(ignored)]
+            return repo.revs(ignored)
         elif status == "goods":
-            return [c.rev() for c in repo.set(goods)]
+            return repo.revs(goods)
         elif status == "bads":
-            return [c.rev() for c in repo.set(bads)]
-
+            return repo.revs(bads)
         else:
             raise error.ParseError(_('invalid bisect state'))
 
-def label(repo, node, short=False):
+def label(repo, node):
     rev = repo.changelog.rev(node)
 
     # Try explicit sets
--- a/mercurial/help/config.txt	Tue Nov 22 17:51:43 2011 +0100
+++ b/mercurial/help/config.txt	Tue Nov 22 18:16:59 2011 +0100
@@ -227,6 +227,24 @@
    processed before shell aliases and will thus not be passed to
    aliases.
 
+
+``annotate``
+""""""""
+
+Settings used when displaying file annotations. All values are
+Booleans and default to False. See ``diff`` section for related
+options for the diff command.
+
+``ignorews``
+    Ignore white space when comparing lines.
+
+``ignorewsamount``
+    Ignore changes in the amount of white space.
+
+``ignoreblanklines``
+    Ignore changes whose lines are all blank.
+
+
 ``auth``
 """"""""
 
@@ -364,8 +382,9 @@
 ``diff``
 """"""""
 
-Settings used when displaying diffs. Everything except for ``unified`` is a
-Boolean and defaults to False.
+Settings used when displaying diffs. Everything except for ``unified``
+is a Boolean and defaults to False. See ``annotate`` section for
+related options for the annotate command.
 
 ``git``
     Use git extended diff format.
--- a/mercurial/help/subrepos.txt	Tue Nov 22 17:51:43 2011 +0100
+++ b/mercurial/help/subrepos.txt	Tue Nov 22 18:16:59 2011 +0100
@@ -73,8 +73,10 @@
 -----------------------------------
 
 :add: add does not recurse in subrepos unless -S/--subrepos is
-    specified. Git and Subversion subrepositories are currently
-    silently ignored.
+    specified.  However, if you specify the full path of a file in a
+    subrepo, it will be added even without -S/--subrepos specified.
+    Git and Subversion subrepositories are currently silently
+    ignored.
 
 :archive: archive does not recurse in subrepositories unless
     -S/--subrepos is specified.
@@ -93,6 +95,9 @@
     elements. Git and Subversion subrepositories are currently
     silently ignored.
 
+:forget: forget currently only handles exact file matches in subrepos.
+    Git and Subversion subrepositories are currently silently ignored.
+
 :incoming: incoming does not recurse in subrepos unless -S/--subrepos
     is specified. Git and Subversion subrepositories are currently
     silently ignored.
--- a/mercurial/hgweb/webcommands.py	Tue Nov 22 17:51:43 2011 +0100
+++ b/mercurial/hgweb/webcommands.py	Tue Nov 22 18:16:59 2011 +0100
@@ -12,7 +12,7 @@
 from mercurial.util import binary
 from common import paritygen, staticfile, get_contact, ErrorResponse
 from common import HTTP_OK, HTTP_FORBIDDEN, HTTP_NOT_FOUND
-from mercurial import graphmod
+from mercurial import graphmod, patch
 from mercurial import help as helpmod
 from mercurial.i18n import _
 
@@ -576,6 +576,7 @@
     fctx = webutil.filectx(web.repo, req)
     f = fctx.path()
     parity = paritygen(web.stripecount)
+    diffopts = patch.diffopts(web.repo.ui, untrusted=True, section='annotate')
 
     def annotate(**map):
         last = None
@@ -585,7 +586,8 @@
             lines = enumerate([((fctx.filectx(fctx.filerev()), 1),
                                 '(binary:%s)' % mt)])
         else:
-            lines = enumerate(fctx.annotate(follow=True, linenumber=True))
+            lines = enumerate(fctx.annotate(follow=True, linenumber=True,
+                                            diffopts=diffopts))
         for lineno, ((f, targetline), l) in lines:
             fnode = f.filenode()
 
--- a/mercurial/localrepo.py	Tue Nov 22 17:51:43 2011 +0100
+++ b/mercurial/localrepo.py	Tue Nov 22 18:16:59 2011 +0100
@@ -8,7 +8,7 @@
 from node import bin, hex, nullid, nullrev, short
 from i18n import _
 import repo, changegroup, subrepo, discovery, pushkey
-import changelog, dirstate, filelog, manifest, context, bookmarks
+import changelog, dirstate, filelog, manifest, context, bookmarks, phases
 import lock, transaction, store, encoding
 import scmutil, util, extensions, hook, error, revset
 import match as matchmod
@@ -36,6 +36,7 @@
         self.wopener = scmutil.opener(self.root)
         self.baseui = baseui
         self.ui = baseui.copy()
+        self._dirtyphases = False
 
         try:
             self.ui.readconfig(self.join("hgrc"), self.root)
@@ -170,6 +171,25 @@
     def _writebookmarks(self, marks):
       bookmarks.write(self)
 
+    @filecache('phaseroots')
+    def _phaseroots(self):
+        self._dirtyphases = False
+        phaseroots = phases.readroots(self)
+        phases.filterunknown(self, phaseroots)
+        return phaseroots
+
+    @propertycache
+    def _phaserev(self):
+        cache = [0] * len(self)
+        for phase in phases.trackedphases:
+            roots = map(self.changelog.rev, self._phaseroots[phase])
+            if roots:
+                for rev in roots:
+                    cache[rev] = phase
+                for rev in self.changelog.descendants(*roots):
+                    cache[rev] = phase
+        return cache
+
     @filecache('00changelog.i', True)
     def changelog(self):
         c = changelog.changelog(self.sopener)
@@ -220,15 +240,18 @@
         for i in xrange(len(self)):
             yield i
 
+    def revs(self, expr, *args):
+        '''Return a list of revisions matching the given revset'''
+        expr = revset.formatspec(expr, *args)
+        m = revset.match(None, expr)
+        return [r for r in m(self, range(len(self)))]
+
     def set(self, expr, *args):
         '''
         Yield a context for each matching revision, after doing arg
         replacement via revset.formatspec
         '''
-
-        expr = revset.formatspec(expr, *args)
-        m = revset.match(None, expr)
-        for r in m(self, range(len(self))):
+        for r in self.revs(expr, *args):
             yield self[r]
 
     def url(self):
@@ -737,10 +760,16 @@
             util.copyfile(bkname, self.join('journal.bookmarks'))
         else:
             self.opener.write('journal.bookmarks', '')
+        phasesname = self.sjoin('phaseroots')
+        if os.path.exists(phasesname):
+            util.copyfile(phasesname, self.sjoin('journal.phaseroots'))
+        else:
+            self.sopener.write('journal.phaseroots', '')
 
         return (self.sjoin('journal'), self.join('journal.dirstate'),
                 self.join('journal.branch'), self.join('journal.desc'),
-                self.join('journal.bookmarks'))
+                self.join('journal.bookmarks'),
+                self.sjoin('journal.phaseroots'))
 
     def recover(self):
         lock = self.lock()
@@ -805,6 +834,9 @@
         if os.path.exists(self.join('undo.bookmarks')):
             util.rename(self.join('undo.bookmarks'),
                         self.join('bookmarks'))
+        if os.path.exists(self.sjoin('undo.phaseroots')):
+            util.rename(self.sjoin('undo.phaseroots'),
+                        self.sjoin('phaseroots'))
         self.invalidate()
 
         parentgone = (parents[0] not in self.changelog.nodemap or
@@ -891,6 +923,8 @@
 
         def unlock():
             self.store.write()
+            if self._dirtyphases:
+                phases.writeroots(self)
             for k, ce in self._filecache.items():
                 if k == 'dirstate':
                     continue
@@ -1209,6 +1243,8 @@
             self.hook('pretxncommit', throw=True, node=hex(n), parent1=xp1,
                       parent2=xp2, pending=p)
             self.changelog.finalize(trp)
+            # ensure the new commit is 1-phase
+            phases.retractboundary(self, 1, [n])
             tr.close()
 
             if self._branchcache:
@@ -1484,6 +1520,7 @@
                     cg = remote.changegroupsubset(fetch, heads, 'pull')
                 result = self.addchangegroup(cg, 'pull', remote.url(),
                                              lock=lock)
+            phases.advanceboundary(self, 0, common)
         finally:
             lock.release()
 
@@ -1518,24 +1555,32 @@
         if not unbundle:
             lock = remote.lock()
         try:
-            cg, remote_heads = discovery.prepush(self, remote, force, revs,
-                                                 newbranch)
-            ret = remote_heads
-            if cg is not None:
-                if unbundle:
-                    # local repo finds heads on server, finds out what
-                    # revs it must push. once revs transferred, if server
-                    # finds it has different heads (someone else won
-                    # commit/push race), server aborts.
-                    if force:
-                        remote_heads = ['force']
-                    # ssh: return remote's addchangegroup()
-                    # http: return remote's addchangegroup() or 0 for error
-                    ret = remote.unbundle(cg, remote_heads, 'push')
-                else:
-                    # we return an integer indicating remote head count change
-                    ret = remote.addchangegroup(cg, 'push', self.url(),
-                                                lock=lock)
+            # get local lock as we might write phase data
+            locallock = self.lock()
+            try:
+                cg, remote_heads, fut = discovery.prepush(self, remote, force,
+                                                           revs, newbranch)
+                ret = remote_heads
+                if cg is not None:
+                    if unbundle:
+                        # local repo finds heads on server, finds out what
+                        # revs it must push. once revs transferred, if server
+                        # finds it has different heads (someone else won
+                        # commit/push race), server aborts.
+                        if force:
+                            remote_heads = ['force']
+                        # ssh: return remote's addchangegroup()
+                        # http: return remote's addchangegroup() or 0 for error
+                        ret = remote.unbundle(cg, remote_heads, 'push')
+                    else:
+                        # we return an integer indicating remote head count change
+                        ret = remote.addchangegroup(cg, 'push', self.url(),
+                                                    lock=lock)
+                # if we don't push, the common data is already useful
+                # everything exchange is public for now
+                phases.advanceboundary(self, 0, fut)
+            finally:
+                locallock.release()
         finally:
             if lock is not None:
                 lock.release()
@@ -1942,6 +1987,9 @@
                           node=hex(cl.node(clstart)), source=srctype,
                           url=url, pending=p)
 
+            added = [cl.node(r) for r in xrange(clstart, clend)]
+            if srctype != 'strip':
+                phases.advanceboundary(self, 0, added)
             # make changelog see real files again
             cl.finalize(trp)
 
@@ -1958,9 +2006,8 @@
             self.hook("changegroup", node=hex(cl.node(clstart)),
                       source=srctype, url=url)
 
-            for i in xrange(clstart, clend):
-                self.hook("incoming", node=hex(cl.node(i)),
-                          source=srctype, url=url)
+            for n in added:
+                self.hook("incoming", node=hex(n), source=srctype, url=url)
 
         # never return 0 here:
         if dh < 0:
--- a/mercurial/mdiff.py	Tue Nov 22 17:51:43 2011 +0100
+++ b/mercurial/mdiff.py	Tue Nov 22 18:16:59 2011 +0100
@@ -67,14 +67,81 @@
 
 def wsclean(opts, text, blank=True):
     if opts.ignorews:
-        text = re.sub('[ \t\r]+', '', text)
+        text = bdiff.fixws(text, 1)
     elif opts.ignorewsamount:
-        text = re.sub('[ \t\r]+', ' ', text)
-        text = text.replace(' \n', '\n')
+        text = bdiff.fixws(text, 0)
     if blank and opts.ignoreblanklines:
         text = re.sub('\n+', '\n', text).strip('\n')
     return text
 
+def splitblock(base1, lines1, base2, lines2, opts):
+    # The input lines matches except for interwoven blank lines. We
+    # transform it into a sequence of matching blocks and blank blocks.
+    lines1 = [(wsclean(opts, l) and 1 or 0) for l in lines1]
+    lines2 = [(wsclean(opts, l) and 1 or 0) for l in lines2]
+    s1, e1 = 0, len(lines1)
+    s2, e2 = 0, len(lines2)
+    while s1 < e1 or s2 < e2:
+        i1, i2, btype = s1, s2, '='
+        if (i1 >= e1 or lines1[i1] == 0
+            or i2 >= e2 or lines2[i2] == 0):
+            # Consume the block of blank lines
+            btype = '~'
+            while i1 < e1 and lines1[i1] == 0:
+                i1 += 1
+            while i2 < e2 and lines2[i2] == 0:
+                i2 += 1
+        else:
+            # Consume the matching lines
+            while i1 < e1 and lines1[i1] == 1 and lines2[i2] == 1:
+                i1 += 1
+                i2 += 1
+        yield [base1 + s1, base1 + i1, base2 + s2, base2 + i2], btype
+        s1 = i1
+        s2 = i2
+
+def allblocks(text1, text2, opts=None, lines1=None, lines2=None, refine=False):
+    """Return (block, type) tuples, where block is an mdiff.blocks
+    line entry. type is '=' for blocks matching exactly one another
+    (bdiff blocks), '!' for non-matching blocks and '~' for blocks
+    matching only after having filtered blank lines. If refine is True,
+    then '~' blocks are refined and are only made of blank lines.
+    line1 and line2 are text1 and text2 split with splitnewlines() if
+    they are already available.
+    """
+    if opts is None:
+        opts = defaultopts
+    if opts.ignorews or opts.ignorewsamount:
+        text1 = wsclean(opts, text1, False)
+        text2 = wsclean(opts, text2, False)
+    diff = bdiff.blocks(text1, text2)
+    for i, s1 in enumerate(diff):
+        # The first match is special.
+        # we've either found a match starting at line 0 or a match later
+        # in the file.  If it starts later, old and new below will both be
+        # empty and we'll continue to the next match.
+        if i > 0:
+            s = diff[i - 1]
+        else:
+            s = [0, 0, 0, 0]
+        s = [s[1], s1[0], s[3], s1[2]]
+
+        # bdiff sometimes gives huge matches past eof, this check eats them,
+        # and deals with the special first match case described above
+        if s[0] != s[1] or s[2] != s[3]:
+            type = '!'
+            if opts.ignoreblanklines:
+                if lines1 is None:
+                    lines1 = splitnewlines(text1)
+                if lines2 is None:
+                    lines2 = splitnewlines(text2)
+                old = wsclean(opts, "".join(lines1[s[0]:s[1]]))
+                new = wsclean(opts, "".join(lines2[s[2]:s[3]]))
+                if old == new:
+                    type = '~'
+            yield s, type
+        yield s1, '='
+
 def diffline(revs, a, b, opts):
     parts = ['diff']
     if opts.git:
@@ -100,6 +167,9 @@
         return ""
     epoch = util.datestr((0, 0))
 
+    fn1 = util.pconvert(fn1)
+    fn2 = util.pconvert(fn2)
+
     if not opts.text and (util.binary(a) or util.binary(b)):
         if a and b and len(a) == len(b) and a == b:
             return ""
@@ -197,39 +267,15 @@
     # below finds the spaces between those matching sequences and translates
     # them into diff output.
     #
-    if opts.ignorews or opts.ignorewsamount:
-        t1 = wsclean(opts, t1, False)
-        t2 = wsclean(opts, t2, False)
-
-    diff = bdiff.blocks(t1, t2)
     hunk = None
-    for i, s1 in enumerate(diff):
-        # The first match is special.
-        # we've either found a match starting at line 0 or a match later
-        # in the file.  If it starts later, old and new below will both be
-        # empty and we'll continue to the next match.
-        if i > 0:
-            s = diff[i - 1]
-        else:
-            s = [0, 0, 0, 0]
+    for s, stype in allblocks(t1, t2, opts, l1, l2):
+        if stype != '!':
+            continue
         delta = []
-        a1 = s[1]
-        a2 = s1[0]
-        b1 = s[3]
-        b2 = s1[2]
-
+        a1, a2, b1, b2 = s
         old = l1[a1:a2]
         new = l2[b1:b2]
 
-        # bdiff sometimes gives huge matches past eof, this check eats them,
-        # and deals with the special first match case described above
-        if not old and not new:
-            continue
-
-        if opts.ignoreblanklines:
-            if wsclean(opts, "".join(old)) == wsclean(opts, "".join(new)):
-                continue
-
         astart = contextstart(a1)
         bstart = contextstart(b1)
         prev = None
--- a/mercurial/patch.py	Tue Nov 22 17:51:43 2011 +0100
+++ b/mercurial/patch.py	Tue Nov 22 18:16:59 2011 +0100
@@ -566,8 +566,8 @@
         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+))? (---|\*\*\*)')
+unidesc = re.compile('@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@')
+contextdesc = re.compile('(?:---|\*\*\*) (\d+)(?:,(\d+))? (?:---|\*\*\*)')
 eolmodes = ['strict', 'crlf', 'lf', 'auto']
 
 class patchfile(object):
@@ -830,7 +830,7 @@
         m = unidesc.match(self.desc)
         if not m:
             raise PatchError(_("bad hunk #%d") % self.number)
-        self.starta, foo, self.lena, self.startb, foo2, self.lenb = m.groups()
+        self.starta, self.lena, self.startb, self.lenb = m.groups()
         if self.lena is None:
             self.lena = 1
         else:
@@ -857,7 +857,7 @@
         m = contextdesc.match(self.desc)
         if not m:
             raise PatchError(_("bad hunk #%d") % self.number)
-        foo, self.starta, foo2, aend, foo3 = m.groups()
+        self.starta, aend = m.groups()
         self.starta = int(self.starta)
         if aend is None:
             aend = self.starta
@@ -890,7 +890,7 @@
         m = contextdesc.match(l)
         if not m:
             raise PatchError(_("bad hunk #%d") % self.number)
-        foo, self.startb, foo2, bend, foo3 = m.groups()
+        self.startb, bend = m.groups()
         self.startb = int(self.startb)
         if bend is None:
             bend = self.startb
@@ -1527,10 +1527,10 @@
 class GitDiffRequired(Exception):
     pass
 
-def diffopts(ui, opts=None, untrusted=False):
+def diffopts(ui, opts=None, untrusted=False, section='diff'):
     def get(key, name=None, getter=ui.configbool):
         return ((opts and opts.get(key)) or
-                getter('diff', name or key, None, untrusted=untrusted))
+                getter(section, name or key, None, untrusted=untrusted))
     return mdiff.diffopts(
         text=opts and opts.get('text'),
         git=get('git'),
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mercurial/phases.py	Tue Nov 22 18:16:59 2011 +0100
@@ -0,0 +1,102 @@
+# Mercurial phases support code
+#
+# Copyright 2011 Pierre-Yves David <pierre-yves.david@ens-lyon.org>
+#                Logilab SA        <contact@logilab.fr>
+#                Augie Fackler     <durin42@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 errno
+from node import nullid, bin, hex, short
+from i18n import _
+
+allphases = range(2)
+trackedphases = allphases[1:]
+
+def readroots(repo):
+    """Read phase roots from disk"""
+    roots = [set() for i in allphases]
+    roots[0].add(nullid)
+    try:
+        f = repo.sopener('phaseroots')
+        try:
+            for line in f:
+                phase, nh = line.strip().split()
+                roots[int(phase)].add(bin(nh))
+        finally:
+            f.close()
+    except IOError, inst:
+        if inst.errno != errno.ENOENT:
+            raise
+    return roots
+
+def writeroots(repo):
+    """Write phase roots from disk"""
+    f = repo.sopener('phaseroots', 'w', atomictemp=True)
+    try:
+        for phase, roots in enumerate(repo._phaseroots):
+            for h in roots:
+                f.write('%i %s\n' % (phase, hex(h)))
+        repo._dirtyphases = False
+    finally:
+        f.close()
+
+def filterunknown(repo, phaseroots=None):
+    """remove unknown nodes from the phase boundary
+
+    no data is lost as unknown node only old data for their descentants
+    """
+    if phaseroots is None:
+        phaseroots = repo._phaseroots
+    for phase, nodes in enumerate(phaseroots):
+        missing = [node for node in nodes if node not in repo]
+        if missing:
+            for mnode in missing:
+                msg = _('Removing unknown node %(n)s from %(p)i-phase boundary')
+                repo.ui.debug(msg, {'n': short(mnode), 'p': phase})
+            nodes.symmetric_difference_update(missing)
+            repo._dirtyphases = True
+
+def advanceboundary(repo, targetphase, nodes):
+    """Add nodes to a phase changing other nodes phases if necessary.
+
+    This function move boundary *forward* this means that all nodes are set
+    in the target phase or kept in a *lower* phase.
+
+    Simplify boundary to contains phase roots only."""
+    for phase in xrange(targetphase + 1, len(allphases)):
+        # filter nodes that are not in a compatible phase already
+        # XXX rev phase cache might have been invalidated by a previous loop
+        # XXX we need to be smarter here
+        nodes = [n for n in nodes if repo[n].phase() >= phase]
+        if not nodes:
+            break # no roots to move anymore
+        roots = repo._phaseroots[phase]
+        olds = roots.copy()
+        ctxs = list(repo.set('roots((%ln::) - (%ln::%ln))', olds, olds, nodes))
+        roots.clear()
+        roots.update(ctx.node() for ctx in ctxs)
+        if olds != roots:
+            # invalidate cache (we probably could be smarter here
+            if '_phaserev' in vars(repo):
+                del repo._phaserev
+            repo._dirtyphases = True
+
+def retractboundary(repo, targetphase, nodes):
+    """Set nodes back to a phase changing other nodes phases if necessary.
+
+    This function move boundary *backward* this means that all nodes are set
+    in the target phase or kept in a *higher* phase.
+
+    Simplify boundary to contains phase roots only."""
+    currentroots = repo._phaseroots[targetphase]
+    newroots = [n for n in nodes if repo[n].phase() < targetphase]
+    if newroots:
+        currentroots.update(newroots)
+        ctxs = repo.set('roots(%ln::)', currentroots)
+        currentroots.intersection_update(ctx.node() for ctx in ctxs)
+        if '_phaserev' in vars(repo):
+            del repo._phaserev
+        repo._dirtyphases = True
+
--- a/mercurial/pure/bdiff.py	Tue Nov 22 17:51:43 2011 +0100
+++ b/mercurial/pure/bdiff.py	Tue Nov 22 18:16:59 2011 +0100
@@ -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.
 
-import struct, difflib
+import struct, difflib, re
 
 def splitnewlines(text):
     '''like str.splitlines, but only split on newlines.'''
@@ -78,3 +78,10 @@
     d = _normalizeblocks(an, bn, d)
     return [(i, i + n, j, j + n) for (i, j, n) in d]
 
+def fixws(text, allws):
+    if allws:
+        text = re.sub('[ \t\r]+', '', text)
+    else:
+        text = re.sub('[ \t\r]+', ' ', text)
+        text = text.replace(' \n', '\n')
+    return text
--- a/mercurial/repair.py	Tue Nov 22 17:51:43 2011 +0100
+++ b/mercurial/repair.py	Tue Nov 22 18:16:59 2011 +0100
@@ -6,7 +6,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 import changegroup, bookmarks
+from mercurial import changegroup, bookmarks, phases
 from mercurial.node import short
 from mercurial.i18n import _
 import os
@@ -145,7 +145,9 @@
         for m in updatebm:
             bm[m] = repo['.'].node()
         bookmarks.write(repo)
-
+        # remove potential unknown phase
+        # XXX using to_strip data would be faster
+        phases.filterunknown(repo)
     except:
         if backupfile:
             ui.warn(_("strip failed, full bundle stored in '%s'\n")
--- a/mercurial/scmutil.py	Tue Nov 22 17:51:43 2011 +0100
+++ b/mercurial/scmutil.py	Tue Nov 22 18:16:59 2011 +0100
@@ -98,7 +98,7 @@
                 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')
+                    raise util.Abort(_("path '%s' is inside nested repo %r")
                                      % (path, base))
 
         parts.pop()
@@ -123,7 +123,7 @@
                 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') %
+                        raise util.Abort(_("path '%s' is inside nested repo %r") %
                                          (path, prefix))
             prefixes.append(prefix)
             parts.pop()
--- a/mercurial/subrepo.py	Tue Nov 22 17:51:43 2011 +0100
+++ b/mercurial/subrepo.py	Tue Nov 22 18:16:59 2011 +0100
@@ -353,6 +353,15 @@
                         unit=_('files'), total=total)
         ui.progress(_('archiving (%s)') % relpath, None)
 
+    def walk(self, match):
+        '''
+        walk recursively through the directory tree, finding all files
+        matched by the match function
+        '''
+        pass
+
+    def forget(self, files):
+        pass
 
 class hgsubrepo(abstractsubrepo):
     def __init__(self, ctx, path, state):
@@ -543,6 +552,13 @@
         ctx = self._repo[rev]
         return ctx.flags(name)
 
+    def walk(self, match):
+        ctx = self._repo[None]
+        return ctx.walk(match)
+
+    def forget(self, files):
+        ctx = self._repo[None]
+        ctx.forget(files)
 
 class svnsubrepo(abstractsubrepo):
     def __init__(self, ctx, path, state):
--- a/mercurial/templatekw.py	Tue Nov 22 17:51:43 2011 +0100
+++ b/mercurial/templatekw.py	Tue Nov 22 18:16:59 2011 +0100
@@ -275,6 +275,10 @@
     """
     return ctx.hex()
 
+def showphase(repo, ctx, templ, **args):
+    """:rev: Integer. The changeset phase."""
+    return ctx.phase()
+
 def showrev(repo, ctx, templ, **args):
     """:rev: Integer. The repository-local changeset revision number."""
     return ctx.rev()
@@ -312,6 +316,7 @@
     'latesttagdistance': showlatesttagdistance,
     'manifest': showmanifest,
     'node': shownode,
+    'phase': showphase,
     'rev': showrev,
     'tags': showtags,
 }
--- a/mercurial/util.py	Tue Nov 22 17:51:43 2011 +0100
+++ b/mercurial/util.py	Tue Nov 22 18:16:59 2011 +0100
@@ -1495,7 +1495,7 @@
     """
 
     _safechars = "!~*'()+"
-    _safepchars = "/!~*'()+"
+    _safepchars = "/!~*'()+:"
     _matchscheme = re.compile(r'^[a-zA-Z0-9+.\-]+:').match
 
     def __init__(self, path, parsequery=True, parsefragment=True):
@@ -1607,8 +1607,8 @@
 
         Examples:
 
-        >>> str(url('http://user:pw@host:80/?foo#bar'))
-        'http://user:pw@host:80/?foo#bar'
+        >>> str(url('http://user:pw@host:80/c:/bob?fo:oo#ba:ar'))
+        'http://user:pw@host:80/c:/bob?fo:oo#ba:ar'
         >>> str(url('http://user:pw@host:80/?foo=bar&baz=42'))
         'http://user:pw@host:80/?foo=bar&baz=42'
         >>> str(url('http://user:pw@host:80/?foo=bar%3dbaz'))
--- a/mercurial/windows.py	Tue Nov 22 17:51:43 2011 +0100
+++ b/mercurial/windows.py	Tue Nov 22 18:16:59 2011 +0100
@@ -26,7 +26,7 @@
 unlink = win32.unlink
 
 nulldev = 'NUL:'
-umask = 002
+umask = 0022
 
 # wrap osutil.posixfile to provide friendlier exceptions
 def posixfile(name, mode='r', buffering=-1):
--- a/setup.py	Tue Nov 22 17:51:43 2011 +0100
+++ b/setup.py	Tue Nov 22 18:16:59 2011 +0100
@@ -44,7 +44,7 @@
     pass
 
 if isironpython:
-    print "warning: IronPython detected (no bz2 support)"
+    sys.stderr.write("warning: IronPython detected (no bz2 support)\n")
 else:
     try:
         import bz2
@@ -68,6 +68,19 @@
 from distutils.sysconfig import get_python_inc
 from distutils.version import StrictVersion
 
+convert2to3 = '--c2to3' in sys.argv
+if convert2to3:
+    try:
+        from distutils.command.build_py import build_py_2to3 as build_py
+        from lib2to3.refactor import get_fixers_from_package as getfixers
+    except ImportError:
+        if sys.version_info[0] < 3:
+            raise SystemExit("--c2to3 is only compatible with python3.")
+        raise
+    sys.path.append('contrib')
+elif sys.version_info[0] >= 3:
+    raise SystemExit("setup.py with python3 needs --c2to3 (experimental)")
+
 scripts = ['hg']
 if os.name == 'nt':
     scripts.append('contrib/win32/hg.bat')
@@ -108,6 +121,8 @@
 try:
     import py2exe
     py2exeloaded = True
+    # import py2exe's patched Distribution class
+    from distutils.core import Distribution
 except ImportError:
     py2exeloaded = False
 
@@ -186,6 +201,17 @@
 except ImportError:
     version = 'unknown'
 
+class hgbuild(build):
+    # Insert hgbuildmo first so that files in mercurial/locale/ are found
+    # when build_py is run next.
+    sub_commands = [('build_mo', None),
+    # We also need build_ext before build_py. Otherwise, when 2to3 is called (in
+    # build_py), it will not find osutil & friends, thinking that those modules are
+    # global and, consequently, making a mess, now that all module imports are
+    # global.
+                    ('build_ext', build.has_ext_modules),
+                   ] + build.sub_commands
+
 class hgbuildmo(build):
 
     description = "build translations (.mo files)"
@@ -217,13 +243,20 @@
             self.make_file([pofile], mobuildfile, spawn, (cmd,))
 
 
-# Insert hgbuildmo first so that files in mercurial/locale/ are found
-# when build_py is run next.
-build.sub_commands.insert(0, ('build_mo', None))
+class hgdist(Distribution):
+    pure = 0
 
-Distribution.pure = 0
-Distribution.global_options.append(('pure', None, "use pure (slow) Python "
-                                    "code instead of C extensions"))
+    global_options = Distribution.global_options + \
+                     [('pure', None, "use pure (slow) Python "
+                        "code instead of C extensions"),
+                      ('c2to3', None, "(experimental!) convert "
+                        "code with 2to3"),
+                     ]
+
+    def has_ext_modules(self):
+        # self.ext_modules is emptied in hgbuildpy.finalize_options which is
+        # too late for some cases
+        return not self.pure and Distribution.has_ext_modules(self)
 
 class hgbuildext(build_ext):
 
@@ -237,6 +270,9 @@
                      ext.name)
 
 class hgbuildpy(build_py):
+    if convert2to3:
+        fixer_names = sorted(set(getfixers("lib2to3.fixes") +
+                                 getfixers("hgfixes")))
 
     def finalize_options(self):
         build_py.finalize_options(self)
@@ -327,7 +363,7 @@
             fp.close()
 
             # skip binary files
-            if '\0' in data:
+            if b('\0') in data:
                 continue
 
             data = data.replace('@LIBDIR@', libdir.encode('string_escape'))
@@ -335,7 +371,8 @@
             fp.write(data)
             fp.close()
 
-cmdclass = {'build_mo': hgbuildmo,
+cmdclass = {'build': hgbuild,
+            'build_mo': hgbuildmo,
             'build_ext': hgbuildext,
             'build_py': hgbuildpy,
             'build_hgextindex': buildhgextindex,
@@ -435,6 +472,7 @@
       data_files=datafiles,
       package_data=packagedata,
       cmdclass=cmdclass,
+      distclass=hgdist,
       options=dict(py2exe=dict(packages=['hgext', 'email']),
                    bdist_mpkg=dict(zipdist=True,
                                    license='COPYING',
--- a/tests/heredoctest.py	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/heredoctest.py	Tue Nov 22 18:16:59 2011 +0100
@@ -1,16 +1,19 @@
-import doctest, tempfile, os, sys
-
-if __name__ == "__main__":
-    if 'TERM' in os.environ:
-        del os.environ['TERM']
-
-    fd, name = tempfile.mkstemp(suffix='hg-tst')
+import sys
 
-    try:
-        os.write(fd, sys.stdin.read())
-        os.close(fd)
-        failures, _ = doctest.testfile(name, module_relative=False)
-        if failures:
-            sys.exit(1)
-    finally:
-        os.remove(name)
+globalvars = {}
+localvars = {}
+lines = sys.stdin.readlines()
+while lines:
+    l = lines.pop(0)
+    if l.startswith('SALT'):
+        print l[:-1]
+    elif l.startswith('>>> '):
+        snippet = l[4:]
+        while lines and lines[0].startswith('... '):
+            l = lines.pop(0)
+            snippet += "\n" + l[4:]
+        c = compile(snippet, '<heredoc>', 'single')
+        try:
+            exec c in globalvars, localvars
+        except Exception, inst:
+            print repr(inst)
--- a/tests/hghave	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/hghave	Tue Nov 22 18:16:59 2011 +0100
@@ -161,7 +161,7 @@
     return matchoutput('p4 -V', r'Rev\. P4/') and matchoutput('p4d -V', r'Rev\. P4D/')
 
 def has_symlink():
-    return hasattr(os, "symlink")
+    return hasattr(os, "symlink") # FIXME: should also check file system and os
 
 def has_tla():
     return matchoutput('tla --version 2>&1', r'The GNU Arch Revision')
@@ -209,6 +209,18 @@
     except ImportError:
         return False
 
+def has_windows():
+    return os.name == 'nt'
+
+def has_system_sh():
+    return os.name != 'nt'
+
+def has_serve():
+    return os.name != 'nt' # gross approximation
+
+def has_tic():
+    return matchoutput('test -x "`which tic`"', '')
+
 checks = {
     "baz": (has_baz, "GNU Arch baz client"),
     "bzr": (has_bzr, "Canonical's Bazaar client"),
@@ -231,14 +243,18 @@
     "p4": (has_p4, "Perforce server and client"),
     "pyflakes": (has_pyflakes, "Pyflakes python linter"),
     "pygments": (has_pygments, "Pygments source highlighting library"),
+    "serve": (has_serve, "platform and python can manage 'hg serve -d'"),
     "ssl": (has_ssl, "python >= 2.6 ssl module and python OpenSSL"),
     "svn": (has_svn, "subversion client and admin tools"),
     "svn13": (has_svn13, "subversion client and admin tools >= 1.3"),
     "svn15": (has_svn15, "subversion client and admin tools >= 1.5"),
     "svn-bindings": (has_svn_bindings, "subversion python bindings"),
     "symlink": (has_symlink, "symbolic links"),
+    "system-sh": (has_system_sh, "system() uses sh"),
+    "tic": (has_tic, "terminfo compiler"),
     "tla": (has_tla, "GNU Arch tla client"),
     "unix-permissions": (has_unix_permissions, "unix-style permissions"),
+    "windows": (has_windows, "Windows"),
 }
 
 def list_features():
--- a/tests/run-tests.py	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/run-tests.py	Tue Nov 22 18:16:59 2011 +0100
@@ -87,7 +87,7 @@
 SKIPPED_STATUS = 80
 SKIPPED_PREFIX = 'skipped: '
 FAILED_PREFIX  = 'hghave check failed: '
-PYTHON = sys.executable
+PYTHON = sys.executable.replace('\\', '/')
 IMPL_PATH = 'PYTHONPATH'
 if 'java' in sys.platform:
     IMPL_PATH = 'JYTHONPATH'
@@ -508,7 +508,7 @@
     return run(cmd, wd, options, replacements)
 
 def shtest(test, wd, options, replacements):
-    cmd = '"%s"' % test
+    cmd = '%s "%s"' % (options.shell, test)
     vlog("# Running", cmd)
     return run(cmd, wd, options, replacements)
 
@@ -521,43 +521,103 @@
 def stringescape(s):
     return escapesub(escapef, s)
 
-def transformtst(lines):
-    inblock = False
-    for l in lines:
-        if inblock:
-            if l.startswith('  $ ') or not l.startswith('  '):
-                inblock = False
-                yield '  > EOF\n'
-                yield l
-            else:
-                yield '  > ' + l[2:]
+def rematch(el, l):
+    try:
+        # ensure that the regex matches to the end of the string
+        return re.match(el + r'\Z', l)
+    except re.error:
+        # el is an invalid regex
+        return False
+
+def globmatch(el, l):
+    # The only supported special characters are * and ? plus / which also
+    # matches \ on windows. Escaping of these caracters is supported.
+    i, n = 0, len(el)
+    res = ''
+    while i < n:
+        c = el[i]
+        i += 1
+        if c == '\\' and el[i] in '*?\\/':
+            res += el[i - 1:i + 1]
+            i += 1
+        elif c == '*':
+            res += '.*'
+        elif c == '?':
+            res += '.'
+        elif c == '/' and os.name == 'nt':
+            res += '[/\\\\]'
         else:
-            if l.startswith('  >>> '):
-                inblock = True
-                yield '  $ %s -m heredoctest <<EOF\n' % PYTHON
-                yield '  > ' + l[2:]
-            else:
-                yield l
-    if inblock:
-        yield '  > EOF\n'
+            res += re.escape(c)
+    return rematch(res, l)
+
+def linematch(el, l):
+    if el == l: # perfect match (fast)
+        return True
+    if (el and
+        (el.endswith(" (re)\n") and rematch(el[:-6] + '\n', l) or
+         el.endswith(" (glob)\n") and globmatch(el[:-8] + '\n', l) or
+         el.endswith(" (esc)\n") and
+             (el[:-7].decode('string-escape') + '\n' == l or
+              el[:-7].decode('string-escape').replace('\r', '') +
+                  '\n' == l and os.name == 'nt'))):
+        return True
+    return False
 
 def tsttest(test, wd, options, replacements):
-    t = open(test)
-    out = []
-    script = []
+    # We generate a shell script which outputs unique markers to line
+    # up script results with our source. These markers include input
+    # line number and the last return code
     salt = "SALT" + str(time.time())
+    def addsalt(line, inpython):
+        if inpython:
+            script.append('%s %d 0\n' % (salt, line))
+        else:
+            script.append('echo %s %s $?\n' % (salt, line))
 
-    pos = prepos = -1
+    # After we run the shell script, we re-unify the script output
+    # with non-active parts of the source, with synchronization by our
+    # SALT line number markers. The after table contains the
+    # non-active components, ordered by line number
     after = {}
+    pos = prepos = -1
+
+    # Expected shellscript output
     expected = {}
-    for n, l in enumerate(transformtst(t)):
+
+    # We keep track of whether or not we're in a Python block so we
+    # can generate the surrounding doctest magic
+    inpython = False
+
+    f = open(test)
+    t = f.readlines()
+    f.close()
+
+    script = []
+    for n, l in enumerate(t):
         if not l.endswith('\n'):
             l += '\n'
-        if l.startswith('  $ '): # commands
+        if l.startswith('  >>> '): # python inlines
             after.setdefault(pos, []).append(l)
             prepos = pos
             pos = n
-            script.append('echo %s %s $?\n' % (salt, n))
+            if not inpython:
+                # we've just entered a Python block, add the header
+                inpython = True
+                addsalt(prepos, False) # make sure we report the exit code
+                script.append('%s -m heredoctest <<EOF\n' % PYTHON)
+            addsalt(n, True)
+            script.append(l[2:])
+        if l.startswith('  ... '): # python inlines
+            after.setdefault(prepos, []).append(l)
+            script.append(l[2:])
+        elif l.startswith('  $ '): # commands
+            if inpython:
+                script.append("EOF\n")
+                inpython = False
+            after.setdefault(pos, []).append(l)
+            prepos = pos
+            pos = n
+            addsalt(n, False)
             script.append(l[4:])
         elif l.startswith('  > '): # continuations
             after.setdefault(prepos, []).append(l)
@@ -566,21 +626,24 @@
             # queue up a list of expected results
             expected.setdefault(pos, []).append(l[2:])
         else:
+            if inpython:
+                script.append("EOF\n")
+                inpython = False
             # non-command/result - queue up for merged output
             after.setdefault(pos, []).append(l)
 
-    t.close()
+    if inpython:
+        script.append("EOF\n")
+    addsalt(n + 1, False)
 
-    script.append('echo %s %s $?\n' % (salt, n + 1))
-
+    # Write out the script and execute it
     fd, name = tempfile.mkstemp(suffix='hg-tst')
-
     try:
         for l in script:
             os.write(fd, l)
         os.close(fd)
 
-        cmd = '"%s" "%s"' % (options.shell, name)
+        cmd = '%s "%s"' % (options.shell, name)
         vlog("# Running", cmd)
         exitcode, output = run(cmd, wd, options, replacements)
         # do not merge output if skipped, return hghave message instead
@@ -590,32 +653,7 @@
     finally:
         os.remove(name)
 
-    def rematch(el, l):
-        try:
-            # ensure that the regex matches to the end of the string
-            return re.match(el + r'\Z', l)
-        except re.error:
-            # el is an invalid regex
-            return False
-
-    def globmatch(el, l):
-        # The only supported special characters are * and ?. Escaping is
-        # supported.
-        i, n = 0, len(el)
-        res = ''
-        while i < n:
-            c = el[i]
-            i += 1
-            if c == '\\' and el[i] in '*?\\':
-                res += el[i - 1:i + 1]
-                i += 1
-            elif c == '*':
-                res += '.*'
-            elif c == '?':
-                res += '.'
-            else:
-                res += re.escape(c)
-        return rematch(res, l)
+    # Merge the script output back into a unified test
 
     pos = -1
     postout = []
@@ -627,20 +665,16 @@
 
         if lout:
             if lcmd:
+                # output block had no trailing newline, clean up
                 lout += ' (no-eol)\n'
 
+            # find the expected output at the current position
             el = None
             if pos in expected and expected[pos]:
                 el = expected[pos].pop(0)
 
-            if el == lout: # perfect match (fast)
-                postout.append("  " + lout)
-            elif (el and
-                  (el.endswith(" (re)\n") and rematch(el[:-6] + '\n', lout) or
-                   el.endswith(" (glob)\n") and globmatch(el[:-8] + '\n', lout)
-                   or el.endswith(" (esc)\n") and
-                      el.decode('string-escape') == l)):
-                postout.append("  " + el) # fallback regex/glob/esc match
+            if linematch(el, lout):
+                postout.append("  " + el)
             else:
                 if needescape(lout):
                     lout = stringescape(lout.rstrip('\n')) + " (esc)\n"
@@ -652,6 +686,7 @@
             if ret != 0:
                 postout.append("  [%s]\n" % ret)
             if pos in after:
+                # merge in non-active test bits
                 postout += after.pop(pos)
             pos = int(lcmd.split()[0])
 
@@ -832,15 +867,26 @@
 
     # Make a tmp subdirectory to work in
     testtmp = os.environ["TESTTMP"] = os.environ["HOME"] = \
-        os.path.join(HGTMP, os.path.basename(test))
+        os.path.join(HGTMP, os.path.basename(test)).replace('\\', '/')
 
-    os.mkdir(testtmp)
-    ret, out = runner(testpath, testtmp, options, [
-        (re.escape(testtmp), '$TESTTMP'),
+    replacements = [
         (r':%s\b' % options.port, ':$HGPORT'),
         (r':%s\b' % (options.port + 1), ':$HGPORT1'),
         (r':%s\b' % (options.port + 2), ':$HGPORT2'),
-        ])
+        ]
+    if os.name == 'nt':
+        replacements.append((r'\r\n', '\n'))
+        replacements.append(
+            (''.join(c.isalpha() and '[%s%s]' % (c.lower(), c.upper()) or
+                     c in '/\\' and r'[/\\]' or
+                     c.isdigit() and c or
+                     '\\' + c
+                     for c in testtmp), '$TESTTMP'))
+    else:
+        replacements.append((re.escape(testtmp), '$TESTTMP'))
+
+    os.mkdir(testtmp)
+    ret, out = runner(testpath, testtmp, options, replacements)
     vlog("# Ret was:", ret)
 
     mark = '.'
@@ -853,7 +899,7 @@
         refout = None                   # to match "out is None"
     elif os.path.exists(ref):
         f = open(ref, "r")
-        refout = list(transformtst(splitnewlines(f.read())))
+        refout = list(splitnewlines(f.read()))
         f.close()
     else:
         refout = []
--- a/tests/test-acl.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-acl.t	Tue Nov 22 18:16:59 2011 +0100
@@ -868,10 +868,10 @@
   added 3 changesets with 3 changes to 3 files
   calling hook pretxnchangegroup.acl: hgext.acl.hook
   acl: checking access for user "barney"
-  error: pretxnchangegroup.acl hook raised an exception: [Errno 2] No such file or directory: '../acl.config'
+  error: pretxnchangegroup.acl hook raised an exception: [Errno 2] *: '../acl.config' (glob)
   transaction abort!
   rollback completed
-  abort: No such file or directory: ../acl.config
+  abort: *: ../acl.config (glob)
   no rollback information available
   0:6675d58eff77
   
--- a/tests/test-add.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-add.t	Tue Nov 22 18:16:59 2011 +0100
@@ -1,3 +1,5 @@
+  $ "$TESTDIR/hghave" no-windows || exit 80
+
   $ hg init a
   $ cd a
   $ echo a > a
@@ -86,7 +88,7 @@
   $ hg merge
   merging a
   warning: conflicts during merge.
-  merging a failed!
+  merging a incomplete! (edit conflicts, then use 'hg resolve --mark')
   0 files updated, 0 files merged, 0 files removed, 1 files unresolved
   use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
   [1]
@@ -121,11 +123,11 @@
   ? a.orig
 
   $ hg add c && echo "unexpected addition of missing file"
-  c: No such file or directory
+  c: * (glob)
   [1]
   $ echo c > c
   $ hg add d c && echo "unexpected addition of missing file"
-  d: No such file or directory
+  d: * (glob)
   [1]
   $ hg st
   M a
--- a/tests/test-addremove-similar.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-addremove-similar.t	Tue Nov 22 18:16:59 2011 +0100
@@ -81,7 +81,7 @@
   $ hg addremove -s80
   removing d/a
   adding d/b
-  recording removal of d/a as rename to d/b (100% similar)
+  recording removal of d/a as rename to d/b (100% similar) (glob)
   $ hg debugstate
   r   0          0 1970-01-01 00:00:00 d/a
   a   0         -1 unset               d/b
@@ -91,10 +91,10 @@
 no copies found here (since the target isn't in d
 
   $ hg addremove -s80 d
-  removing d/b
+  removing d/b (glob)
 
 copies here
 
   $ hg addremove -s80
   adding c
-  recording removal of d/a as rename to c (100% similar)
+  recording removal of d/a as rename to c (100% similar) (glob)
--- a/tests/test-addremove.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-addremove.t	Tue Nov 22 18:16:59 2011 +0100
@@ -1,3 +1,5 @@
+  $ "$TESTDIR/hghave" no-windows || exit 80
+
   $ hg init rep
   $ cd rep
   $ mkdir dir
--- a/tests/test-alias.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-alias.t	Tue Nov 22 18:16:59 2011 +0100
@@ -1,3 +1,5 @@
+  $ "$TESTDIR/hghave" system-sh || exit 80
+
   $ HGFOO=BAR; export HGFOO
   $ cat >> $HGRCPATH <<EOF
   > [extensions]
--- a/tests/test-annotate.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-annotate.t	Tue Nov 22 18:16:59 2011 +0100
@@ -2,7 +2,8 @@
 
 init
 
-  $ hg init
+  $ hg init repo
+  $ cd repo
 
 commit
 
@@ -253,3 +254,56 @@
   $ hg ann nosuchfile
   abort: nosuchfile: no such file in rev e9e6b4fa872f
   [255]
+
+Test annotate with whitespace options
+
+  $ cd ..
+  $ hg init repo-ws
+  $ cd repo-ws
+  $ cat > a <<EOF
+  > aa
+  > 
+  > b b
+  > EOF
+  $ hg ci -Am "adda"
+  adding a
+  $ cat > a <<EOF
+  > a  a
+  > 
+  >  
+  > b  b
+  > EOF
+  $ hg ci -m "changea"
+
+Annotate with no option
+
+  $ hg annotate a
+  1: a  a
+  0: 
+  1:  
+  1: b  b
+
+Annotate with --ignore-space-change
+
+  $ hg annotate --ignore-space-change a
+  1: a  a
+  1: 
+  0:  
+  0: b  b
+
+Annotate with --ignore-all-space
+
+  $ hg annotate --ignore-all-space a
+  0: a  a
+  0: 
+  1:  
+  0: b  b
+
+Annotate with --ignore-blank-lines (similar to no options case)
+
+  $ hg annotate --ignore-blank-lines a
+  1: a  a
+  0: 
+  1:  
+  1: b  b
+
--- a/tests/test-archive.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-archive.t	Tue Nov 22 18:16:59 2011 +0100
@@ -1,3 +1,5 @@
+  $ "$TESTDIR/hghave" serve || exit 80
+
   $ hg init test
   $ cd test
   $ echo foo>foo
--- a/tests/test-audit-path.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-audit-path.t	Tue Nov 22 18:16:59 2011 +0100
@@ -1,9 +1,11 @@
+  $ "$TESTDIR/hghave" symlink || exit 80
+
   $ hg init
 
 should fail
 
   $ hg add .hg/00changelog.i
-  abort: path contains illegal component: .hg/00changelog.i
+  abort: path contains illegal component: .hg/00changelog.i (glob)
   [255]
 
   $ mkdir a
@@ -16,7 +18,7 @@
 should fail
 
   $ hg add b/b
-  abort: path 'b/b' traverses symbolic link 'b'
+  abort: path 'b/b' traverses symbolic link 'b' (glob)
   [255]
 
 should succeed
@@ -26,7 +28,7 @@
 should still fail - maybe
 
   $ hg add b/b
-  abort: path 'b/b' traverses symbolic link 'b'
+  abort: path 'b/b' traverses symbolic link 'b' (glob)
   [255]
 
 unbundle tampered bundle
@@ -78,5 +80,5 @@
   $ hg manifest -r4
   /tmp/test
   $ hg update -Cr4
-  abort: No such file or directory: $TESTTMP/target//tmp/test
+  abort: *: $TESTTMP/target//tmp/test (glob)
   [255]
--- a/tests/test-backout.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-backout.t	Tue Nov 22 18:16:59 2011 +0100
@@ -48,8 +48,8 @@
   $ hg backout -d '3 0' --merge tip --tool=true
   removing a
   changeset 3:7f6d0f120113 backs out changeset 2:de31bdc76c0d
-  $ cat a 2>/dev/null || echo cat: a: No such file or directory
-  cat: a: No such file or directory
+  $ test -f a
+  [1]
 
 across branch
 
--- a/tests/test-bad-pull.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-bad-pull.t	Tue Nov 22 18:16:59 2011 +0100
@@ -1,9 +1,11 @@
+  $ "$TESTDIR/hghave" serve || exit 80
+
   $ hg clone http://localhost:$HGPORT/ copy
   abort: error: Connection refused
   [255]
 
-  $ test -d copy || echo copy: No such file or directory
-  copy: No such file or directory
+  $ test -d copy
+  [1]
 
   $ cat > dumb.py <<EOF
   > import BaseHTTPServer, SimpleHTTPServer, os, signal
--- a/tests/test-bdiff.py	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-bdiff.py	Tue Nov 22 18:16:59 2011 +0100
@@ -50,3 +50,17 @@
 showdiff("x\n\nx\n\nx\n\nx\n\nz\n", "x\n\nx\n\ny\n\nx\n\ny\n\nx\n\nz\n")
 
 print "done"
+
+def testfixws(a, b, allws):
+    c = bdiff.fixws(a, allws)
+    if c != b:
+        print "*** fixws", repr(a), repr(b), allws
+        print "got:"
+        print repr(c)
+
+testfixws(" \ta\r b\t\n", "ab\n", 1)
+testfixws(" \ta\r b\t\n", " a b\n", 0)
+testfixws("", "", 1)
+testfixws("", "", 0)
+
+print "done"
--- a/tests/test-bdiff.py.out	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-bdiff.py.out	Tue Nov 22 18:16:59 2011 +0100
@@ -21,3 +21,4 @@
 6 6 'y\n\n'
 9 9 'y\n\n'
 done
+done
--- a/tests/test-bisect.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-bisect.t	Tue Nov 22 18:16:59 2011 +0100
@@ -1,3 +1,5 @@
+  $ "$TESTDIR/hghave" system-sh || exit 80
+
   $ hg init
 
 
--- a/tests/test-bisect3.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-bisect3.t	Tue Nov 22 18:16:59 2011 +0100
@@ -14,15 +14,15 @@
   $ hg add a
   $ hg ci -u test -d '0 0' -m '0'
   $ echo '1' >a
-  $ hg ci -u test -d '0 1' -m '1'
+  $ hg ci -u test -d '1 0' -m '1'
 
 branch 2-3
 
   $ echo '2' >b
   $ hg add b
-  $ hg ci -u test -d '0 2' -m '2'
+  $ hg ci -u test -d '2 0' -m '2'
   $ echo '3' >b
-  $ hg ci -u test -d '0 3' -m '3'
+  $ hg ci -u test -d '3 0' -m '3'
 
 branch 4-8
 
@@ -30,30 +30,30 @@
   0 files updated, 0 files merged, 1 files removed, 0 files unresolved
   $ echo '4' >c
   $ hg add c
-  $ hg ci -u test -d '0 4' -m '4'
+  $ hg ci -u test -d '4 0' -m '4'
   created new head
   $ echo '5' >c
-  $ hg ci -u test -d '0 5' -m '5'
+  $ hg ci -u test -d '5 0' -m '5'
   $ echo '6' >c
-  $ hg ci -u test -d '0 6' -m '6'
+  $ hg ci -u test -d '6 0' -m '6'
   $ echo '7' >c
-  $ hg ci -u test -d '0 7' -m '7'
+  $ hg ci -u test -d '7 0' -m '7'
   $ echo '8' >c
-  $ hg ci -u test -d '0 8' -m '8'
+  $ hg ci -u test -d '8 0' -m '8'
 
 merge
 
   $ hg merge -r 3
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
   (branch merge, don't forget to commit)
-  $ hg ci -u test -d '0 9' -m '9=8+3'
+  $ hg ci -u test -d '9 0' -m '9=8+3'
 
   $ echo '10' >a
-  $ hg ci -u test -d '0 10' -m '10'
+  $ hg ci -u test -d '10 0' -m '10'
   $ echo '11' >a
-  $ hg ci -u test -d '0 11' -m '11'
+  $ hg ci -u test -d '11 0' -m '11'
   $ echo '12' >a
-  $ hg ci -u test -d '0 12' -m '12'
+  $ hg ci -u test -d '12 0' -m '12'
 
 unrelated branch
 
@@ -61,10 +61,10 @@
   1 files updated, 0 files merged, 1 files removed, 0 files unresolved
   $ echo '13' >d
   $ hg add d
-  $ hg ci -u test -d '0 13' -m '13'
+  $ hg ci -u test -d '13 0' -m '13'
   created new head
   $ echo '14' >d
-  $ hg ci -u test -d '0 14' -m '14'
+  $ hg ci -u test -d '14 0' -m '14'
 
 mark changesets
 
@@ -72,140 +72,140 @@
   $ hg bisect --good 4
   $ hg bisect --good 6
   $ hg bisect --bad 12
-  Testing changeset 9:8bcbdb072033 (6 changesets remaining, ~2 tests)
+  Testing changeset 9:2197c557e14c (6 changesets remaining, ~2 tests)
   1 files updated, 0 files merged, 1 files removed, 0 files unresolved
   $ hg bisect --bad 10
-  Testing changeset 8:3cd112f87d77 (4 changesets remaining, ~2 tests)
+  Testing changeset 8:e74a86251f58 (4 changesets remaining, ~2 tests)
   0 files updated, 0 files merged, 1 files removed, 0 files unresolved
   $ hg bisect --skip 7
-  Testing changeset 8:3cd112f87d77 (4 changesets remaining, ~2 tests)
+  Testing changeset 8:e74a86251f58 (4 changesets remaining, ~2 tests)
   0 files updated, 0 files merged, 0 files removed, 0 files unresolved
 
 test template
 
   $ hg log --template '{rev}:{node|short} {bisect}\n'
-  14:cecd84203acc 
-  13:86f7c8cdb6df 
-  12:a76089b5f47c bad
-  11:5c3eb122d29c bad (implicit)
-  10:b097cef2be03 bad
-  9:8bcbdb072033 untested
-  8:3cd112f87d77 untested
-  7:577e237a73bd skipped
-  6:e597fa2707c5 good
-  5:b9cea37a76bc good (implicit)
-  4:da6b357259d7 good
-  3:e7f031aee8ca ignored
-  2:b1ad1b6bcc5c ignored
-  1:37f42ae8b45e good (implicit)
+  14:cbf2f3105bbf 
+  13:e07efca37c43 
+  12:98c6b56349c0 bad
+  11:03f491376e63 bad (implicit)
+  10:c012b15e2409 bad
+  9:2197c557e14c untested
+  8:e74a86251f58 untested
+  7:a5f87041c899 skipped
+  6:7d997bedcd8d good
+  5:2dd1875f1028 good (implicit)
+  4:2a1daef14cd4 good
+  3:8417d459b90c ignored
+  2:e1355ee1f23e ignored
+  1:ce7c85e06a9f good (implicit)
   0:b4e73ffab476 good (implicit)
   $ hg log --template '{bisect|shortbisect} {rev}:{node|short}\n'
-    14:cecd84203acc
-    13:86f7c8cdb6df
-  B 12:a76089b5f47c
-  B 11:5c3eb122d29c
-  B 10:b097cef2be03
-  U 9:8bcbdb072033
-  U 8:3cd112f87d77
-  S 7:577e237a73bd
-  G 6:e597fa2707c5
-  G 5:b9cea37a76bc
-  G 4:da6b357259d7
-  I 3:e7f031aee8ca
-  I 2:b1ad1b6bcc5c
-  G 1:37f42ae8b45e
+    14:cbf2f3105bbf
+    13:e07efca37c43
+  B 12:98c6b56349c0
+  B 11:03f491376e63
+  B 10:c012b15e2409
+  U 9:2197c557e14c
+  U 8:e74a86251f58
+  S 7:a5f87041c899
+  G 6:7d997bedcd8d
+  G 5:2dd1875f1028
+  G 4:2a1daef14cd4
+  I 3:8417d459b90c
+  I 2:e1355ee1f23e
+  G 1:ce7c85e06a9f
   G 0:b4e73ffab476
 
 test style
 
   $ hg log --style bisect
-  changeset:   14:cecd84203acc
+  changeset:   14:cbf2f3105bbf
   bisect:      
   tag:         tip
   user:        test
-  date:        Wed Dec 31 23:59:46 1969 -0000
+  date:        Thu Jan 01 00:00:14 1970 +0000
   summary:     14
   
-  changeset:   13:86f7c8cdb6df
+  changeset:   13:e07efca37c43
   bisect:      
-  parent:      3:e7f031aee8ca
+  parent:      3:8417d459b90c
   user:        test
-  date:        Wed Dec 31 23:59:47 1969 -0000
+  date:        Thu Jan 01 00:00:13 1970 +0000
   summary:     13
   
-  changeset:   12:a76089b5f47c
+  changeset:   12:98c6b56349c0
   bisect:      bad
   user:        test
-  date:        Wed Dec 31 23:59:48 1969 -0000
+  date:        Thu Jan 01 00:00:12 1970 +0000
   summary:     12
   
-  changeset:   11:5c3eb122d29c
+  changeset:   11:03f491376e63
   bisect:      bad (implicit)
   user:        test
-  date:        Wed Dec 31 23:59:49 1969 -0000
+  date:        Thu Jan 01 00:00:11 1970 +0000
   summary:     11
   
-  changeset:   10:b097cef2be03
+  changeset:   10:c012b15e2409
   bisect:      bad
   user:        test
-  date:        Wed Dec 31 23:59:50 1969 -0000
+  date:        Thu Jan 01 00:00:10 1970 +0000
   summary:     10
   
-  changeset:   9:8bcbdb072033
+  changeset:   9:2197c557e14c
   bisect:      untested
-  parent:      8:3cd112f87d77
-  parent:      3:e7f031aee8ca
+  parent:      8:e74a86251f58
+  parent:      3:8417d459b90c
   user:        test
-  date:        Wed Dec 31 23:59:51 1969 -0000
+  date:        Thu Jan 01 00:00:09 1970 +0000
   summary:     9=8+3
   
-  changeset:   8:3cd112f87d77
+  changeset:   8:e74a86251f58
   bisect:      untested
   user:        test
-  date:        Wed Dec 31 23:59:52 1969 -0000
+  date:        Thu Jan 01 00:00:08 1970 +0000
   summary:     8
   
-  changeset:   7:577e237a73bd
+  changeset:   7:a5f87041c899
   bisect:      skipped
   user:        test
-  date:        Wed Dec 31 23:59:53 1969 -0000
+  date:        Thu Jan 01 00:00:07 1970 +0000
   summary:     7
   
-  changeset:   6:e597fa2707c5
+  changeset:   6:7d997bedcd8d
   bisect:      good
   user:        test
-  date:        Wed Dec 31 23:59:54 1969 -0000
+  date:        Thu Jan 01 00:00:06 1970 +0000
   summary:     6
   
-  changeset:   5:b9cea37a76bc
+  changeset:   5:2dd1875f1028
   bisect:      good (implicit)
   user:        test
-  date:        Wed Dec 31 23:59:55 1969 -0000
+  date:        Thu Jan 01 00:00:05 1970 +0000
   summary:     5
   
-  changeset:   4:da6b357259d7
+  changeset:   4:2a1daef14cd4
   bisect:      good
-  parent:      1:37f42ae8b45e
+  parent:      1:ce7c85e06a9f
   user:        test
-  date:        Wed Dec 31 23:59:56 1969 -0000
+  date:        Thu Jan 01 00:00:04 1970 +0000
   summary:     4
   
-  changeset:   3:e7f031aee8ca
+  changeset:   3:8417d459b90c
   bisect:      ignored
   user:        test
-  date:        Wed Dec 31 23:59:57 1969 -0000
+  date:        Thu Jan 01 00:00:03 1970 +0000
   summary:     3
   
-  changeset:   2:b1ad1b6bcc5c
+  changeset:   2:e1355ee1f23e
   bisect:      ignored
   user:        test
-  date:        Wed Dec 31 23:59:58 1969 -0000
+  date:        Thu Jan 01 00:00:02 1970 +0000
   summary:     2
   
-  changeset:   1:37f42ae8b45e
+  changeset:   1:ce7c85e06a9f
   bisect:      good (implicit)
   user:        test
-  date:        Wed Dec 31 23:59:59 1969 -0000
+  date:        Thu Jan 01 00:00:01 1970 +0000
   summary:     1
   
   changeset:   0:b4e73ffab476
@@ -215,18 +215,18 @@
   summary:     0
   
   $ hg log --quiet --style bisect
-    14:cecd84203acc
-    13:86f7c8cdb6df
-  B 12:a76089b5f47c
-  B 11:5c3eb122d29c
-  B 10:b097cef2be03
-  U 9:8bcbdb072033
-  U 8:3cd112f87d77
-  S 7:577e237a73bd
-  G 6:e597fa2707c5
-  G 5:b9cea37a76bc
-  G 4:da6b357259d7
-  I 3:e7f031aee8ca
-  I 2:b1ad1b6bcc5c
-  G 1:37f42ae8b45e
+    14:cbf2f3105bbf
+    13:e07efca37c43
+  B 12:98c6b56349c0
+  B 11:03f491376e63
+  B 10:c012b15e2409
+  U 9:2197c557e14c
+  U 8:e74a86251f58
+  S 7:a5f87041c899
+  G 6:7d997bedcd8d
+  G 5:2dd1875f1028
+  G 4:2a1daef14cd4
+  I 3:8417d459b90c
+  I 2:e1355ee1f23e
+  G 1:ce7c85e06a9f
   G 0:b4e73ffab476
--- a/tests/test-bookmarks-pushpull.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-bookmarks-pushpull.t	Tue Nov 22 18:16:59 2011 +0100
@@ -1,3 +1,5 @@
+  $ "$TESTDIR/hghave" serve || exit 80
+
 initialize
 
   $ hg init a
--- a/tests/test-bundle.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-bundle.t	Tue Nov 22 18:16:59 2011 +0100
@@ -1,3 +1,5 @@
+  $ "$TESTDIR/hghave" system-sh || exit 80
+
 Setting up test
 
   $ hg init test
@@ -375,7 +377,7 @@
 Outgoing -R does-not-exist.hg vs partial2 in partial
 
   $ hg -R bundle://../does-not-exist.hg outgoing ../partial2
-  abort: No such file or directory: ../does-not-exist.hg
+  abort: *: ../does-not-exist.hg (glob)
   [255]
   $ cd ..
 
@@ -408,7 +410,7 @@
 recurse infinitely (issue 2528)
 
   $ hg clone full.hg ''
-  abort: No such file or directory
+  abort: * (glob)
   [255]
 
 test for http://mercurial.selenic.com/bts/issue216
--- a/tests/test-check-code.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-check-code.t	Tue Nov 22 18:16:59 2011 +0100
@@ -132,3 +132,11 @@
    object comparison with literal
   [1]
 
+  $ cat > warning.py <<EOF
+  > except:
+  > EOF
+  $ "$check_code" warning.py --warning --nolineno
+  warning.py:0:
+   > except:
+   warning: naked except clause
+  [1]
--- a/tests/test-clone-failure.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-clone-failure.t	Tue Nov 22 18:16:59 2011 +0100
@@ -1,3 +1,5 @@
+  $ "$TESTDIR/hghave" unix-permissions || exit 80
+
 No local source
 
   $ hg clone a b
--- a/tests/test-clone-pull-corruption.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-clone-pull-corruption.t	Tue Nov 22 18:16:59 2011 +0100
@@ -1,3 +1,5 @@
+  $ "$TESTDIR/hghave" system-sh || exit 80
+
 Corrupt an hg repo with a pull started during an aborted commit
 Create two repos, so that one of them can pull from the other one.
 
--- a/tests/test-clone.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-clone.t	Tue Nov 22 18:16:59 2011 +0100
@@ -10,7 +10,7 @@
 
 Create a non-inlined filelog:
 
-  $ python -c 'for x in range(10000): print x' >> data1
+  $ python -c 'file("data1", "wb").write("".join("%s\n" % x for x in range(10000)))'
   $ for j in 0 1 2 3 4 5 6 7 8 9; do
   >   cat data1 >> b
   >   hg commit -m test
@@ -43,7 +43,7 @@
 Invalid dest '' must abort:
 
   $ hg clone . ''
-  abort: No such file or directory
+  abort: * (glob)
   [255]
 
 No update, with debug option:
@@ -85,7 +85,7 @@
 
   $ hg clone -q -U --config 'paths.foobar=a#0' foobar f
   $ hg -R f showconfig paths.default
-  $TESTTMP/a#0
+  $TESTTMP/a#0 (glob)
 
 Use --pull:
 
@@ -107,7 +107,7 @@
 Invalid dest '' with --pull must abort (issue2528):
 
   $ hg clone --pull a ''
-  abort: No such file or directory
+  abort: * (glob)
   [255]
 
 Clone to '.':
--- a/tests/test-command-template.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-command-template.t	Tue Nov 22 18:16:59 2011 +0100
@@ -1,3 +1,5 @@
+  $ "$TESTDIR/hghave" unix-permissions || exit 80
+
   $ hg init a
   $ cd a
   $ echo a > a
--- a/tests/test-commandserver.py	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-commandserver.py	Tue Nov 22 18:16:59 2011 +0100
@@ -26,6 +26,7 @@
         return channel, server.stdout.read(length)
 
 def runcommand(server, args, output=sys.stdout, error=sys.stderr, input=None):
+    print ' runcommand', ' '.join(args)
     server.stdin.write('runcommand\n')
     writeblock(server, '\0'.join(args))
 
@@ -52,6 +53,9 @@
                 return
 
 def check(func, repopath=None):
+    print
+    print 'testing %s:' % func.__name__
+    print
     server = connect(repopath)
     try:
         return func(server)
@@ -124,7 +128,7 @@
     """ check that --cwd doesn't persist between requests """
     readchannel(server)
     os.mkdir('foo')
-    f = open('foo/bar', 'w')
+    f = open('foo/bar', 'wb')
     f.write('a')
     f.close()
     runcommand(server, ['--cwd', 'foo', 'st', 'bar'])
@@ -141,7 +145,7 @@
 
     # but not for this repo
     runcommand(server, ['init', 'foo'])
-    runcommand(server, ['-R', 'foo', 'showconfig'])
+    runcommand(server, ['-R', 'foo', 'showconfig', 'ui', 'defaults'])
     shutil.rmtree('foo')
 
 def hook(**args):
@@ -156,7 +160,10 @@
 
 def outsidechanges(server):
     readchannel(server)
-    os.system('echo a >> a && hg ci -Am2')
+    f = open('a', 'ab')
+    f.write('a\n')
+    f.close()
+    os.system('hg ci -Am2')
     runcommand(server, ['tip'])
 
 def bookmarks(server):
--- a/tests/test-commandserver.py.out	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-commandserver.py.out	Tue Nov 22 18:16:59 2011 +0100
@@ -1,6 +1,17 @@
+
+testing hellomessage:
+
 o, 'capabilities: getencoding runcommand\nencoding: ***'
+ runcommand id
 000000000000 tip
 abort: unknown command unknowncommand
+
+testing unknowncommand:
+
+
+testing checkruncommand:
+
+ runcommand 
 Mercurial Distributed SCM
 
 basic commands:
@@ -24,44 +35,85 @@
  update     update working directory (or switch revisions)
 
 use "hg help" for the full list of commands or "hg -v" for details
+ runcommand id --quiet
 000000000000
+ runcommand id
 000000000000 tip
+ runcommand id --config ui.quiet=True
 000000000000
+ runcommand id
 000000000000 tip
+
+testing inputeof:
+
 server exit code = 1
+
+testing serverinput:
+
+ runcommand import -
 applying patch from stdin
+ runcommand log
 changeset:   0:eff892de26ec
 tag:         tip
 user:        test
 date:        Thu Jan 01 00:00:00 1970 +0000
 summary:     1
 
+
+testing cwd:
+
+ runcommand --cwd foo st bar
 ? bar
+ runcommand st foo/bar
 ? foo/bar
+
+testing localhgrc:
+
+ runcommand showconfig
 bundle.mainreporoot=$TESTTMP
 defaults.backout=-d "0 0"
 defaults.commit=-d "0 0"
 defaults.tag=-d "0 0"
 ui.slash=True
 ui.foo=bar
-bundle.mainreporoot=$TESTTMP/foo
+ runcommand init foo
+ runcommand -R foo showconfig ui defaults
 defaults.backout=-d "0 0"
 defaults.commit=-d "0 0"
 defaults.tag=-d "0 0"
 ui.slash=True
+
+testing hookoutput:
+
+ runcommand --config hooks.pre-identify=python:test-commandserver.hook id
 hook talking
 now try to read something: 'some input'
 eff892de26ec tip
+
+testing outsidechanges:
+
+ runcommand tip
 changeset:   1:d3a0a68be6de
 tag:         tip
 user:        test
 date:        Thu Jan 01 00:00:00 1970 +0000
 summary:     2
 
+
+testing bookmarks:
+
+ runcommand bookmarks
 no bookmarks set
+ runcommand bookmarks
    bm1                       1:d3a0a68be6de
    bm2                       1:d3a0a68be6de
+ runcommand bookmarks
  * bm1                       1:d3a0a68be6de
    bm2                       1:d3a0a68be6de
 
+testing tagscache:
+
+ runcommand id -t -r 0
+
+ runcommand id -t -r 0
 foo
--- a/tests/test-commit-unresolved.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-commit-unresolved.t	Tue Nov 22 18:16:59 2011 +0100
@@ -29,7 +29,7 @@
   $ hg merge
   merging A
   warning: conflicts during merge.
-  merging A failed!
+  merging A incomplete! (edit conflicts, then use 'hg resolve --mark')
   1 files updated, 0 files merged, 0 files removed, 1 files unresolved
   use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
   [1]
--- a/tests/test-commit.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-commit.t	Tue Nov 22 18:16:59 2011 +0100
@@ -1,3 +1,5 @@
+  $ "$TESTDIR/hghave" symlink || exit 80
+
 commit date test
 
   $ hg init test
@@ -43,7 +45,7 @@
   $ mkdir dir
   $ echo boo > dir/file
   $ hg add
-  adding dir/file
+  adding dir/file (glob)
   $ hg -v commit -m commit-9 dir
   dir/file
   committed changeset 2:d2a76177cb42
@@ -71,7 +73,7 @@
   $ cd ..
 
   $ hg commit -m commit-14 does-not-exist
-  abort: does-not-exist: No such file or directory
+  abort: does-not-exist: * (glob)
   [255]
   $ ln -s foo baz
   $ hg commit -m commit-15 baz
@@ -113,8 +115,8 @@
   $ mkdir bar
   $ echo bar > bar/bar
   $ hg add
-  adding bar/bar
-  adding foo/foo
+  adding bar/bar (glob)
+  adding foo/foo (glob)
   $ hg ci -m commit-subdir-1 foo
   $ hg ci -m commit-subdir-2 bar
 
--- a/tests/test-conflict.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-conflict.t	Tue Nov 22 18:16:59 2011 +0100
@@ -13,7 +13,7 @@
   $ hg merge 1
   merging a
   warning: conflicts during merge.
-  merging a failed!
+  merging a incomplete! (edit conflicts, then use 'hg resolve --mark')
   0 files updated, 0 files merged, 0 files removed, 1 files unresolved
   use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
   [1]
--- a/tests/test-contrib.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-contrib.t	Tue Nov 22 18:16:59 2011 +0100
@@ -107,7 +107,7 @@
 Test shrink-revlog:
   $ cd repo-a
   $ hg --config extensions.shrink=$CONTRIBDIR/shrink-revlog.py shrink
-  shrinking $TESTTMP/repo-a/.hg/store/00manifest.i
+  shrinking $TESTTMP/repo-a/.hg/store/00manifest.i (glob)
   reading revs
   sorting revs
   writing revs
@@ -115,8 +115,8 @@
   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
+    $TESTTMP/repo-a/.hg/store/00manifest.i.old (glob)
+    $TESTTMP/repo-a/.hg/store/00manifest.d.old (glob)
   (You can delete those files when you are satisfied that your
   repository is still sane.  Running 'hg verify' is strongly recommended.)
   $ hg verify
--- a/tests/test-convert-authormap.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-convert-authormap.t	Tue Nov 22 18:16:59 2011 +0100
@@ -27,7 +27,7 @@
   sorting...
   converting...
   0 foo
-  Writing author map file $TESTTMP/new/.hg/authormap
+  Writing author map file $TESTTMP/new/.hg/authormap (glob)
   $ cat new/.hg/authormap
   user name=Long User Name
   $ hg -Rnew log
@@ -44,7 +44,7 @@
   $ hg init new
   $ mv authormap.txt new/.hg/authormap
   $ hg convert orig new
-  Ignoring bad line in author map file $TESTTMP/new/.hg/authormap: this line is ignored
+  Ignoring bad line in author map file $TESTTMP/new/.hg/authormap: this line is ignored (glob)
   scanning source...
   sorting...
   converting...
--- a/tests/test-convert-bzr.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-convert-bzr.t	Tue Nov 22 18:16:59 2011 +0100
@@ -1,3 +1,4 @@
+  $ "$TESTDIR/hghave" symlink execbit || exit 80
 
   $ . "$TESTDIR/bzr-definitions"
 
--- a/tests/test-convert-hg-source.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-convert-hg-source.t	Tue Nov 22 18:16:59 2011 +0100
@@ -1,3 +1,4 @@
+  $ "$TESTDIR/hghave" execbit || exit 80
 
   $ cat >> $HGRCPATH <<EOF
   > [extensions]
--- a/tests/test-convert-svn-sink.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-convert-svn-sink.t	Tue Nov 22 18:16:59 2011 +0100
@@ -1,5 +1,4 @@
-
-  $ "$TESTDIR/hghave" svn13 no-outer-repo || exit 80
+  $ "$TESTDIR/hghave" svn13 no-outer-repo symlink execbit || exit 80
 
   $ fixpath()
   > {
@@ -417,7 +416,7 @@
   $ hg --cwd b merge
   merging b
   warning: conflicts during merge.
-  merging b failed!
+  merging b incomplete! (edit conflicts, then use 'hg resolve --mark')
   2 files updated, 0 files merged, 0 files removed, 1 files unresolved
   use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
   [1]
--- a/tests/test-convert-tla.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-convert-tla.t	Tue Nov 22 18:16:59 2011 +0100
@@ -1,5 +1,5 @@
 
-  $ "$TESTDIR/hghave" tla || exit 80
+  $ "$TESTDIR/hghave" tla symlink || exit 80
   $ tla my-id "mercurial <mercurial@selenic.com>"
   $ echo "[extensions]" >> $HGRCPATH
   $ echo "convert=" >> $HGRCPATH
--- a/tests/test-convert.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-convert.t	Tue Nov 22 18:16:59 2011 +0100
@@ -1,3 +1,4 @@
+  $ "$TESTDIR/hghave" unix-permissions || exit 80
 
   $ cat >> $HGRCPATH <<EOF
   > [extensions]
--- a/tests/test-debugcomplete.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-debugcomplete.t	Tue Nov 22 18:16:59 2011 +0100
@@ -189,7 +189,7 @@
 Show all commands + options
   $ hg debugcommands
   add: include, exclude, subrepos, dry-run
-  annotate: rev, follow, no-follow, text, user, file, date, number, changeset, line-number, include, exclude
+  annotate: rev, follow, no-follow, text, user, file, date, number, changeset, line-number, ignore-all-space, ignore-space-change, ignore-blank-lines, include, exclude
   clone: noupdate, updaterev, rev, branch, pull, uncompressed, ssh, remotecmd, insecure
   commit: addremove, close-branch, include, exclude, message, logfile, date, user, subrepos
   diff: rev, change, text, git, nodates, show-function, reverse, ignore-all-space, ignore-space-change, ignore-blank-lines, unified, stat, include, exclude, subrepos
--- a/tests/test-default-push.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-default-push.t	Tue Nov 22 18:16:59 2011 +0100
@@ -18,7 +18,7 @@
 Push should push to 'default' when 'default-push' not set:
 
   $ hg --cwd b push
-  pushing to $TESTTMP/a
+  pushing to $TESTTMP/a (glob)
   searching for changes
   adding changesets
   adding manifests
@@ -29,7 +29,7 @@
 
   $ echo 'default-push = ../c' >> b/.hg/hgrc
   $ hg --cwd b push
-  pushing to $TESTTMP/c
+  pushing to $TESTTMP/c (glob)
   searching for changes
   adding changesets
   adding manifests
--- a/tests/test-diff-color.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-diff-color.t	Tue Nov 22 18:16:59 2011 +0100
@@ -1,3 +1,5 @@
+  $ "$TESTDIR/hghave" execbit || exit 80
+
 Setup
 
   $ echo "[color]" >> $HGRCPATH
@@ -74,7 +76,7 @@
 
 record
 
-  $ chmod 0755 a
+  $ chmod +x a
   $ hg record --color=always -m moda a <<EOF
   > y
   > y
--- a/tests/test-diff-hashes.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-diff-hashes.t	Tue Nov 22 18:16:59 2011 +0100
@@ -2,8 +2,8 @@
   $ cd a
 
   $ hg diff inexistent1 inexistent2
-  inexistent1: No such file or directory
-  inexistent2: No such file or directory
+  inexistent1: * (glob)
+  inexistent2: * (glob)
 
   $ echo bar > foo
   $ hg add foo
--- a/tests/test-diff-newlines.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-diff-newlines.t	Tue Nov 22 18:16:59 2011 +0100
@@ -1,6 +1,6 @@
   $ hg init
 
-  $ python -c 'print "confuse str.splitlines\nembedded\rnewline"' > a
+  $ python -c 'file("a", "wb").write("confuse str.splitlines\nembedded\rnewline\n")'
   $ hg ci -Ama -d '1 0'
   adding a
 
--- a/tests/test-diff-upgrade.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-diff-upgrade.t	Tue Nov 22 18:16:59 2011 +0100
@@ -1,3 +1,4 @@
+  $ "$TESTDIR/hghave" execbit || exit 80
 
   $ echo "[extensions]" >> $HGRCPATH
   $ echo "autodiff=$TESTDIR/autodiff.py" >> $HGRCPATH
--- a/tests/test-dirstate.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-dirstate.t	Tue Nov 22 18:16:59 2011 +0100
@@ -11,9 +11,9 @@
   adding a/b/c/d/y
   adding a/b/c/d/z
   $ hg mv a z
-  moving a/b/c/d/x to z/b/c/d/x
-  moving a/b/c/d/y to z/b/c/d/y
-  moving a/b/c/d/z to z/b/c/d/z
+  moving a/b/c/d/x to z/b/c/d/x (glob)
+  moving a/b/c/d/y to z/b/c/d/y (glob)
+  moving a/b/c/d/z to z/b/c/d/z (glob)
   $ cd ..
 
 Issue1790: dirstate entry locked into unset if file mtime is set into
--- a/tests/test-eol.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-eol.t	Tue Nov 22 18:16:59 2011 +0100
@@ -1,3 +1,5 @@
+  $ "$TESTDIR/hghave" unix-permissions || exit 80
+
 Test EOL extension
 
   $ cat >> $HGRCPATH <<EOF
--- a/tests/test-extdiff.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-extdiff.t	Tue Nov 22 18:16:59 2011 +0100
@@ -1,3 +1,5 @@
+  $ "$TESTDIR/hghave" symlink execbit || exit 80
+
   $ echo "[extensions]" >> $HGRCPATH
   $ echo "extdiff=" >> $HGRCPATH
 
--- a/tests/test-extension.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-extension.t	Tue Nov 22 18:16:59 2011 +0100
@@ -473,7 +473,7 @@
   > cmdtable = None
   > EOF
   $ hg --config extensions.path=./path.py help foo > /dev/null
-  warning: error finding commands in $TESTTMP/hgext/forest.py
+  warning: error finding commands in $TESTTMP/hgext/forest.py (glob)
   hg: unknown command 'foo'
-  warning: error finding commands in $TESTTMP/hgext/forest.py
+  warning: error finding commands in $TESTTMP/hgext/forest.py (glob)
   [255]
--- a/tests/test-fetch.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-fetch.t	Tue Nov 22 18:16:59 2011 +0100
@@ -1,3 +1,5 @@
+  $ "$TESTDIR/hghave" serve || exit 80
+
   $ echo "[extensions]" >> $HGRCPATH
   $ echo "fetch=" >> $HGRCPATH
 
--- a/tests/test-filecache.py	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-filecache.py	Tue Nov 22 18:16:59 2011 +0100
@@ -1,6 +1,6 @@
 import sys, os, subprocess
 
-if subprocess.call(['%s/hghave' % os.environ['TESTDIR'], 'cacheable']):
+if subprocess.call(['python', '%s/hghave' % os.environ['TESTDIR'], 'cacheable']):
     sys.exit(80)
 
 from mercurial import util, scmutil, extensions
--- a/tests/test-flags.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-flags.t	Tue Nov 22 18:16:59 2011 +0100
@@ -1,3 +1,5 @@
+  $ "$TESTDIR/hghave" execbit || exit 80
+
   $ umask 027
 
   $ hg init test1
--- a/tests/test-fncache.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-fncache.t	Tue Nov 22 18:16:59 2011 +0100
@@ -14,7 +14,7 @@
   $ mkdir a.i
   $ echo "some other text" > a.i/b
   $ hg add
-  adding a.i/b
+  adding a.i/b (glob)
   $ hg ci -m second
   $ cat .hg/store/fncache | sort
   data/a.i
@@ -25,7 +25,7 @@
   $ mkdir a.i.hg
   $ echo "yet another text" > a.i.hg/c
   $ hg add
-  adding a.i.hg/c
+  adding a.i.hg/c (glob)
   $ hg ci -m third
   $ cat .hg/store/fncache | sort
   data/a.i
@@ -74,12 +74,14 @@
   .hg/data/tst.d.hg/foo.i
   .hg/dirstate
   .hg/last-message.txt
+  .hg/phaseroots
   .hg/requires
   .hg/undo
   .hg/undo.bookmarks
   .hg/undo.branch
   .hg/undo.desc
   .hg/undo.dirstate
+  .hg/undo.phaseroots
   $ cd ..
 
 Non fncache repo:
@@ -102,7 +104,9 @@
   .hg/store/data
   .hg/store/data/tst.d.hg
   .hg/store/data/tst.d.hg/_foo.i
+  .hg/store/phaseroots
   .hg/store/undo
+  .hg/store/undo.phaseroots
   .hg/undo.bookmarks
   .hg/undo.branch
   .hg/undo.desc
--- a/tests/test-getbundle.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-getbundle.t	Tue Nov 22 18:16:59 2011 +0100
@@ -1,3 +1,4 @@
+  $ "$TESTDIR/hghave" serve || exit 80
 
 = Test the getbundle() protocol function =
 
--- a/tests/test-git-export.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-git-export.t	Tue Nov 22 18:16:59 2011 +0100
@@ -1,3 +1,5 @@
+  $ "$TESTDIR/hghave" execbit || exit 80
+
   $ hg init
   $ echo start > start
   $ hg ci -Amstart
--- a/tests/test-graft.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-graft.t	Tue Nov 22 18:16:59 2011 +0100
@@ -151,7 +151,7 @@
   merging e
   my e@77eb504366ab+ other e@9c233e8e184d ancestor e@68795b066622
   warning: conflicts during merge.
-  merging e failed!
+  merging e incomplete! (edit conflicts, then use 'hg resolve --mark')
     searching for copies back to rev 1
     unmatched files in local:
      c
--- a/tests/test-hardlinks.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-hardlinks.t	Tue Nov 22 18:16:59 2011 +0100
@@ -1,3 +1,5 @@
+  $ "$TESTDIR/hghave" no-windows || exit 80
+
   $ cat > nlinks.py <<EOF
   > import os, sys
   > for f in sorted(sys.stdin.readlines()):
@@ -45,7 +47,9 @@
   1 r1/.hg/store/data/d1/f2.i
   1 r1/.hg/store/data/f1.i
   1 r1/.hg/store/fncache
+  1 r1/.hg/store/phaseroots
   1 r1/.hg/store/undo
+  1 r1/.hg/store/undo.phaseroots
 
 
 Create hardlinked clone r2:
@@ -73,7 +77,9 @@
   2 r1/.hg/store/data/d1/f2.i
   2 r1/.hg/store/data/f1.i
   2 r1/.hg/store/fncache
+  1 r1/.hg/store/phaseroots
   1 r1/.hg/store/undo
+  1 r1/.hg/store/undo.phaseroots
 
   $ nlinksdir r2/.hg/store
   2 r2/.hg/store/00changelog.i
@@ -91,6 +97,7 @@
   1 r3/.hg/store/data/f1.i
   1 r3/.hg/store/fncache
   1 r3/.hg/store/undo
+  1 r3/.hg/store/undo.phaseroots
 
 
 Create a non-inlined filelog in r3:
@@ -110,7 +117,9 @@
   1 r3/.hg/store/data/d1/f2.i
   1 r3/.hg/store/data/f1.i
   1 r3/.hg/store/fncache
+  1 r3/.hg/store/phaseroots
   1 r3/.hg/store/undo
+  1 r3/.hg/store/undo.phaseroots
 
 Push to repo r1 should break up most hardlinks in r2:
 
@@ -193,7 +202,9 @@
   2 r4/.hg/store/data/d1/f2.i
   2 r4/.hg/store/data/f1.i
   2 r4/.hg/store/fncache
+  2 r4/.hg/store/phaseroots
   2 r4/.hg/store/undo
+  2 r4/.hg/store/undo.phaseroots
   2 r4/.hg/undo.bookmarks
   2 r4/.hg/undo.branch
   2 r4/.hg/undo.desc
@@ -222,7 +233,9 @@
   2 r4/.hg/store/data/d1/f2.i
   2 r4/.hg/store/data/f1.i
   2 r4/.hg/store/fncache
+  2 r4/.hg/store/phaseroots
   2 r4/.hg/store/undo
+  2 r4/.hg/store/undo.phaseroots
   2 r4/.hg/undo.bookmarks
   2 r4/.hg/undo.branch
   2 r4/.hg/undo.desc
--- a/tests/test-hgignore.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-hgignore.t	Tue Nov 22 18:16:59 2011 +0100
@@ -44,7 +44,7 @@
 
   $ echo "*.o" > .hgignore
   $ hg status
-  abort: $TESTTMP/.hgignore: invalid pattern (relre): *.o
+  abort: $TESTTMP/.hgignore: invalid pattern (relre): *.o (glob)
   [255]
 
   $ echo ".*\.o" > .hgignore
@@ -88,7 +88,7 @@
 
   $ echo "syntax: invalid" > .hgignore
   $ hg status
-  $TESTTMP/.hgignore: ignoring invalid syntax 'invalid'
+  $TESTTMP/.hgignore: ignoring invalid syntax 'invalid' (glob)
   A dir/b.o
   ? .hgignore
   ? a.c
--- a/tests/test-hgrc.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-hgrc.t	Tue Nov 22 18:16:59 2011 +0100
@@ -26,12 +26,12 @@
   $ cd foobar
   $ cat .hg/hgrc
   [paths]
-  default = $TESTTMP/foo%bar
+  default = $TESTTMP/foo%bar (glob)
   $ hg paths
-  default = $TESTTMP/foo%bar
+  default = $TESTTMP/foo%bar (glob)
   $ hg showconfig
-  bundle.mainreporoot=$TESTTMP/foobar
-  paths.default=$TESTTMP/foo%bar
+  bundle.mainreporoot=$TESTTMP/foobar (glob)
+  paths.default=$TESTTMP/foo%bar (glob)
   $ cd ..
 
 issue1829: wrong indentation
--- a/tests/test-hgweb-commands.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-hgweb-commands.t	Tue Nov 22 18:16:59 2011 +0100
@@ -1,3 +1,5 @@
+  $ "$TESTDIR/hghave" serve || exit 80
+
 An attempt at more fully testing the hgweb web interface.
 The following things are tested elsewhere and are therefore omitted:
 - archive, tested in test-archive
--- a/tests/test-hgweb-descend-empties.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-hgweb-descend-empties.t	Tue Nov 22 18:16:59 2011 +0100
@@ -1,3 +1,5 @@
+  $ "$TESTDIR/hghave" serve || exit 80
+
 Test chains of near empty directories, terminating 3 different ways:
 - a1: file at level 4 (deepest)
 - b1: two dirs at level 3
--- a/tests/test-hgweb-diffs.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-hgweb-diffs.t	Tue Nov 22 18:16:59 2011 +0100
@@ -1,3 +1,5 @@
+  $ "$TESTDIR/hghave" serve execbit || exit 80
+
 setting up repo
 
   $ hg init test
@@ -10,7 +12,7 @@
 
 change permissions for git diffs
 
-  $ chmod 755 a
+  $ chmod +x a
   $ hg ci -Amb
 
 set up hgweb
--- a/tests/test-hgweb-empty.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-hgweb-empty.t	Tue Nov 22 18:16:59 2011 +0100
@@ -1,3 +1,5 @@
+  $ "$TESTDIR/hghave" serve || exit 80
+
 Some tests for hgweb in an empty repository
 
   $ hg init test
--- a/tests/test-hgweb-filelog.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-hgweb-filelog.t	Tue Nov 22 18:16:59 2011 +0100
@@ -1,3 +1,4 @@
+  $ "$TESTDIR/hghave" serve || exit 80
 
   $ hg init test
   $ cd test
--- a/tests/test-hgweb-raw.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-hgweb-raw.t	Tue Nov 22 18:16:59 2011 +0100
@@ -1,3 +1,5 @@
+  $ "$TESTDIR/hghave" serve || exit 80
+
 Test raw style of hgweb
 
   $ hg init test
--- a/tests/test-hgweb-removed.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-hgweb-removed.t	Tue Nov 22 18:16:59 2011 +0100
@@ -1,3 +1,5 @@
+  $ "$TESTDIR/hghave" serve || exit 80
+
 setting up repo
 
   $ hg init test
--- a/tests/test-hgweb.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-hgweb.t	Tue Nov 22 18:16:59 2011 +0100
@@ -1,3 +1,5 @@
+  $ "$TESTDIR/hghave" serve || exit 80
+
 Some tests for hgweb. Tests static files, plain files and different 404's.
 
   $ hg init test
--- a/tests/test-hgwebdir.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-hgwebdir.t	Tue Nov 22 18:16:59 2011 +0100
@@ -1,3 +1,5 @@
+  $ "$TESTDIR/hghave" serve || exit 80
+
 Tests some basic hgwebdir functionality. Tests setting up paths and
 collection, different forms of 404s and the subdirectory support.
 
--- a/tests/test-hgwebdirsym.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-hgwebdirsym.t	Tue Nov 22 18:16:59 2011 +0100
@@ -1,6 +1,6 @@
 Tests whether or not hgwebdir properly handles various symlink topologies.
 
-  $ "$TESTDIR/hghave" symlink || exit 80
+  $ "$TESTDIR/hghave" serve symlink || exit 80
   $ hg init a
   $ echo a > a/a
   $ hg --cwd a ci -Ama -d'1 0'
--- a/tests/test-highlight.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-highlight.t	Tue Nov 22 18:16:59 2011 +0100
@@ -1,5 +1,5 @@
 
-  $ "$TESTDIR/hghave" pygments || exit 80
+  $ "$TESTDIR/hghave" pygments serve || exit 80
   $ cat <<EOF >> $HGRCPATH
   > [extensions]
   > highlight =
--- a/tests/test-hook.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-hook.t	Tue Nov 22 18:16:59 2011 +0100
@@ -1,3 +1,5 @@
+  $ "$TESTDIR/hghave" system-sh || exit 80
+
 commit hooks can see env vars
 
   $ hg init a
--- a/tests/test-http-branchmap.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-http-branchmap.t	Tue Nov 22 18:16:59 2011 +0100
@@ -1,3 +1,4 @@
+  $ "$TESTDIR/hghave" serve || exit 80
 
   $ hgserve() {
   >     hg serve -a localhost -p $HGPORT1 -d --pid-file=hg.pid -E errors.log -v $@
--- a/tests/test-http-clone-r.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-http-clone-r.t	Tue Nov 22 18:16:59 2011 +0100
@@ -1,3 +1,5 @@
+  $ "$TESTDIR/hghave" serve || exit 80
+
 creating 'remote
 
   $ hg init remote
--- a/tests/test-http-proxy.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-http-proxy.t	Tue Nov 22 18:16:59 2011 +0100
@@ -1,3 +1,4 @@
+  $ "$TESTDIR/hghave" serve || exit 80
 
   $ hg init a
   $ cd a
--- a/tests/test-http.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-http.t	Tue Nov 22 18:16:59 2011 +0100
@@ -1,3 +1,4 @@
+  $ "$TESTDIR/hghave" serve || exit 80
 
   $ hg init test
   $ cd test
--- a/tests/test-https.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-https.t	Tue Nov 22 18:16:59 2011 +0100
@@ -1,6 +1,6 @@
 Proper https client requires the built-in ssl from Python 2.6.
 
-  $ "$TESTDIR/hghave" ssl || exit 80
+  $ "$TESTDIR/hghave" serve ssl || exit 80
 
 Certificates created with:
  printf '.\n.\n.\n.\n.\nlocalhost\nhg@localhost\n' | \
--- a/tests/test-hup.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-hup.t	Tue Nov 22 18:16:59 2011 +0100
@@ -1,6 +1,6 @@
 Test hangup signal in the middle of transaction
 
-  $ "$TESTDIR/hghave" fifo || exit 80
+  $ "$TESTDIR/hghave" serve fifo || exit 80
   $ hg init
   $ mkfifo p
   $ hg serve --stdio < p &
@@ -17,4 +17,4 @@
   rollback completed
   killed!
   $ echo .hg/* .hg/store/*
-  .hg/00changelog.i .hg/journal.bookmarks .hg/journal.branch .hg/journal.desc .hg/journal.dirstate .hg/requires .hg/store .hg/store/00changelog.i .hg/store/00changelog.i.a
+  .hg/00changelog.i .hg/journal.bookmarks .hg/journal.branch .hg/journal.desc .hg/journal.dirstate .hg/requires .hg/store .hg/store/00changelog.i .hg/store/00changelog.i.a .hg/store/journal.phaseroots
--- a/tests/test-identify.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-identify.t	Tue Nov 22 18:16:59 2011 +0100
@@ -1,4 +1,4 @@
-  $ "$TESTDIR/hghave" no-outer-repo || exit 80
+  $ "$TESTDIR/hghave" no-outer-repo serve || exit 80
 
 no repo
 
--- a/tests/test-import-bypass.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-import-bypass.t	Tue Nov 22 18:16:59 2011 +0100
@@ -1,3 +1,5 @@
+  $ "$TESTDIR/hghave" symlink execbit || exit 80
+
   $ echo "[extensions]" >> $HGRCPATH
   $ echo "purge=" >> $HGRCPATH
   $ echo "graphlog=" >> $HGRCPATH
--- a/tests/test-import-git.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-import-git.t	Tue Nov 22 18:16:59 2011 +0100
@@ -1,3 +1,4 @@
+  $ "$TESTDIR/hghave" symlink || exit 80
 
   $ hg init
 
--- a/tests/test-import.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-import.t	Tue Nov 22 18:16:59 2011 +0100
@@ -1,3 +1,5 @@
+  $ "$TESTDIR/hghave" unix-permissions || exit 80
+
   $ hg init a
   $ mkdir a/d1
   $ mkdir a/d1/d2
@@ -233,7 +235,7 @@
   > msg.set_payload('email commit message\n' + patch)
   > msg['Subject'] = 'email patch'
   > msg['From'] = 'email patcher'
-  > sys.stdout.write(msg.as_string())
+  > file(sys.argv[2], 'wb').write(msg.as_string())
   > EOF
 
 
@@ -246,7 +248,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
-  $ python mkmsg.py diffed-tip.patch > 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
@@ -308,7 +310,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
-  $ python mkmsg.py exported-tip.patch | hg --cwd b import -
+  $ python mkmsg.py exported-tip.patch msg.patch
+  $ cat msg.patch | hg --cwd b import -
   applying patch from stdin
   $ hg --cwd b tip | grep second
   summary:     second change
@@ -325,7 +328,7 @@
   > 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())
+  > file(sys.argv[2], 'wb').write(msg.as_string())
   > EOF
 
 
@@ -338,7 +341,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
-  $ python mkmsg2.py diffed-tip.patch | hg --cwd b import -
+  $ python mkmsg2.py diffed-tip.patch msg.patch
+  $ cat msg.patch | hg --cwd b import -
   applying patch from stdin
   $ hg --cwd b tip --template '{desc}\n'
   email patch
--- a/tests/test-incoming-outgoing.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-incoming-outgoing.t	Tue Nov 22 18:16:59 2011 +0100
@@ -1,3 +1,5 @@
+  $ "$TESTDIR/hghave" serve || exit 80
+
   $ hg init test
   $ cd test
   $ for i in 0 1 2 3 4 5 6 7 8; do
--- a/tests/test-inherit-mode.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-inherit-mode.t	Tue Nov 22 18:16:59 2011 +0100
@@ -76,7 +76,9 @@
   00660 ./.hg/store/data/dir/bar.i
   00660 ./.hg/store/data/foo.i
   00660 ./.hg/store/fncache
+  00660 ./.hg/store/phaseroots
   00660 ./.hg/store/undo
+  00660 ./.hg/store/undo.phaseroots
   00660 ./.hg/undo.bookmarks
   00660 ./.hg/undo.branch
   00660 ./.hg/undo.desc
@@ -118,6 +120,7 @@
   00660 ../push/.hg/store/data/foo.i
   00660 ../push/.hg/store/fncache
   00660 ../push/.hg/store/undo
+  00660 ../push/.hg/store/undo.phaseroots
   00660 ../push/.hg/undo.bookmarks
   00660 ../push/.hg/undo.branch
   00660 ../push/.hg/undo.desc
--- a/tests/test-init.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-init.t	Tue Nov 22 18:16:59 2011 +0100
@@ -1,3 +1,5 @@
+  $ "$TESTDIR/hghave" no-windows || exit 80
+
 This test tries to exercise the ssh functionality with a dummy script
 
   $ checknewrepo()
--- a/tests/test-install.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-install.t	Tue Nov 22 18:16:59 2011 +0100
@@ -1,8 +1,8 @@
 hg debuginstall
   $ hg debuginstall
   Checking encoding (ascii)...
-  Checking installed modules (*/mercurial)... (glob)
-  Checking templates (*/mercurial/templates)... (glob)
+  Checking installed modules (*mercurial)... (glob)
+  Checking templates (*mercurial?templates)... (glob)
   Checking commit editor...
   Checking username...
   No problems detected
@@ -10,8 +10,8 @@
 hg debuginstall with no username
   $ HGUSER= hg debuginstall
   Checking encoding (ascii)...
-  Checking installed modules (*/mercurial)... (glob)
-  Checking templates (*/mercurial/templates)... (glob)
+  Checking installed modules (*mercurial)... (glob)
+  Checking templates (*mercurial?templates)... (glob)
   Checking commit editor...
   Checking username...
    no username supplied (see "hg help config")
--- a/tests/test-interhg.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-interhg.t	Tue Nov 22 18:16:59 2011 +0100
@@ -1,3 +1,5 @@
+  $ "$TESTDIR/hghave" serve || exit 80
+
   $ hg init test
   $ cd test
 
--- a/tests/test-issue1089.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-issue1089.t	Tue Nov 22 18:16:59 2011 +0100
@@ -7,7 +7,7 @@
   adding a/b
 
   $ hg rm a
-  removing a/b
+  removing a/b (glob)
   $ hg ci -m m a
 
   $ mkdir a b
@@ -16,7 +16,7 @@
   adding a/b
 
   $ hg rm a
-  removing a/b
+  removing a/b (glob)
   $ cd b
 
 Relative delete:
--- a/tests/test-issue1502.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-issue1502.t	Tue Nov 22 18:16:59 2011 +0100
@@ -13,7 +13,7 @@
   $ echo "bar" > foo1/a && hg -R foo1 commit -m "edit a in foo1"
   $ echo "hi" > foo/a && hg -R foo commit -m "edited a foo"
   $ hg -R foo1 pull -u
-  pulling from $TESTTMP/foo
+  pulling from $TESTTMP/foo (glob)
   searching for changes
   adding changesets
   adding manifests
@@ -29,7 +29,7 @@
 
   $ echo "there" >> foo/a && hg -R foo commit -m "edited a again"
   $ hg -R foo1 pull
-  pulling from $TESTTMP/foo
+  pulling from $TESTTMP/foo (glob)
   searching for changes
   adding changesets
   adding manifests
--- a/tests/test-issue1802.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-issue1802.t	Tue Nov 22 18:16:59 2011 +0100
@@ -1,3 +1,5 @@
+  $ "$TESTDIR/hghave" execbit || exit 80
+
 Create extension that can disable exec checks:
 
   $ cat > noexec.py <<EOF
--- a/tests/test-issue612.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-issue612.t	Tue Nov 22 18:16:59 2011 +0100
@@ -7,7 +7,7 @@
   adding src/a.c
 
   $ hg mv src source
-  moving src/a.c to source/a.c
+  moving src/a.c to source/a.c (glob)
 
   $ hg ci -Ammove
 
--- a/tests/test-issue660.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-issue660.t	Tue Nov 22 18:16:59 2011 +0100
@@ -67,9 +67,9 @@
 
   $ hg revert --all
   undeleting a
-  forgetting a/a
+  forgetting a/a (glob)
   forgetting b
-  undeleting b/b
+  undeleting b/b (glob)
 
   $ hg st
 
--- a/tests/test-journal-exists.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-journal-exists.t	Tue Nov 22 18:16:59 2011 +0100
@@ -1,3 +1,5 @@
+  $ "$TESTDIR/hghave" unix-permissions || exit 80
+
   $ hg init
   $ echo a > a
   $ hg ci -Am0
--- a/tests/test-keyword.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-keyword.t	Tue Nov 22 18:16:59 2011 +0100
@@ -1,3 +1,5 @@
+  $ "$TESTDIR/hghave" symlink unix-permissions serve || exit 80
+
   $ cat <<EOF >> $HGRCPATH
   > [extensions]
   > keyword =
@@ -208,7 +210,7 @@
   Message-Id: <hg.a2392c293916*> (glob)
   To: Test
   
-  changeset a2392c293916 in $TESTTMP/Test
+  changeset a2392c293916 in $TESTTMP/Test (glob)
   details: $TESTTMP/Test?cmd=changeset;node=a2392c293916
   description:
   	addsym
@@ -231,7 +233,7 @@
   Message-Id: <hg.ef63ca68695b*> (glob)
   To: Test
   
-  changeset ef63ca68695b in $TESTTMP/Test
+  changeset ef63ca68695b in $TESTTMP/Test (glob)
   details: $TESTTMP/Test?cmd=changeset;node=ef63ca68695b
   description:
   	absym
@@ -797,7 +799,7 @@
   > default = ../Test
   > EOF
   $ hg incoming
-  comparing with $TESTTMP/Test
+  comparing with $TESTTMP/Test (glob)
   searching for changes
   changeset:   2:bb948857c743
   tag:         tip
@@ -974,7 +976,7 @@
   $ hg merge
   merging m
   warning: conflicts during merge.
-  merging m failed!
+  merging m incomplete! (edit conflicts, then use 'hg resolve --mark')
   0 files updated, 0 files merged, 0 files removed, 1 files unresolved
   use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
   [1]
--- a/tests/test-known.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-known.t	Tue Nov 22 18:16:59 2011 +0100
@@ -1,3 +1,4 @@
+  $ "$TESTDIR/hghave" serve || exit 80
 
 = Test the known() protocol function =
 
--- a/tests/test-largefiles.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-largefiles.t	Tue Nov 22 18:16:59 2011 +0100
@@ -1,3 +1,5 @@
+  $ "$TESTDIR/hghave" symlink unix-permissions serve || exit 80
+
   $ cat >> $HGRCPATH <<EOF
   > [extensions]
   > largefiles=
@@ -183,8 +185,8 @@
   $ echo large6 > sub2/large6
   $ echo large7 > sub2/large7
   $ hg add --large sub2
-  adding sub2/large6 as a largefile
-  adding sub2/large7 as a largefile
+  adding sub2/large6 as a largefile (glob)
+  adding sub2/large7 as a largefile (glob)
   $ hg st
   M large3
   A large5
@@ -347,7 +349,7 @@
   added 1 changesets with 2 changes to 2 files (+1 heads)
   getting changed largefiles
   1 largefiles updated, 0 removed
-  saved backup bundle to $TESTTMP/d/.hg/strip-backup/f574fb32bb45-backup.hg
+  saved backup bundle to $TESTTMP/d/.hg/strip-backup/f574fb32bb45-backup.hg (glob)
   nothing to rebase
   $ hg log --template '{rev}:{node|short}  {desc|firstline}\n'
   9:598410d3eb9a  modify normal file largefile in repo d
@@ -382,7 +384,7 @@
   $ hg rebase
   getting changed largefiles
   1 largefiles updated, 0 removed
-  saved backup bundle to $TESTTMP/e/.hg/strip-backup/f574fb32bb45-backup.hg
+  saved backup bundle to $TESTTMP/e/.hg/strip-backup/f574fb32bb45-backup.hg (glob)
   $ hg log
   changeset:   9:598410d3eb9a
   tag:         tip
@@ -552,8 +554,8 @@
 # XXX we don't really want to report that we're reverting the standin;
 # that's just an implementation detail. But I don't see an obvious fix. ;-(
   $ hg revert sub
-  reverting .hglf/sub/large4
-  reverting sub/normal4
+  reverting .hglf/sub/large4 (glob)
+  reverting sub/normal4 (glob)
   $ hg status
   M normal3
   A sub2/large8
@@ -565,8 +567,8 @@
   $ cat sub/large4
   large4-modified
   $ hg revert -a --no-backup
-  undeleting .hglf/sub2/large6
-  forgetting .hglf/sub2/large8
+  undeleting .hglf/sub2/large6 (glob)
+  forgetting .hglf/sub2/large8 (glob)
   reverting normal3
   $ hg status
   ? sub/large4.orig
@@ -580,11 +582,11 @@
 
 revert some files to an older revision
   $ hg revert --no-backup -r 8 sub2
-  reverting .hglf/sub2/large6
+  reverting .hglf/sub2/large6 (glob)
   $ cat sub2/large6
   large6
   $ hg revert --no-backup sub2
-  reverting .hglf/sub2/large6
+  reverting .hglf/sub2/large6 (glob)
   $ hg status
 
 "verify --large" actually verifies largefiles
@@ -815,6 +817,7 @@
   getting changed largefiles
   1 largefiles updated, 0 removed
   $ cd ..
+  $ chmod -R u+w alice/pubrepo
   $ HOME="$ORIGHOME"
 
 Symlink to a large largefile should behave the same as a symlink to a normal file
--- a/tests/test-lfconvert.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-lfconvert.t	Tue Nov 22 18:16:59 2011 +0100
@@ -83,8 +83,8 @@
   $ hg commit -q -m"remove large, normal3"
   $ hg merge
   merging sub/maybelarge.dat and stuff/maybelarge.dat to stuff/maybelarge.dat
-  warning: $TESTTMP/bigfile-repo/stuff/maybelarge.dat looks like a binary file.
-  merging stuff/maybelarge.dat failed!
+  warning: $TESTTMP/bigfile-repo/stuff/maybelarge.dat looks like a binary file. (glob)
+  merging stuff/maybelarge.dat incomplete! (edit conflicts, then use 'hg resolve --mark')
   merging sub/normal2 and stuff/normal2 to stuff/normal2
   0 files updated, 1 files merged, 0 files removed, 1 files unresolved
   use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
@@ -170,7 +170,7 @@
   $ hg share -q -U bigfile-repo shared
   $ printf 'bogus' > shared/.hg/sharedpath
   $ hg lfconvert shared foo
-  abort: .hg/sharedpath points to nonexistent directory $TESTTMP/bogus!
+  abort: .hg/sharedpath points to nonexistent directory $TESTTMP/bogus! (glob)
   [255]
   $ hg lfconvert bigfile-repo largefiles-repo
   initializing destination largefiles-repo
--- a/tests/test-locate.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-locate.t	Tue Nov 22 18:16:59 2011 +0100
@@ -88,33 +88,33 @@
   $ rm -r t
 
   $ hg locate 't/**'
-  t/b
-  t/e.h
-  t/x
+  t/b (glob)
+  t/e.h (glob)
+  t/x (glob)
 
   $ mkdir otherdir
   $ cd otherdir
 
   $ hg locate b
-  ../b
-  ../t/b
+  ../b (glob)
+  ../t/b (glob)
   $ hg locate '*.h'
-  ../t.h
-  ../t/e.h
+  ../t.h (glob)
+  ../t/e.h (glob)
   $ hg locate path:t/x
-  ../t/x
+  ../t/x (glob)
   $ hg locate 're:.*\.h$'
-  ../t.h
-  ../t/e.h
+  ../t.h (glob)
+  ../t/e.h (glob)
   $ hg locate -r 0 b
-  ../b
-  ../t/b
+  ../b (glob)
+  ../t/b (glob)
   $ hg locate -r 0 '*.h'
-  ../t.h
-  ../t/e.h
+  ../t.h (glob)
+  ../t/e.h (glob)
   $ hg locate -r 0 path:t/x
-  ../t/x
+  ../t/x (glob)
   $ hg locate -r 0 're:.*\.h$'
-  ../t.h
-  ../t/e.h
+  ../t.h (glob)
+  ../t/e.h (glob)
 
--- a/tests/test-lock-badness.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-lock-badness.t	Tue Nov 22 18:16:59 2011 +0100
@@ -1,3 +1,5 @@
+  $ "$TESTDIR/hghave" unix-permissions || exit 80
+
   $ hg init a
   $ echo a > a/a
   $ hg -R a ci -A -m a
--- a/tests/test-log.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-log.t	Tue Nov 22 18:16:59 2011 +0100
@@ -1,3 +1,5 @@
+  $ "$TESTDIR/hghave" execbit || exit 80
+
   $ hg init a
 
   $ cd a
@@ -920,7 +922,7 @@
   $ hg merge 7
   merging foo
   warning: conflicts during merge.
-  merging foo failed!
+  merging foo incomplete! (edit conflicts, then use 'hg resolve --mark')
   0 files updated, 0 files merged, 0 files removed, 1 files unresolved
   use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
   [1]
@@ -931,7 +933,7 @@
   $ hg merge 4
   merging foo
   warning: conflicts during merge.
-  merging foo failed!
+  merging foo incomplete! (edit conflicts, then use 'hg resolve --mark')
   1 files updated, 0 files merged, 0 files removed, 1 files unresolved
   use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
   [1]
--- a/tests/test-manifest.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-manifest.t	Tue Nov 22 18:16:59 2011 +0100
@@ -1,3 +1,5 @@
+  $ "$TESTDIR/hghave" symlink || exit 80
+
 Source bundle was generated with the following script:
 
 # hg init
--- a/tests/test-merge-local.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-merge-local.t	Tue Nov 22 18:16:59 2011 +0100
@@ -63,7 +63,7 @@
   merging zzz1_merge_ok
   merging zzz2_merge_bad
   warning: conflicts during merge.
-  merging zzz2_merge_bad failed!
+  merging zzz2_merge_bad incomplete! (edit conflicts, then use 'hg resolve --mark')
   2 files updated, 1 files merged, 3 files removed, 1 files unresolved
   use 'hg resolve' to retry unresolved file merges
   [1]
@@ -88,7 +88,7 @@
   merging zzz1_merge_ok
   merging zzz2_merge_bad
   warning: conflicts during merge.
-  merging zzz2_merge_bad failed!
+  merging zzz2_merge_bad incomplete! (edit conflicts, then use 'hg resolve --mark')
   3 files updated, 1 files merged, 2 files removed, 1 files unresolved
   use 'hg resolve' to retry unresolved file merges
   [1]
@@ -97,7 +97,7 @@
   merging zzz1_merge_ok
   merging zzz2_merge_bad
   warning: conflicts during merge.
-  merging zzz2_merge_bad failed!
+  merging zzz2_merge_bad incomplete! (edit conflicts, then use 'hg resolve --mark')
   2 files updated, 1 files merged, 3 files removed, 1 files unresolved
   use 'hg resolve' to retry unresolved file merges
   [1]
--- a/tests/test-merge-prompt.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-merge-prompt.t	Tue Nov 22 18:16:59 2011 +0100
@@ -77,7 +77,7 @@
 
   $ status
   --- status ---
-  file2: No such file or directory
+  file2: * (glob)
   C file1
   --- file1 ---
   1
@@ -133,7 +133,7 @@
 
   $ status
   --- status ---
-  file2: No such file or directory
+  file2: * (glob)
   C file1
   --- file1 ---
   1
--- a/tests/test-merge-revert2.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-merge-revert2.t	Tue Nov 22 18:16:59 2011 +0100
@@ -45,7 +45,7 @@
   $ hg update
   merging file1
   warning: conflicts during merge.
-  merging file1 failed!
+  merging file1 incomplete! (edit conflicts, then use 'hg resolve --mark')
   0 files updated, 0 files merged, 0 files removed, 1 files unresolved
   use 'hg resolve' to retry unresolved file merges
   [1]
--- a/tests/test-merge-symlinks.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-merge-symlinks.t	Tue Nov 22 18:16:59 2011 +0100
@@ -1,3 +1,4 @@
+  $ "$TESTDIR/hghave" symlink || exit 80
 
   $ cat > echo.py <<EOF
   > #!/usr/bin/env python
--- a/tests/test-merge-tools.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-merge-tools.t	Tue Nov 22 18:16:59 2011 +0100
@@ -1,3 +1,5 @@
+  $ "$TESTDIR/hghave" system-sh || exit 80
+
 test merge-tools configuration - mostly exercising filemerge.py
 
   $ unset HGMERGE # make sure HGMERGE doesn't interfere with the test
@@ -66,7 +68,7 @@
   $ PATH="$BINDIR" $PYTHON "$BINDIR"/hg merge -r 2
   merging f
   warning: conflicts during merge.
-  merging f failed!
+  merging f incomplete! (edit conflicts, then use 'hg resolve --mark')
   0 files updated, 0 files merged, 0 files removed, 1 files unresolved
   use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
   [1]
@@ -101,6 +103,32 @@
   M f
   ? f.orig
 
+unexecutable file in $PATH shouldn't be found:
+
+  $ touch false
+  $ hg up -qC 1
+  $ PATH="`pwd`:$BINDIR" $PYTHON "$BINDIR"/hg merge -r 2
+  merging f
+  warning: conflicts during merge.
+  merging f incomplete! (edit conflicts, then use 'hg resolve --mark')
+  0 files updated, 0 files merged, 0 files removed, 1 files unresolved
+  use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
+  [1]
+  $ rm false
+
+executable directory in $PATH shouldn't be found:
+
+  $ mkdir false
+  $ hg up -qC 1
+  $ PATH="`pwd`:$BINDIR" $PYTHON "$BINDIR"/hg merge -r 2
+  merging f
+  warning: conflicts during merge.
+  merging f incomplete! (edit conflicts, then use 'hg resolve --mark')
+  0 files updated, 0 files merged, 0 files removed, 1 files unresolved
+  use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
+  [1]
+  $ rmdir false
+
 true with higher .priority gets precedence:
 
   $ echo "true.priority=1" >> .hg/hgrc
--- a/tests/test-merge-types.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-merge-types.t	Tue Nov 22 18:16:59 2011 +0100
@@ -1,3 +1,5 @@
+  $ "$TESTDIR/hghave" symlink execbit || exit 80
+
   $ hg init
 
   $ echo a > a
--- a/tests/test-merge7.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-merge7.t	Tue Nov 22 18:16:59 2011 +0100
@@ -45,7 +45,7 @@
   $ hg merge
   merging test.txt
   warning: conflicts during merge.
-  merging test.txt failed!
+  merging test.txt incomplete! (edit conflicts, then use 'hg resolve --mark')
   0 files updated, 0 files merged, 0 files removed, 1 files unresolved
   use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
   [1]
@@ -90,7 +90,7 @@
   merging test.txt
   my test.txt@50c3a7e29886+ other test.txt@40d11a4173a8 ancestor test.txt@96b70246a118
   warning: conflicts during merge.
-  merging test.txt failed!
+  merging test.txt incomplete! (edit conflicts, then use 'hg resolve --mark')
   0 files updated, 0 files merged, 0 files removed, 1 files unresolved
   use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
   [1]
--- a/tests/test-merge9.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-merge9.t	Tue Nov 22 18:16:59 2011 +0100
@@ -83,7 +83,7 @@
   $ hg resolve -a
   merging bar
   warning: conflicts during merge.
-  merging bar failed!
+  merging bar incomplete! (edit conflicts, then use 'hg resolve --mark')
   [1]
 
 after
--- a/tests/test-mq-merge.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-mq-merge.t	Tue Nov 22 18:16:59 2011 +0100
@@ -56,7 +56,7 @@
 Save the patch queue so we can merge it later:
 
   $ hg qsave -c -e
-  copy $TESTTMP/t/.hg/patches to $TESTTMP/t/.hg/patches.1
+  copy $TESTTMP/t/.hg/patches to $TESTTMP/t/.hg/patches.1 (glob)
   $ checkundo
 
 Update b and commit in an "update" changeset:
@@ -76,7 +76,7 @@
   b
 
   $ hg qpush -a -m
-  merging with queue at: $TESTTMP/t/.hg/patches.1
+  merging with queue at: $TESTTMP/t/.hg/patches.1 (glob)
   applying rm_a
   now at: rm_a
 
@@ -115,14 +115,14 @@
 Create the reference queue:
 
   $ hg qsave -c -e -n refqueue
-  copy $TESTTMP/t2/.hg/patches to $TESTTMP/t2/.hg/refqueue
+  copy $TESTTMP/t2/.hg/patches to $TESTTMP/t2/.hg/refqueue (glob)
   $ hg up -C 1
   1 files updated, 0 files merged, 1 files removed, 0 files unresolved
 
 Merge:
 
   $ HGMERGE=internal:other hg qpush -a -m -n refqueue
-  merging with queue at: $TESTTMP/t2/.hg/refqueue
+  merging with queue at: $TESTTMP/t2/.hg/refqueue (glob)
   applying patcha
   patching file a
   Hunk #1 FAILED at 0
--- a/tests/test-mq-qclone-http.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-mq-qclone-http.t	Tue Nov 22 18:16:59 2011 +0100
@@ -1,3 +1,4 @@
+  $ "$TESTDIR/hghave" serve || exit 80
 
   $ echo "[extensions]" >> $HGRCPATH
   $ echo "mq=" >> $HGRCPATH
--- a/tests/test-mq-qdelete.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-mq-qdelete.t	Tue Nov 22 18:16:59 2011 +0100
@@ -188,7 +188,9 @@
   $ 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
+  $ echo pup > base
   $ hg qfinish -a
+  warning: uncommitted changes in the working directory
   revision 2b1c98802260 refers to unknown patches: 5.diff
   revision 33a6861311c0 refers to unknown patches: 4.diff
 
--- a/tests/test-mq-qimport.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-mq-qimport.t	Tue Nov 22 18:16:59 2011 +0100
@@ -1,3 +1,4 @@
+  $ "$TESTDIR/hghave" serve || exit 80
 
   $ cat > writelines.py <<EOF
   > import sys
--- a/tests/test-mq-qnew.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-mq-qnew.t	Tue Nov 22 18:16:59 2011 +0100
@@ -123,7 +123,7 @@
   A series
   A uncommitted.patch
   % qnew missing
-  abort: missing: No such file or directory
+  abort: missing: * (glob)
   % qnew -m
   foo bar
   
@@ -155,7 +155,7 @@
   created new head
   merging a
   warning: conflicts during merge.
-  merging a failed!
+  merging a incomplete! (edit conflicts, then use 'hg resolve --mark')
   0 files updated, 0 files merged, 0 files removed, 1 files unresolved
   use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
   abort: cannot manage merge changesets
@@ -190,7 +190,7 @@
   A series
   A uncommitted.patch
   % qnew missing
-  abort: missing: No such file or directory
+  abort: missing: * (glob)
   % qnew -m
   # HG changeset patch
   # Parent 
@@ -228,7 +228,7 @@
   created new head
   merging a
   warning: conflicts during merge.
-  merging a failed!
+  merging a incomplete! (edit conflicts, then use 'hg resolve --mark')
   0 files updated, 0 files merged, 0 files removed, 1 files unresolved
   use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
   abort: cannot manage merge changesets
--- a/tests/test-mq-safety.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-mq-safety.t	Tue Nov 22 18:16:59 2011 +0100
@@ -39,7 +39,7 @@
   abort: popping would remove a revision not managed by this patch queue
   [255]
   $ hg qpop -n patches
-  using patch queue: $TESTTMP/repo/.hg/patches
+  using patch queue: $TESTTMP/repo/.hg/patches (glob)
   abort: popping would remove a revision not managed by this patch queue
   [255]
   $ hg qrefresh
--- a/tests/test-mq.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-mq.t	Tue Nov 22 18:16:59 2011 +0100
@@ -1,3 +1,5 @@
+  $ "$TESTDIR/hghave" execbit || exit 80
+
   $ checkundo()
   > {
   >     if [ -f .hg/store/undo ]; then
@@ -135,7 +137,7 @@
   guards
   $ cat .hg/patches/series
   $ hg qinit -c
-  abort: repository $TESTTMP/d/.hg/patches already exists!
+  abort: repository $TESTTMP/d/.hg/patches already exists! (glob)
   [255]
   $ cd ..
 
@@ -154,8 +156,8 @@
   $ echo status >> .hg/patches/.hgignore
   $ echo bleh >> .hg/patches/.hgignore
   $ hg qinit -c
-  adding .hg/patches/A
-  adding .hg/patches/B
+  adding .hg/patches/A (glob)
+  adding .hg/patches/B (glob)
   $ hg -R .hg/patches status
   A .hgignore
   A A
@@ -1191,7 +1193,7 @@
 
   $ cd qclonesource
   $ hg qinit -c
-  adding .hg/patches/patch1
+  adding .hg/patches/patch1 (glob)
   $ hg qci -m checkpoint
   $ qlog
   main repo:
--- a/tests/test-mv-cp-st-diff.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-mv-cp-st-diff.t	Tue Nov 22 18:16:59 2011 +0100
@@ -1138,7 +1138,7 @@
   updating to branch default
   3 files updated, 0 files merged, 0 files removed, 0 files unresolved
   created new head
-  moving x/x to y/x
+  moving x/x to y/x (glob)
   ** directory move **
   ** hg mv x y / add y/x x1 / add y/x x2
   - working to parent: 
--- a/tests/test-nested-repo.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-nested-repo.t	Tue Nov 22 18:16:59 2011 +0100
@@ -11,16 +11,16 @@
 Should fail:
 
   $ hg st b/x
-  abort: path 'b/x' is inside nested repo 'b'
+  abort: path 'b/x' is inside nested repo 'b' (glob)
   [255]
   $ hg add b/x
-  abort: path 'b/x' is inside nested repo 'b'
+  abort: path 'b/x' is inside nested repo 'b' (glob)
   [255]
 
 Should fail:
 
   $ hg add b b/x
-  abort: path 'b/x' is inside nested repo 'b'
+  abort: path 'b/x' is inside nested repo 'b' (glob)
   [255]
   $ hg st
 
@@ -34,7 +34,7 @@
 Should fail:
 
   $ hg mv a b
-  abort: path 'b/a' is inside nested repo 'b'
+  abort: path 'b/a' is inside nested repo 'b' (glob)
   [255]
   $ hg st
 
--- a/tests/test-notify-changegroup.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-notify-changegroup.t	Tue Nov 22 18:16:59 2011 +0100
@@ -56,11 +56,11 @@
   Message-Id: <*> (glob)
   To: baz, foo@bar
   
-  changeset cb9a9f314b8b in $TESTTMP/a
+  changeset cb9a9f314b8b in $TESTTMP/a (glob)
   details: $TESTTMP/a?cmd=changeset;node=cb9a9f314b8b
   summary: a
   
-  changeset ba677d0156c1 in $TESTTMP/a
+  changeset ba677d0156c1 in $TESTTMP/a (glob)
   details: $TESTTMP/a?cmd=changeset;node=ba677d0156c1
   summary: b
   
@@ -107,11 +107,11 @@
   Message-Id: <*> (glob)
   To: baz, foo@bar
   
-  changeset cb9a9f314b8b in $TESTTMP/a
+  changeset cb9a9f314b8b in $TESTTMP/a (glob)
   details: $TESTTMP/a?cmd=changeset;node=cb9a9f314b8b
   summary: a
   
-  changeset ba677d0156c1 in $TESTTMP/a
+  changeset ba677d0156c1 in $TESTTMP/a (glob)
   details: $TESTTMP/a?cmd=changeset;node=ba677d0156c1
   summary: b
   
--- a/tests/test-notify.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-notify.t	Tue Nov 22 18:16:59 2011 +0100
@@ -173,7 +173,7 @@
   Message-Id: <*> (glob)
   To: baz, foo@bar
   
-  changeset 0647d048b600 in $TESTTMP/b
+  changeset 0647d048b600 in $TESTTMP/b (glob)
   details: $TESTTMP/b?cmd=changeset;node=0647d048b600
   description: b
   
--- a/tests/test-patchbomb.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-patchbomb.t	Tue Nov 22 18:16:59 2011 +0100
@@ -1,11 +1,5 @@
-  $ fixheaders()
-  > {
-  >     sed -e 's/\(Message-Id:.*@\).*/\1/'  \
-  >         -e 's/\(In-Reply-To:.*@\).*/\1/' \
-  >         -e 's/\(References:.*@\).*/\1/'  \
-  >         -e 's/\(User-Agent:.*\)\/.*/\1/'  \
-  >         -e 's/===.*/===/'
-  > }
+  $ "$TESTDIR/hghave" system-sh || exit 80
+
   $ echo "[extensions]" >> $HGRCPATH
   $ echo "patchbomb=" >> $HGRCPATH
 
@@ -25,7 +19,7 @@
   Content-Transfer-Encoding: 7bit
   Subject: [PATCH] a
   X-Mercurial-Node: 8580ff50825a50c8f716709acdf8de0deddcd6ab
-  Message-Id: <8580ff50825a50c8f716.60@* (glob)
+  Message-Id: <8580ff50825a50c8f716.60@*> (glob)
   User-Agent: Mercurial-patchbomb/* (glob)
   Date: Thu, 01 Jan 1970 00:01:00 +0000
   From: quux
@@ -80,7 +74,7 @@
   MIME-Version: 1.0
   Content-Transfer-Encoding: 7bit
   Subject: [PATCH 0 of 2] test
-  Message-Id: <patchbomb\.120@[^>]*> (re)
+  Message-Id: <patchbomb.120@*> (glob)
   User-Agent: Mercurial-patchbomb/* (glob)
   Date: Thu, 01 Jan 1970 00:02:00 +0000
   From: quux
@@ -94,9 +88,9 @@
   Content-Transfer-Encoding: 7bit
   Subject: [PATCH 1 of 2] a
   X-Mercurial-Node: 8580ff50825a50c8f716709acdf8de0deddcd6ab
-  Message-Id: <8580ff50825a50c8f716\.121@[^>]*> (re)
-  In-Reply-To: <patchbomb\.120@[^>]*> (re)
-  References: <patchbomb\.120@[^>]*> (re)
+  Message-Id: <8580ff50825a50c8f716.121@*> (glob)
+  In-Reply-To: <patchbomb.120@*> (glob)
+  References: <patchbomb.120@*> (glob)
   User-Agent: Mercurial-patchbomb/* (glob)
   Date: Thu, 01 Jan 1970 00:02:01 +0000
   From: quux
@@ -122,9 +116,9 @@
   Content-Transfer-Encoding: 7bit
   Subject: [PATCH 2 of 2] b
   X-Mercurial-Node: 97d72e5f12c7e84f85064aa72e5a297142c36ed9
-  Message-Id: <97d72e5f12c7e84f8506\.122@[^>]*> (re)
-  In-Reply-To: <patchbomb\.120@[^>]*> (re)
-  References: <patchbomb\.120@[^>]*> (re)
+  Message-Id: <97d72e5f12c7e84f8506.122@*> (glob)
+  In-Reply-To: <patchbomb.120@*> (glob)
+  References: <patchbomb.120@*> (glob)
   User-Agent: Mercurial-patchbomb/* (glob)
   Date: Thu, 01 Jan 1970 00:02:02 +0000
   From: quux
@@ -200,22 +194,22 @@
 
 test bundle and description:
   $ hg email --date '1970-1-1 0:3' -n -f quux -t foo \
-  >  -c bar -s test -r tip -b --desc description | fixheaders
+  >  -c bar -s test -r tip -b --desc description
   searching for changes
   1 changesets found
   
   Displaying test ...
-  Content-Type: multipart/mixed; boundary="===
+  Content-Type: multipart/mixed; boundary="===*" (glob)
   MIME-Version: 1.0
   Subject: test
-  Message-Id: <patchbomb.180@
-  User-Agent: Mercurial-patchbomb
+  Message-Id: <patchbomb.180@*> (glob)
+  User-Agent: Mercurial-patchbomb/* (glob)
   Date: Thu, 01 Jan 1970 00:03:00 +0000
   From: quux
   To: foo
   Cc: bar
   
-  --===
+  --===* (glob)
   Content-Type: text/plain; charset="us-ascii"
   MIME-Version: 1.0
   Content-Transfer-Encoding: 7bit
@@ -224,7 +218,7 @@
   
   description
   
-  --===
+  --===* (glob)
   Content-Type: application/x-mercurial-bundle
   MIME-Version: 1.0
   Content-Disposition: attachment; filename="bundle.hg"
@@ -237,86 +231,27 @@
   SlIBpFisgGkyRjX//TMtfcUAEsGu56+YnE1OlTZmzKm8BSu2rvo4rHAYYaadIFFuTy0LYgIkgLVD
   sgVa2F19D1tx9+hgbAygLgQwaIqcDdgA4BjQgIiz/AEP72++llgDKhKducqodGE4B0ETqF3JFOFC
   Q70eyNw=
-  --===
+  --===*-- (glob)
 
 utf-8 patch:
   $ python -c 'fp = open("utf", "wb"); fp.write("h\xC3\xB6mma!\n"); fp.close();'
-  $ hg commit -A -d '4 0' -m 'charset=utf-8; content-transfer-encoding: base64'
+  $ hg commit -A -d '4 0' -m 'utf-8 content'
   adding description
   adding utf
 
 no mime encoding for email --test:
-  $ hg email --date '1970-1-1 0:4' -f quux -t foo -c bar -r tip -n | fixheaders > mailtest
-
-md5sum of 8-bit output:
-  $ $TESTDIR/md5sum.py mailtest
-  e726c29b3008e77994c7572563e57c34  mailtest
-
-  $ rm mailtest
-
-mime encoded mbox (base64):
-  $ hg email --date '1970-1-1 0:4' -f quux -t foo -c bar -r tip -m mbox
+  $ hg email --date '1970-1-1 0:4' -f quux -t foo -c bar -r tip -n
   This patch series consists of 1 patches.
   
   
-  Writing [PATCH] charset=utf-8; content-transfer-encoding: base64 ...
-
-  $ cat mbox
-  From quux Thu Jan 01 00:04:01 1970
-  Content-Type: text/plain; charset="utf-8"
-  MIME-Version: 1.0
-  Content-Transfer-Encoding: base64
-  Subject: [PATCH] charset=utf-8; content-transfer-encoding: base64
-  X-Mercurial-Node: c3c9e37db9f4fe4882cda39baf42fed6bad8b15a
-  Message-Id: <c3c9e37db9f4fe4882cd.240@* (glob)
-  User-Agent: Mercurial-patchbomb/* (glob)
-  Date: Thu, 01 Jan 1970 00:04:00 +0000
-  From: quux
-  To: foo
-  Cc: bar
-  
-  IyBIRyBjaGFuZ2VzZXQgcGF0Y2gKIyBVc2VyIHRlc3QKIyBEYXRlIDQgMAojIE5vZGUgSUQgYzNj
-  OWUzN2RiOWY0ZmU0ODgyY2RhMzliYWY0MmZlZDZiYWQ4YjE1YQojIFBhcmVudCAgZmYyYzlmYTIw
-  MThiMTVmYTc0YjMzMzYzYmRhOTUyNzMyM2UyYTk5ZgpjaGFyc2V0PXV0Zi04OyBjb250ZW50LXRy
-  YW5zZmVyLWVuY29kaW5nOiBiYXNlNjQKCmRpZmYgLXIgZmYyYzlmYTIwMThiIC1yIGMzYzllMzdk
-  YjlmNCBkZXNjcmlwdGlvbgotLS0gL2Rldi9udWxsCVRodSBKYW4gMDEgMDA6MDA6MDAgMTk3MCAr
-  MDAwMAorKysgYi9kZXNjcmlwdGlvbglUaHUgSmFuIDAxIDAwOjAwOjA0IDE5NzAgKzAwMDAKQEAg
-  LTAsMCArMSwzIEBACithIG11bHRpbGluZQorCitkZXNjcmlwdGlvbgpkaWZmIC1yIGZmMmM5ZmEy
-  MDE4YiAtciBjM2M5ZTM3ZGI5ZjQgdXRmCi0tLSAvZGV2L251bGwJVGh1IEphbiAwMSAwMDowMDow
-  MCAxOTcwICswMDAwCisrKyBiL3V0ZglUaHUgSmFuIDAxIDAwOjAwOjA0IDE5NzAgKzAwMDAKQEAg
-  LTAsMCArMSwxIEBACitow7ZtbWEhCg==
-  
-  
-  $ rm mbox
-
-mime encoded mbox (quoted-printable):
-  $ python -c 'fp = open("qp", "wb"); fp.write("%s\nfoo\n\nbar\n" % ("x" * 1024)); fp.close();'
-  $ hg commit -A -d '4 0' -m 'charset=utf-8; content-transfer-encoding: quoted-printable'
-  adding qp
-
-no mime encoding for email --test:
-  $ hg email --date '1970-1-1 0:4' -f quux -t foo -c bar -r tip -n | \
-  >  fixheaders > mailtest
-md5sum of qp output:
-  $ $TESTDIR/md5sum.py mailtest
-  0402c7d033e04044e423bb04816f9dae  mailtest
-  $ rm mailtest
-
-mime encoded mbox (quoted-printable):
-  $ hg email --date '1970-1-1 0:4' -f quux -t foo -c bar -r tip -m mbox
-  This patch series consists of 1 patches.
-  
-  
-  Writing [PATCH] charset=utf-8; content-transfer-encoding: quoted-printable ...
-  $ cat mbox | fixheaders
-  From quux Thu Jan 01 00:04:01 1970
+  Displaying [PATCH] utf-8 content ...
   Content-Type: text/plain; charset="us-ascii"
   MIME-Version: 1.0
-  Content-Transfer-Encoding: quoted-printable
-  Subject: [PATCH] charset=utf-8; content-transfer-encoding: quoted-printable
-  X-Mercurial-Node: c655633f8c87700bb38cc6a59a2753bdc5a6c376
-  Message-Id: <c655633f8c87700bb38c.240@
-  User-Agent: Mercurial-patchbomb
+  Content-Transfer-Encoding: 8bit
+  Subject: [PATCH] utf-8 content
+  X-Mercurial-Node: 909a00e13e9d78b575aeee23dddbada46d5a143f
+  Message-Id: <909a00e13e9d78b575ae.240@*> (glob)
+  User-Agent: Mercurial-patchbomb/* (glob)
   Date: Thu, 01 Jan 1970 00:04:00 +0000
   From: quux
   To: foo
@@ -325,13 +260,162 @@
   # HG changeset patch
   # User test
   # Date 4 0
-  # Node ID c655633f8c87700bb38cc6a59a2753bdc5a6c376
-  # Parent  c3c9e37db9f4fe4882cda39baf42fed6bad8b15a
-  charset=3Dutf-8; content-transfer-encoding: quoted-printable
+  # Node ID 909a00e13e9d78b575aeee23dddbada46d5a143f
+  # Parent  ff2c9fa2018b15fa74b33363bda9527323e2a99f
+  utf-8 content
+  
+  diff -r ff2c9fa2018b -r 909a00e13e9d description
+  --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+  +++ b/description	Thu Jan 01 00:00:04 1970 +0000
+  @@ -0,0 +1,3 @@
+  +a multiline
+  +
+  +description
+  diff -r ff2c9fa2018b -r 909a00e13e9d utf
+  --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+  +++ b/utf	Thu Jan 01 00:00:04 1970 +0000
+  @@ -0,0 +1,1 @@
+  +h\xc3\xb6mma! (esc)
+  
+
+mime encoded mbox (base64):
+  $ hg email --date '1970-1-1 0:4' -f quux -t foo -c bar -r tip -m mbox
+  This patch series consists of 1 patches.
+  
+  
+  Writing [PATCH] utf-8 content ...
+
+  $ cat mbox
+  From quux Thu Jan 01 00:04:01 1970
+  Content-Type: text/plain; charset="utf-8"
+  MIME-Version: 1.0
+  Content-Transfer-Encoding: base64
+  Subject: [PATCH] utf-8 content
+  X-Mercurial-Node: 909a00e13e9d78b575aeee23dddbada46d5a143f
+  Message-Id: <909a00e13e9d78b575ae.240@*> (glob)
+  User-Agent: Mercurial-patchbomb/* (glob)
+  Date: Thu, 01 Jan 1970 00:04:00 +0000
+  From: quux
+  To: foo
+  Cc: bar
+  
+  IyBIRyBjaGFuZ2VzZXQgcGF0Y2gKIyBVc2VyIHRlc3QKIyBEYXRlIDQgMAojIE5vZGUgSUQgOTA5
+  YTAwZTEzZTlkNzhiNTc1YWVlZTIzZGRkYmFkYTQ2ZDVhMTQzZgojIFBhcmVudCAgZmYyYzlmYTIw
+  MThiMTVmYTc0YjMzMzYzYmRhOTUyNzMyM2UyYTk5Zgp1dGYtOCBjb250ZW50CgpkaWZmIC1yIGZm
+  MmM5ZmEyMDE4YiAtciA5MDlhMDBlMTNlOWQgZGVzY3JpcHRpb24KLS0tIC9kZXYvbnVsbAlUaHUg
+  SmFuIDAxIDAwOjAwOjAwIDE5NzAgKzAwMDAKKysrIGIvZGVzY3JpcHRpb24JVGh1IEphbiAwMSAw
+  MDowMDowNCAxOTcwICswMDAwCkBAIC0wLDAgKzEsMyBAQAorYSBtdWx0aWxpbmUKKworZGVzY3Jp
+  cHRpb24KZGlmZiAtciBmZjJjOWZhMjAxOGIgLXIgOTA5YTAwZTEzZTlkIHV0ZgotLS0gL2Rldi9u
+  dWxsCVRodSBKYW4gMDEgMDA6MDA6MDAgMTk3MCArMDAwMAorKysgYi91dGYJVGh1IEphbiAwMSAw
+  MDowMDowNCAxOTcwICswMDAwCkBAIC0wLDAgKzEsMSBAQAoraMO2bW1hIQo=
+  
+  
+  $ python -c 'print open("mbox").read().split("\n\n")[1].decode("base64")'
+  # HG changeset patch
+  # User test
+  # Date 4 0
+  # Node ID 909a00e13e9d78b575aeee23dddbada46d5a143f
+  # Parent  ff2c9fa2018b15fa74b33363bda9527323e2a99f
+  utf-8 content
+  
+  diff -r ff2c9fa2018b -r 909a00e13e9d description
+  --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+  +++ b/description	Thu Jan 01 00:00:04 1970 +0000
+  @@ -0,0 +1,3 @@
+  +a multiline
+  +
+  +description
+  diff -r ff2c9fa2018b -r 909a00e13e9d utf
+  --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+  +++ b/utf	Thu Jan 01 00:00:04 1970 +0000
+  @@ -0,0 +1,1 @@
+  +h\xc3\xb6mma! (esc)
   
-  diff -r c3c9e37db9f4 -r c655633f8c87 qp
+  $ rm mbox
+
+mime encoded mbox (quoted-printable):
+  $ python -c 'fp = open("long", "wb"); fp.write("%s\nfoo\n\nbar\n" % ("x" * 1024)); fp.close();'
+  $ hg commit -A -d '4 0' -m 'long line'
+  adding long
+
+no mime encoding for email --test:
+  $ hg email --date '1970-1-1 0:4' -f quux -t foo -c bar -r tip -n
+  This patch series consists of 1 patches.
+  
+  
+  Displaying [PATCH] long line ...
+  Content-Type: text/plain; charset="us-ascii"
+  MIME-Version: 1.0
+  Content-Transfer-Encoding: quoted-printable
+  Subject: [PATCH] long line
+  X-Mercurial-Node: a2ea8fc83dd8b93cfd86ac97b28287204ab806e1
+  Message-Id: <a2ea8fc83dd8b93cfd86.240@*> (glob)
+  User-Agent: Mercurial-patchbomb/* (glob)
+  Date: Thu, 01 Jan 1970 00:04:00 +0000
+  From: quux
+  To: foo
+  Cc: bar
+  
+  # HG changeset patch
+  # User test
+  # Date 4 0
+  # Node ID a2ea8fc83dd8b93cfd86ac97b28287204ab806e1
+  # Parent  909a00e13e9d78b575aeee23dddbada46d5a143f
+  long line
+  
+  diff -r 909a00e13e9d -r a2ea8fc83dd8 long
   --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
-  +++ b/qp	Thu Jan 01 00:00:04 1970 +0000
+  +++ b/long	Thu Jan 01 00:00:04 1970 +0000
+  @@ -0,0 +1,4 @@
+  +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
+  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
+  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
+  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
+  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
+  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
+  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
+  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
+  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
+  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
+  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
+  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
+  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
+  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+  +foo
+  +
+  +bar
+  
+
+mime encoded mbox (quoted-printable):
+  $ hg email --date '1970-1-1 0:4' -f quux -t foo -c bar -r tip -m mbox
+  This patch series consists of 1 patches.
+  
+  
+  Writing [PATCH] long line ...
+  $ cat mbox
+  From quux Thu Jan 01 00:04:01 1970
+  Content-Type: text/plain; charset="us-ascii"
+  MIME-Version: 1.0
+  Content-Transfer-Encoding: quoted-printable
+  Subject: [PATCH] long line
+  X-Mercurial-Node: a2ea8fc83dd8b93cfd86ac97b28287204ab806e1
+  Message-Id: <a2ea8fc83dd8b93cfd86.240@*> (glob)
+  User-Agent: Mercurial-patchbomb/* (glob)
+  Date: Thu, 01 Jan 1970 00:04:00 +0000
+  From: quux
+  To: foo
+  Cc: bar
+  
+  # HG changeset patch
+  # User test
+  # Date 4 0
+  # Node ID a2ea8fc83dd8b93cfd86ac97b28287204ab806e1
+  # Parent  909a00e13e9d78b575aeee23dddbada46d5a143f
+  long line
+  
+  diff -r 909a00e13e9d -r a2ea8fc83dd8 long
+  --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+  +++ b/long	Thu Jan 01 00:00:04 1970 +0000
   @@ -0,0 +1,4 @@
   +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
   xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
@@ -357,7 +441,7 @@
 
 iso-8859-1 patch:
   $ python -c 'fp = open("isolatin", "wb"); fp.write("h\xF6mma!\n"); fp.close();'
-  $ hg commit -A -d '5 0' -m 'charset=us-ascii; content-transfer-encoding: 8bit'
+  $ hg commit -A -d '5 0' -m 'isolatin 8-bit encoding'
   adding isolatin
 
 fake ascii mbox:
@@ -365,16 +449,38 @@
   This patch series consists of 1 patches.
   
   
-  Writing [PATCH] charset=us-ascii; content-transfer-encoding: 8bit ...
-  $ fixheaders < mbox > mboxfix
-
-md5sum of 8-bit output:
-  $ $TESTDIR/md5sum.py mboxfix
-  9ea043d8fc43a71045114508baed144b  mboxfix
+  Writing [PATCH] isolatin 8-bit encoding ...
+  $ cat mbox
+  From quux Thu Jan 01 00:05:01 1970
+  Content-Type: text/plain; charset="us-ascii"
+  MIME-Version: 1.0
+  Content-Transfer-Encoding: 8bit
+  Subject: [PATCH] isolatin 8-bit encoding
+  X-Mercurial-Node: 240fb913fc1b7ff15ddb9f33e73d82bf5277c720
+  Message-Id: <240fb913fc1b7ff15ddb.300@*> (glob)
+  User-Agent: Mercurial-patchbomb/* (glob)
+  Date: Thu, 01 Jan 1970 00:05:00 +0000
+  From: quux
+  To: foo
+  Cc: bar
+  
+  # HG changeset patch
+  # User test
+  # Date 5 0
+  # Node ID 240fb913fc1b7ff15ddb9f33e73d82bf5277c720
+  # Parent  a2ea8fc83dd8b93cfd86ac97b28287204ab806e1
+  isolatin 8-bit encoding
+  
+  diff -r a2ea8fc83dd8 -r 240fb913fc1b isolatin
+  --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+  +++ b/isolatin	Thu Jan 01 00:00:05 1970 +0000
+  @@ -0,0 +1,1 @@
+  +h\xf6mma! (esc)
+  
+  
 
 test diffstat for single patch:
-  $ hg email --date '1970-1-1 0:1' -n -f quux -t foo -c bar -s test -d -y -r 2 | \
-  >  fixheaders
+  $ hg email --date '1970-1-1 0:1' -n -f quux -t foo -c bar -s test -d -y -r 2
   This patch series consists of 1 patches.
   
   
@@ -395,8 +501,8 @@
   Content-Transfer-Encoding: 7bit
   Subject: [PATCH] test
   X-Mercurial-Node: ff2c9fa2018b15fa74b33363bda9527323e2a99f
-  Message-Id: <ff2c9fa2018b15fa74b3.60@
-  User-Agent: Mercurial-patchbomb
+  Message-Id: <ff2c9fa2018b15fa74b3.60@*> (glob)
+  User-Agent: Mercurial-patchbomb/* (glob)
   Date: Thu, 01 Jan 1970 00:01:00 +0000
   From: quux
   To: foo
@@ -422,7 +528,7 @@
 
 test diffstat for multiple patches:
   $ hg email --date '1970-1-1 0:1' -n -f quux -t foo -c bar -s test -d -y \
-  >  -r 0:1 | fixheaders
+  >  -r 0:1
   This patch series consists of 2 patches.
   
   
@@ -452,8 +558,8 @@
   MIME-Version: 1.0
   Content-Transfer-Encoding: 7bit
   Subject: [PATCH 0 of 2] test
-  Message-Id: <patchbomb.60@
-  User-Agent: Mercurial-patchbomb
+  Message-Id: <patchbomb.60@*> (glob)
+  User-Agent: Mercurial-patchbomb/* (glob)
   Date: Thu, 01 Jan 1970 00:01:00 +0000
   From: quux
   To: foo
@@ -470,10 +576,10 @@
   Content-Transfer-Encoding: 7bit
   Subject: [PATCH 1 of 2] a
   X-Mercurial-Node: 8580ff50825a50c8f716709acdf8de0deddcd6ab
-  Message-Id: <8580ff50825a50c8f716.61@
-  In-Reply-To: <patchbomb.60@
-  References: <patchbomb.60@
-  User-Agent: Mercurial-patchbomb
+  Message-Id: <8580ff50825a50c8f716.61@*> (glob)
+  In-Reply-To: <patchbomb.60@*> (glob)
+  References: <patchbomb.60@*> (glob)
+  User-Agent: Mercurial-patchbomb/* (glob)
   Date: Thu, 01 Jan 1970 00:01:01 +0000
   From: quux
   To: foo
@@ -502,10 +608,10 @@
   Content-Transfer-Encoding: 7bit
   Subject: [PATCH 2 of 2] b
   X-Mercurial-Node: 97d72e5f12c7e84f85064aa72e5a297142c36ed9
-  Message-Id: <97d72e5f12c7e84f8506.62@
-  In-Reply-To: <patchbomb.60@
-  References: <patchbomb.60@
-  User-Agent: Mercurial-patchbomb
+  Message-Id: <97d72e5f12c7e84f8506.62@*> (glob)
+  In-Reply-To: <patchbomb.60@*> (glob)
+  References: <patchbomb.60@*> (glob)
+  User-Agent: Mercurial-patchbomb/* (glob)
   Date: Thu, 01 Jan 1970 00:01:02 +0000
   From: quux
   To: foo
@@ -530,24 +636,23 @@
   
 
 test inline for single patch:
-  $ hg email --date '1970-1-1 0:1' -n -f quux -t foo -c bar -s test -i -r 2 | \
-  >  fixheaders
+  $ hg email --date '1970-1-1 0:1' -n -f quux -t foo -c bar -s test -i -r 2
   This patch series consists of 1 patches.
   
   
   Displaying [PATCH] test ...
-  Content-Type: multipart/mixed; boundary="===
+  Content-Type: multipart/mixed; boundary="===*" (glob)
   MIME-Version: 1.0
   Subject: [PATCH] test
   X-Mercurial-Node: ff2c9fa2018b15fa74b33363bda9527323e2a99f
-  Message-Id: <ff2c9fa2018b15fa74b3.60@
-  User-Agent: Mercurial-patchbomb
+  Message-Id: <ff2c9fa2018b15fa74b3.60@*> (glob)
+  User-Agent: Mercurial-patchbomb/* (glob)
   Date: Thu, 01 Jan 1970 00:01:00 +0000
   From: quux
   To: foo
   Cc: bar
   
-  --===
+  --===* (glob)
   Content-Type: text/x-patch; charset="us-ascii"
   MIME-Version: 1.0
   Content-Transfer-Encoding: 7bit
@@ -566,28 +671,27 @@
   @@ -0,0 +1,1 @@
   +c
   
-  --===
+  --===*-- (glob)
 
 
 test inline for single patch (quoted-printable):
-  $ hg email --date '1970-1-1 0:1' -n -f quux -t foo -c bar -s test -i -r 4 | \
-  >  fixheaders
+  $ hg email --date '1970-1-1 0:1' -n -f quux -t foo -c bar -s test -i -r 4
   This patch series consists of 1 patches.
   
   
   Displaying [PATCH] test ...
-  Content-Type: multipart/mixed; boundary="===
+  Content-Type: multipart/mixed; boundary="===*" (glob)
   MIME-Version: 1.0
   Subject: [PATCH] test
-  X-Mercurial-Node: c655633f8c87700bb38cc6a59a2753bdc5a6c376
-  Message-Id: <c655633f8c87700bb38c.60@
-  User-Agent: Mercurial-patchbomb
+  X-Mercurial-Node: a2ea8fc83dd8b93cfd86ac97b28287204ab806e1
+  Message-Id: <a2ea8fc83dd8b93cfd86.60@*> (glob)
+  User-Agent: Mercurial-patchbomb/* (glob)
   Date: Thu, 01 Jan 1970 00:01:00 +0000
   From: quux
   To: foo
   Cc: bar
   
-  --===
+  --===* (glob)
   Content-Type: text/x-patch; charset="us-ascii"
   MIME-Version: 1.0
   Content-Transfer-Encoding: quoted-printable
@@ -596,13 +700,13 @@
   # HG changeset patch
   # User test
   # Date 4 0
-  # Node ID c655633f8c87700bb38cc6a59a2753bdc5a6c376
-  # Parent  c3c9e37db9f4fe4882cda39baf42fed6bad8b15a
-  charset=3Dutf-8; content-transfer-encoding: quoted-printable
+  # Node ID a2ea8fc83dd8b93cfd86ac97b28287204ab806e1
+  # Parent  909a00e13e9d78b575aeee23dddbada46d5a143f
+  long line
   
-  diff -r c3c9e37db9f4 -r c655633f8c87 qp
+  diff -r 909a00e13e9d -r a2ea8fc83dd8 long
   --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
-  +++ b/qp	Thu Jan 01 00:00:04 1970 +0000
+  +++ b/long	Thu Jan 01 00:00:04 1970 +0000
   @@ -0,0 +1,4 @@
   +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
   xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
@@ -622,11 +726,11 @@
   +
   +bar
   
-  --===
+  --===*-- (glob)
 
 test inline for multiple patches:
   $ hg email --date '1970-1-1 0:1' -n -f quux -t foo -c bar -s test -i \
-  >  -r 0:1 -r 4 | fixheaders
+  >  -r 0:1 -r 4
   This patch series consists of 3 patches.
   
   
@@ -638,8 +742,8 @@
   MIME-Version: 1.0
   Content-Transfer-Encoding: 7bit
   Subject: [PATCH 0 of 3] test
-  Message-Id: <patchbomb.60@
-  User-Agent: Mercurial-patchbomb
+  Message-Id: <patchbomb.60@*> (glob)
+  User-Agent: Mercurial-patchbomb/* (glob)
   Date: Thu, 01 Jan 1970 00:01:00 +0000
   From: quux
   To: foo
@@ -647,20 +751,20 @@
   
   
   Displaying [PATCH 1 of 3] a ...
-  Content-Type: multipart/mixed; boundary="===
+  Content-Type: multipart/mixed; boundary="===*" (glob)
   MIME-Version: 1.0
   Subject: [PATCH 1 of 3] a
   X-Mercurial-Node: 8580ff50825a50c8f716709acdf8de0deddcd6ab
-  Message-Id: <8580ff50825a50c8f716.61@
-  In-Reply-To: <patchbomb.60@
-  References: <patchbomb.60@
-  User-Agent: Mercurial-patchbomb
+  Message-Id: <8580ff50825a50c8f716.61@*> (glob)
+  In-Reply-To: <patchbomb.60@*> (glob)
+  References: <patchbomb.60@*> (glob)
+  User-Agent: Mercurial-patchbomb/* (glob)
   Date: Thu, 01 Jan 1970 00:01:01 +0000
   From: quux
   To: foo
   Cc: bar
   
-  --===
+  --===* (glob)
   Content-Type: text/x-patch; charset="us-ascii"
   MIME-Version: 1.0
   Content-Transfer-Encoding: 7bit
@@ -679,22 +783,22 @@
   @@ -0,0 +1,1 @@
   +a
   
-  --===
+  --===*-- (glob)
   Displaying [PATCH 2 of 3] b ...
-  Content-Type: multipart/mixed; boundary="===
+  Content-Type: multipart/mixed; boundary="===*" (glob)
   MIME-Version: 1.0
   Subject: [PATCH 2 of 3] b
   X-Mercurial-Node: 97d72e5f12c7e84f85064aa72e5a297142c36ed9
-  Message-Id: <97d72e5f12c7e84f8506.62@
-  In-Reply-To: <patchbomb.60@
-  References: <patchbomb.60@
-  User-Agent: Mercurial-patchbomb
+  Message-Id: <97d72e5f12c7e84f8506.62@*> (glob)
+  In-Reply-To: <patchbomb.60@*> (glob)
+  References: <patchbomb.60@*> (glob)
+  User-Agent: Mercurial-patchbomb/* (glob)
   Date: Thu, 01 Jan 1970 00:01:02 +0000
   From: quux
   To: foo
   Cc: bar
   
-  --===
+  --===* (glob)
   Content-Type: text/x-patch; charset="us-ascii"
   MIME-Version: 1.0
   Content-Transfer-Encoding: 7bit
@@ -713,23 +817,22 @@
   @@ -0,0 +1,1 @@
   +b
   
-  --===
-  Displaying [PATCH 3 of 3] charset=utf-8; content-transfer-encoding: quoted-printable ...
-  Content-Type: multipart/mixed; boundary="===
+  --===*-- (glob)
+  Displaying [PATCH 3 of 3] long line ...
+  Content-Type: multipart/mixed; boundary="===*" (glob)
   MIME-Version: 1.0
-  Subject: [PATCH 3 of 3] charset=utf-8;
-   content-transfer-encoding: quoted-printable
-  X-Mercurial-Node: c655633f8c87700bb38cc6a59a2753bdc5a6c376
-  Message-Id: <c655633f8c87700bb38c.63@
-  In-Reply-To: <patchbomb.60@
-  References: <patchbomb.60@
-  User-Agent: Mercurial-patchbomb
+  Subject: [PATCH 3 of 3] long line
+  X-Mercurial-Node: a2ea8fc83dd8b93cfd86ac97b28287204ab806e1
+  Message-Id: <a2ea8fc83dd8b93cfd86.63@*> (glob)
+  In-Reply-To: <patchbomb.60@*> (glob)
+  References: <patchbomb.60@*> (glob)
+  User-Agent: Mercurial-patchbomb/* (glob)
   Date: Thu, 01 Jan 1970 00:01:03 +0000
   From: quux
   To: foo
   Cc: bar
   
-  --===
+  --===* (glob)
   Content-Type: text/x-patch; charset="us-ascii"
   MIME-Version: 1.0
   Content-Transfer-Encoding: quoted-printable
@@ -738,13 +841,13 @@
   # HG changeset patch
   # User test
   # Date 4 0
-  # Node ID c655633f8c87700bb38cc6a59a2753bdc5a6c376
-  # Parent  c3c9e37db9f4fe4882cda39baf42fed6bad8b15a
-  charset=3Dutf-8; content-transfer-encoding: quoted-printable
+  # Node ID a2ea8fc83dd8b93cfd86ac97b28287204ab806e1
+  # Parent  909a00e13e9d78b575aeee23dddbada46d5a143f
+  long line
   
-  diff -r c3c9e37db9f4 -r c655633f8c87 qp
+  diff -r 909a00e13e9d -r a2ea8fc83dd8 long
   --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
-  +++ b/qp	Thu Jan 01 00:00:04 1970 +0000
+  +++ b/long	Thu Jan 01 00:00:04 1970 +0000
   @@ -0,0 +1,4 @@
   +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
   xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
@@ -764,27 +867,26 @@
   +
   +bar
   
-  --===
+  --===*-- (glob)
 
 test attach for single patch:
-  $ hg email --date '1970-1-1 0:1' -n -f quux -t foo -c bar -s test -a -r 2 | \
-  >  fixheaders
+  $ hg email --date '1970-1-1 0:1' -n -f quux -t foo -c bar -s test -a -r 2
   This patch series consists of 1 patches.
   
   
   Displaying [PATCH] test ...
-  Content-Type: multipart/mixed; boundary="===
+  Content-Type: multipart/mixed; boundary="===*" (glob)
   MIME-Version: 1.0
   Subject: [PATCH] test
   X-Mercurial-Node: ff2c9fa2018b15fa74b33363bda9527323e2a99f
-  Message-Id: <ff2c9fa2018b15fa74b3.60@
-  User-Agent: Mercurial-patchbomb
+  Message-Id: <ff2c9fa2018b15fa74b3.60@*> (glob)
+  User-Agent: Mercurial-patchbomb/* (glob)
   Date: Thu, 01 Jan 1970 00:01:00 +0000
   From: quux
   To: foo
   Cc: bar
   
-  --===
+  --===* (glob)
   Content-Type: text/plain; charset="us-ascii"
   MIME-Version: 1.0
   Content-Transfer-Encoding: 7bit
@@ -793,7 +895,7 @@
   
   
   
-  --===
+  --===* (glob)
   Content-Type: text/x-patch; charset="us-ascii"
   MIME-Version: 1.0
   Content-Transfer-Encoding: 7bit
@@ -812,27 +914,26 @@
   @@ -0,0 +1,1 @@
   +c
   
-  --===
+  --===*-- (glob)
 
 test attach for single patch (quoted-printable):
-  $ hg email --date '1970-1-1 0:1' -n -f quux -t foo -c bar -s test -a -r 4 | \
-  >  fixheaders
+  $ hg email --date '1970-1-1 0:1' -n -f quux -t foo -c bar -s test -a -r 4
   This patch series consists of 1 patches.
   
   
   Displaying [PATCH] test ...
-  Content-Type: multipart/mixed; boundary="===
+  Content-Type: multipart/mixed; boundary="===*" (glob)
   MIME-Version: 1.0
   Subject: [PATCH] test
-  X-Mercurial-Node: c655633f8c87700bb38cc6a59a2753bdc5a6c376
-  Message-Id: <c655633f8c87700bb38c.60@
-  User-Agent: Mercurial-patchbomb
+  X-Mercurial-Node: a2ea8fc83dd8b93cfd86ac97b28287204ab806e1
+  Message-Id: <a2ea8fc83dd8b93cfd86.60@*> (glob)
+  User-Agent: Mercurial-patchbomb/* (glob)
   Date: Thu, 01 Jan 1970 00:01:00 +0000
   From: quux
   To: foo
   Cc: bar
   
-  --===
+  --===* (glob)
   Content-Type: text/plain; charset="us-ascii"
   MIME-Version: 1.0
   Content-Transfer-Encoding: 7bit
@@ -841,7 +942,7 @@
   
   
   
-  --===
+  --===* (glob)
   Content-Type: text/x-patch; charset="us-ascii"
   MIME-Version: 1.0
   Content-Transfer-Encoding: quoted-printable
@@ -850,13 +951,13 @@
   # HG changeset patch
   # User test
   # Date 4 0
-  # Node ID c655633f8c87700bb38cc6a59a2753bdc5a6c376
-  # Parent  c3c9e37db9f4fe4882cda39baf42fed6bad8b15a
-  charset=3Dutf-8; content-transfer-encoding: quoted-printable
+  # Node ID a2ea8fc83dd8b93cfd86ac97b28287204ab806e1
+  # Parent  909a00e13e9d78b575aeee23dddbada46d5a143f
+  long line
   
-  diff -r c3c9e37db9f4 -r c655633f8c87 qp
+  diff -r 909a00e13e9d -r a2ea8fc83dd8 long
   --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
-  +++ b/qp	Thu Jan 01 00:00:04 1970 +0000
+  +++ b/long	Thu Jan 01 00:00:04 1970 +0000
   @@ -0,0 +1,4 @@
   +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
   xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
@@ -876,11 +977,11 @@
   +
   +bar
   
-  --===
+  --===*-- (glob)
 
 test attach for multiple patches:
   $ hg email --date '1970-1-1 0:1' -n -f quux -t foo -c bar -s test -a \
-  >  -r 0:1 -r 4 | fixheaders
+  >  -r 0:1 -r 4
   This patch series consists of 3 patches.
   
   
@@ -892,8 +993,8 @@
   MIME-Version: 1.0
   Content-Transfer-Encoding: 7bit
   Subject: [PATCH 0 of 3] test
-  Message-Id: <patchbomb.60@
-  User-Agent: Mercurial-patchbomb
+  Message-Id: <patchbomb.60@*> (glob)
+  User-Agent: Mercurial-patchbomb/* (glob)
   Date: Thu, 01 Jan 1970 00:01:00 +0000
   From: quux
   To: foo
@@ -901,20 +1002,20 @@
   
   
   Displaying [PATCH 1 of 3] a ...
-  Content-Type: multipart/mixed; boundary="===
+  Content-Type: multipart/mixed; boundary="===*" (glob)
   MIME-Version: 1.0
   Subject: [PATCH 1 of 3] a
   X-Mercurial-Node: 8580ff50825a50c8f716709acdf8de0deddcd6ab
-  Message-Id: <8580ff50825a50c8f716.61@
-  In-Reply-To: <patchbomb.60@
-  References: <patchbomb.60@
-  User-Agent: Mercurial-patchbomb
+  Message-Id: <8580ff50825a50c8f716.61@*> (glob)
+  In-Reply-To: <patchbomb.60@*> (glob)
+  References: <patchbomb.60@*> (glob)
+  User-Agent: Mercurial-patchbomb/* (glob)
   Date: Thu, 01 Jan 1970 00:01:01 +0000
   From: quux
   To: foo
   Cc: bar
   
-  --===
+  --===* (glob)
   Content-Type: text/plain; charset="us-ascii"
   MIME-Version: 1.0
   Content-Transfer-Encoding: 7bit
@@ -923,7 +1024,7 @@
   
   
   
-  --===
+  --===* (glob)
   Content-Type: text/x-patch; charset="us-ascii"
   MIME-Version: 1.0
   Content-Transfer-Encoding: 7bit
@@ -942,22 +1043,22 @@
   @@ -0,0 +1,1 @@
   +a
   
-  --===
+  --===*-- (glob)
   Displaying [PATCH 2 of 3] b ...
-  Content-Type: multipart/mixed; boundary="===
+  Content-Type: multipart/mixed; boundary="===*" (glob)
   MIME-Version: 1.0
   Subject: [PATCH 2 of 3] b
   X-Mercurial-Node: 97d72e5f12c7e84f85064aa72e5a297142c36ed9
-  Message-Id: <97d72e5f12c7e84f8506.62@
-  In-Reply-To: <patchbomb.60@
-  References: <patchbomb.60@
-  User-Agent: Mercurial-patchbomb
+  Message-Id: <97d72e5f12c7e84f8506.62@*> (glob)
+  In-Reply-To: <patchbomb.60@*> (glob)
+  References: <patchbomb.60@*> (glob)
+  User-Agent: Mercurial-patchbomb/* (glob)
   Date: Thu, 01 Jan 1970 00:01:02 +0000
   From: quux
   To: foo
   Cc: bar
   
-  --===
+  --===* (glob)
   Content-Type: text/plain; charset="us-ascii"
   MIME-Version: 1.0
   Content-Transfer-Encoding: 7bit
@@ -966,7 +1067,7 @@
   
   
   
-  --===
+  --===* (glob)
   Content-Type: text/x-patch; charset="us-ascii"
   MIME-Version: 1.0
   Content-Transfer-Encoding: 7bit
@@ -985,23 +1086,22 @@
   @@ -0,0 +1,1 @@
   +b
   
-  --===
-  Displaying [PATCH 3 of 3] charset=utf-8; content-transfer-encoding: quoted-printable ...
-  Content-Type: multipart/mixed; boundary="===
+  --===*-- (glob)
+  Displaying [PATCH 3 of 3] long line ...
+  Content-Type: multipart/mixed; boundary="===*" (glob)
   MIME-Version: 1.0
-  Subject: [PATCH 3 of 3] charset=utf-8;
-   content-transfer-encoding: quoted-printable
-  X-Mercurial-Node: c655633f8c87700bb38cc6a59a2753bdc5a6c376
-  Message-Id: <c655633f8c87700bb38c.63@
-  In-Reply-To: <patchbomb.60@
-  References: <patchbomb.60@
-  User-Agent: Mercurial-patchbomb
+  Subject: [PATCH 3 of 3] long line
+  X-Mercurial-Node: a2ea8fc83dd8b93cfd86ac97b28287204ab806e1
+  Message-Id: <a2ea8fc83dd8b93cfd86.63@*> (glob)
+  In-Reply-To: <patchbomb.60@*> (glob)
+  References: <patchbomb.60@*> (glob)
+  User-Agent: Mercurial-patchbomb/* (glob)
   Date: Thu, 01 Jan 1970 00:01:03 +0000
   From: quux
   To: foo
   Cc: bar
   
-  --===
+  --===* (glob)
   Content-Type: text/plain; charset="us-ascii"
   MIME-Version: 1.0
   Content-Transfer-Encoding: 7bit
@@ -1010,7 +1110,7 @@
   
   
   
-  --===
+  --===* (glob)
   Content-Type: text/x-patch; charset="us-ascii"
   MIME-Version: 1.0
   Content-Transfer-Encoding: quoted-printable
@@ -1019,13 +1119,13 @@
   # HG changeset patch
   # User test
   # Date 4 0
-  # Node ID c655633f8c87700bb38cc6a59a2753bdc5a6c376
-  # Parent  c3c9e37db9f4fe4882cda39baf42fed6bad8b15a
-  charset=3Dutf-8; content-transfer-encoding: quoted-printable
+  # Node ID a2ea8fc83dd8b93cfd86ac97b28287204ab806e1
+  # Parent  909a00e13e9d78b575aeee23dddbada46d5a143f
+  long line
   
-  diff -r c3c9e37db9f4 -r c655633f8c87 qp
+  diff -r 909a00e13e9d -r a2ea8fc83dd8 long
   --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
-  +++ b/qp	Thu Jan 01 00:00:04 1970 +0000
+  +++ b/long	Thu Jan 01 00:00:04 1970 +0000
   @@ -0,0 +1,4 @@
   +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
   xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
@@ -1045,11 +1145,11 @@
   +
   +bar
   
-  --===
+  --===*-- (glob)
 
 test intro for single patch:
   $ hg email --date '1970-1-1 0:1' -n --intro -f quux -t foo -c bar -s test \
-  >  -r 2 | fixheaders
+  >  -r 2
   This patch series consists of 1 patches.
   
   
@@ -1061,8 +1161,8 @@
   MIME-Version: 1.0
   Content-Transfer-Encoding: 7bit
   Subject: [PATCH 0 of 1] test
-  Message-Id: <patchbomb.60@
-  User-Agent: Mercurial-patchbomb
+  Message-Id: <patchbomb.60@*> (glob)
+  User-Agent: Mercurial-patchbomb/* (glob)
   Date: Thu, 01 Jan 1970 00:01:00 +0000
   From: quux
   To: foo
@@ -1075,10 +1175,10 @@
   Content-Transfer-Encoding: 7bit
   Subject: [PATCH 1 of 1] c
   X-Mercurial-Node: ff2c9fa2018b15fa74b33363bda9527323e2a99f
-  Message-Id: <ff2c9fa2018b15fa74b3.61@
-  In-Reply-To: <patchbomb.60@
-  References: <patchbomb.60@
-  User-Agent: Mercurial-patchbomb
+  Message-Id: <ff2c9fa2018b15fa74b3.61@*> (glob)
+  In-Reply-To: <patchbomb.60@*> (glob)
+  References: <patchbomb.60@*> (glob)
+  User-Agent: Mercurial-patchbomb/* (glob)
   Date: Thu, 01 Jan 1970 00:01:01 +0000
   From: quux
   To: foo
@@ -1101,7 +1201,7 @@
 test --desc without --intro for a single patch:
   $ echo foo > intro.text
   $ hg email --date '1970-1-1 0:1' -n --desc intro.text -f quux -t foo -c bar \
-  >  -s test -r 2 | fixheaders
+  >  -s test -r 2
   This patch series consists of 1 patches.
   
   
@@ -1110,8 +1210,8 @@
   MIME-Version: 1.0
   Content-Transfer-Encoding: 7bit
   Subject: [PATCH 0 of 1] test
-  Message-Id: <patchbomb.60@
-  User-Agent: Mercurial-patchbomb
+  Message-Id: <patchbomb.60@*> (glob)
+  User-Agent: Mercurial-patchbomb/* (glob)
   Date: Thu, 01 Jan 1970 00:01:00 +0000
   From: quux
   To: foo
@@ -1125,10 +1225,10 @@
   Content-Transfer-Encoding: 7bit
   Subject: [PATCH 1 of 1] c
   X-Mercurial-Node: ff2c9fa2018b15fa74b33363bda9527323e2a99f
-  Message-Id: <ff2c9fa2018b15fa74b3.61@
-  In-Reply-To: <patchbomb.60@
-  References: <patchbomb.60@
-  User-Agent: Mercurial-patchbomb
+  Message-Id: <ff2c9fa2018b15fa74b3.61@*> (glob)
+  In-Reply-To: <patchbomb.60@*> (glob)
+  References: <patchbomb.60@*> (glob)
+  User-Agent: Mercurial-patchbomb/* (glob)
   Date: Thu, 01 Jan 1970 00:01:01 +0000
   From: quux
   To: foo
@@ -1150,7 +1250,7 @@
 
 test intro for multiple patches:
   $ hg email --date '1970-1-1 0:1' -n --intro -f quux -t foo -c bar -s test \
-  >  -r 0:1 | fixheaders
+  >  -r 0:1
   This patch series consists of 2 patches.
   
   
@@ -1162,8 +1262,8 @@
   MIME-Version: 1.0
   Content-Transfer-Encoding: 7bit
   Subject: [PATCH 0 of 2] test
-  Message-Id: <patchbomb.60@
-  User-Agent: Mercurial-patchbomb
+  Message-Id: <patchbomb.60@*> (glob)
+  User-Agent: Mercurial-patchbomb/* (glob)
   Date: Thu, 01 Jan 1970 00:01:00 +0000
   From: quux
   To: foo
@@ -1176,10 +1276,10 @@
   Content-Transfer-Encoding: 7bit
   Subject: [PATCH 1 of 2] a
   X-Mercurial-Node: 8580ff50825a50c8f716709acdf8de0deddcd6ab
-  Message-Id: <8580ff50825a50c8f716.61@
-  In-Reply-To: <patchbomb.60@
-  References: <patchbomb.60@
-  User-Agent: Mercurial-patchbomb
+  Message-Id: <8580ff50825a50c8f716.61@*> (glob)
+  In-Reply-To: <patchbomb.60@*> (glob)
+  References: <patchbomb.60@*> (glob)
+  User-Agent: Mercurial-patchbomb/* (glob)
   Date: Thu, 01 Jan 1970 00:01:01 +0000
   From: quux
   To: foo
@@ -1204,10 +1304,10 @@
   Content-Transfer-Encoding: 7bit
   Subject: [PATCH 2 of 2] b
   X-Mercurial-Node: 97d72e5f12c7e84f85064aa72e5a297142c36ed9
-  Message-Id: <97d72e5f12c7e84f8506.62@
-  In-Reply-To: <patchbomb.60@
-  References: <patchbomb.60@
-  User-Agent: Mercurial-patchbomb
+  Message-Id: <97d72e5f12c7e84f8506.62@*> (glob)
+  In-Reply-To: <patchbomb.60@*> (glob)
+  References: <patchbomb.60@*> (glob)
+  User-Agent: Mercurial-patchbomb/* (glob)
   Date: Thu, 01 Jan 1970 00:01:02 +0000
   From: quux
   To: foo
@@ -1229,7 +1329,7 @@
 
 test reply-to via config:
   $ hg email --date '1970-1-1 0:1' -n -f quux -t foo -c bar -s test -r 2 \
-  >  --config patchbomb.reply-to='baz@example.com' | fixheaders
+  >  --config patchbomb.reply-to='baz@example.com'
   This patch series consists of 1 patches.
   
   
@@ -1239,8 +1339,8 @@
   Content-Transfer-Encoding: 7bit
   Subject: [PATCH] test
   X-Mercurial-Node: ff2c9fa2018b15fa74b33363bda9527323e2a99f
-  Message-Id: <ff2c9fa2018b15fa74b3.60@
-  User-Agent: Mercurial-patchbomb
+  Message-Id: <ff2c9fa2018b15fa74b3.60@*> (glob)
+  User-Agent: Mercurial-patchbomb/* (glob)
   Date: Thu, 01 Jan 1970 00:01:00 +0000
   From: quux
   To: foo
@@ -1263,7 +1363,7 @@
 
 test reply-to via command line:
   $ hg email --date '1970-1-1 0:1' -n -f quux -t foo -c bar -s test -r 2 \
-  >  --reply-to baz --reply-to fred | fixheaders
+  >  --reply-to baz --reply-to fred
   This patch series consists of 1 patches.
   
   
@@ -1273,8 +1373,8 @@
   Content-Transfer-Encoding: 7bit
   Subject: [PATCH] test
   X-Mercurial-Node: ff2c9fa2018b15fa74b33363bda9527323e2a99f
-  Message-Id: <ff2c9fa2018b15fa74b3.60@
-  User-Agent: Mercurial-patchbomb
+  Message-Id: <ff2c9fa2018b15fa74b3.60@*> (glob)
+  User-Agent: Mercurial-patchbomb/* (glob)
   Date: Thu, 01 Jan 1970 00:01:00 +0000
   From: quux
   To: foo
@@ -1301,24 +1401,23 @@
   $ hg tag -r2 two two.diff
 
 test inline for single named patch:
-  $ hg email --date '1970-1-1 0:1' -n -f quux -t foo -c bar -s test -i -r 2 | \
-  >  fixheaders
+  $ hg email --date '1970-1-1 0:1' -n -f quux -t foo -c bar -s test -i -r 2
   This patch series consists of 1 patches.
   
   
   Displaying [PATCH] test ...
-  Content-Type: multipart/mixed; boundary="===
+  Content-Type: multipart/mixed; boundary="===*" (glob)
   MIME-Version: 1.0
   Subject: [PATCH] test
   X-Mercurial-Node: ff2c9fa2018b15fa74b33363bda9527323e2a99f
-  Message-Id: <ff2c9fa2018b15fa74b3.60@
-  User-Agent: Mercurial-patchbomb
+  Message-Id: <ff2c9fa2018b15fa74b3.60@*> (glob)
+  User-Agent: Mercurial-patchbomb/* (glob)
   Date: Thu, 01 Jan 1970 00:01:00 +0000
   From: quux
   To: foo
   Cc: bar
   
-  --===
+  --===* (glob)
   Content-Type: text/x-patch; charset="us-ascii"
   MIME-Version: 1.0
   Content-Transfer-Encoding: 7bit
@@ -1337,11 +1436,10 @@
   @@ -0,0 +1,1 @@
   +c
   
-  --===
+  --===*-- (glob)
 
 test inline for multiple named/unnamed patches:
-  $ hg email --date '1970-1-1 0:1' -n -f quux -t foo -c bar -s test -i -r 0:1 | \
-  >  fixheaders
+  $ hg email --date '1970-1-1 0:1' -n -f quux -t foo -c bar -s test -i -r 0:1
   This patch series consists of 2 patches.
   
   
@@ -1353,8 +1451,8 @@
   MIME-Version: 1.0
   Content-Transfer-Encoding: 7bit
   Subject: [PATCH 0 of 2] test
-  Message-Id: <patchbomb.60@
-  User-Agent: Mercurial-patchbomb
+  Message-Id: <patchbomb.60@*> (glob)
+  User-Agent: Mercurial-patchbomb/* (glob)
   Date: Thu, 01 Jan 1970 00:01:00 +0000
   From: quux
   To: foo
@@ -1362,20 +1460,20 @@
   
   
   Displaying [PATCH 1 of 2] a ...
-  Content-Type: multipart/mixed; boundary="===
+  Content-Type: multipart/mixed; boundary="===*" (glob)
   MIME-Version: 1.0
   Subject: [PATCH 1 of 2] a
   X-Mercurial-Node: 8580ff50825a50c8f716709acdf8de0deddcd6ab
-  Message-Id: <8580ff50825a50c8f716.61@
-  In-Reply-To: <patchbomb.60@
-  References: <patchbomb.60@
-  User-Agent: Mercurial-patchbomb
+  Message-Id: <8580ff50825a50c8f716.61@*> (glob)
+  In-Reply-To: <patchbomb.60@*> (glob)
+  References: <patchbomb.60@*> (glob)
+  User-Agent: Mercurial-patchbomb/* (glob)
   Date: Thu, 01 Jan 1970 00:01:01 +0000
   From: quux
   To: foo
   Cc: bar
   
-  --===
+  --===* (glob)
   Content-Type: text/x-patch; charset="us-ascii"
   MIME-Version: 1.0
   Content-Transfer-Encoding: 7bit
@@ -1394,22 +1492,22 @@
   @@ -0,0 +1,1 @@
   +a
   
-  --===
+  --===*-- (glob)
   Displaying [PATCH 2 of 2] b ...
-  Content-Type: multipart/mixed; boundary="===
+  Content-Type: multipart/mixed; boundary="===*" (glob)
   MIME-Version: 1.0
   Subject: [PATCH 2 of 2] b
   X-Mercurial-Node: 97d72e5f12c7e84f85064aa72e5a297142c36ed9
-  Message-Id: <97d72e5f12c7e84f8506.62@
-  In-Reply-To: <patchbomb.60@
-  References: <patchbomb.60@
-  User-Agent: Mercurial-patchbomb
+  Message-Id: <97d72e5f12c7e84f8506.62@*> (glob)
+  In-Reply-To: <patchbomb.60@*> (glob)
+  References: <patchbomb.60@*> (glob)
+  User-Agent: Mercurial-patchbomb/* (glob)
   Date: Thu, 01 Jan 1970 00:01:02 +0000
   From: quux
   To: foo
   Cc: bar
   
-  --===
+  --===* (glob)
   Content-Type: text/x-patch; charset="us-ascii"
   MIME-Version: 1.0
   Content-Transfer-Encoding: 7bit
@@ -1428,12 +1526,12 @@
   @@ -0,0 +1,1 @@
   +b
   
-  --===
+  --===*-- (glob)
 
 
 test inreplyto:
   $ hg email --date '1970-1-1 0:1' -n -f quux -t foo -c bar --in-reply-to baz \
-  >  -r tip | fixheaders
+  >  -r tip
   This patch series consists of 1 patches.
   
   
@@ -1442,11 +1540,11 @@
   MIME-Version: 1.0
   Content-Transfer-Encoding: 7bit
   Subject: [PATCH] Added tag two, two.diff for changeset ff2c9fa2018b
-  X-Mercurial-Node: e317db6a6f288748d1f6cb064f3810fcba66b1b6
-  Message-Id: <e317db6a6f288748d1f6.60@
+  X-Mercurial-Node: 7aead2484924c445ad8ce2613df91f52f9e502ed
+  Message-Id: <7aead2484924c445ad8c.60@*> (glob)
   In-Reply-To: <baz>
   References: <baz>
-  User-Agent: Mercurial-patchbomb
+  User-Agent: Mercurial-patchbomb/* (glob)
   Date: Thu, 01 Jan 1970 00:01:00 +0000
   From: quux
   To: foo
@@ -1455,11 +1553,11 @@
   # HG changeset patch
   # User test
   # Date 0 0
-  # Node ID e317db6a6f288748d1f6cb064f3810fcba66b1b6
-  # Parent  eae5fcf795eee29d0e45ffc9f519a91cd79fc9ff
+  # Node ID 7aead2484924c445ad8ce2613df91f52f9e502ed
+  # Parent  045ca29b1ea20e4940411e695e20e521f2f0f98e
   Added tag two, two.diff for changeset ff2c9fa2018b
   
-  diff -r eae5fcf795ee -r e317db6a6f28 .hgtags
+  diff -r 045ca29b1ea2 -r 7aead2484924 .hgtags
   --- a/.hgtags	Thu Jan 01 00:00:00 1970 +0000
   +++ b/.hgtags	Thu Jan 01 00:00:00 1970 +0000
   @@ -2,3 +2,5 @@
@@ -1471,7 +1569,7 @@
   
 no intro message in non-interactive mode
   $ hg email --date '1970-1-1 0:1' -n -f quux -t foo -c bar --in-reply-to baz \
-  >  -r 0:1 | fixheaders
+  >  -r 0:1
   This patch series consists of 2 patches.
   
   Subject: [PATCH 0 of 2] 
@@ -1482,10 +1580,10 @@
   Content-Transfer-Encoding: 7bit
   Subject: [PATCH 1 of 2] a
   X-Mercurial-Node: 8580ff50825a50c8f716709acdf8de0deddcd6ab
-  Message-Id: <8580ff50825a50c8f716.60@
+  Message-Id: <8580ff50825a50c8f716.60@*> (glob)
   In-Reply-To: <baz>
   References: <baz>
-  User-Agent: Mercurial-patchbomb
+  User-Agent: Mercurial-patchbomb/* (glob)
   Date: Thu, 01 Jan 1970 00:01:00 +0000
   From: quux
   To: foo
@@ -1510,10 +1608,10 @@
   Content-Transfer-Encoding: 7bit
   Subject: [PATCH 2 of 2] b
   X-Mercurial-Node: 97d72e5f12c7e84f85064aa72e5a297142c36ed9
-  Message-Id: <97d72e5f12c7e84f8506.61@
-  In-Reply-To: <8580ff50825a50c8f716.60@
-  References: <8580ff50825a50c8f716.60@
-  User-Agent: Mercurial-patchbomb
+  Message-Id: <97d72e5f12c7e84f8506.61@*> (glob)
+  In-Reply-To: <8580ff50825a50c8f716.60@*> (glob)
+  References: <8580ff50825a50c8f716.60@*> (glob)
+  User-Agent: Mercurial-patchbomb/* (glob)
   Date: Thu, 01 Jan 1970 00:01:01 +0000
   From: quux
   To: foo
@@ -1536,7 +1634,7 @@
 
 
   $ hg email --date '1970-1-1 0:1' -n -f quux -t foo -c bar --in-reply-to baz \
-  >  -s test -r 0:1 | fixheaders
+  >  -s test -r 0:1
   This patch series consists of 2 patches.
   
   
@@ -1548,10 +1646,10 @@
   MIME-Version: 1.0
   Content-Transfer-Encoding: 7bit
   Subject: [PATCH 0 of 2] test
-  Message-Id: <patchbomb.60@
+  Message-Id: <patchbomb.60@*> (glob)
   In-Reply-To: <baz>
   References: <baz>
-  User-Agent: Mercurial-patchbomb
+  User-Agent: Mercurial-patchbomb/* (glob)
   Date: Thu, 01 Jan 1970 00:01:00 +0000
   From: quux
   To: foo
@@ -1564,10 +1662,10 @@
   Content-Transfer-Encoding: 7bit
   Subject: [PATCH 1 of 2] a
   X-Mercurial-Node: 8580ff50825a50c8f716709acdf8de0deddcd6ab
-  Message-Id: <8580ff50825a50c8f716.61@
-  In-Reply-To: <patchbomb.60@
-  References: <patchbomb.60@
-  User-Agent: Mercurial-patchbomb
+  Message-Id: <8580ff50825a50c8f716.61@*> (glob)
+  In-Reply-To: <patchbomb.60@*> (glob)
+  References: <patchbomb.60@*> (glob)
+  User-Agent: Mercurial-patchbomb/* (glob)
   Date: Thu, 01 Jan 1970 00:01:01 +0000
   From: quux
   To: foo
@@ -1592,10 +1690,10 @@
   Content-Transfer-Encoding: 7bit
   Subject: [PATCH 2 of 2] b
   X-Mercurial-Node: 97d72e5f12c7e84f85064aa72e5a297142c36ed9
-  Message-Id: <97d72e5f12c7e84f8506.62@
-  In-Reply-To: <patchbomb.60@
-  References: <patchbomb.60@
-  User-Agent: Mercurial-patchbomb
+  Message-Id: <97d72e5f12c7e84f8506.62@*> (glob)
+  In-Reply-To: <patchbomb.60@*> (glob)
+  References: <patchbomb.60@*> (glob)
+  User-Agent: Mercurial-patchbomb/* (glob)
   Date: Thu, 01 Jan 1970 00:01:02 +0000
   From: quux
   To: foo
@@ -1617,7 +1715,7 @@
 
 test single flag for single patch:
   $ hg email --date '1970-1-1 0:1' -n --flag fooFlag -f quux -t foo -c bar -s test \
-  >  -r 2 | fixheaders
+  >  -r 2
   This patch series consists of 1 patches.
   
   
@@ -1627,8 +1725,8 @@
   Content-Transfer-Encoding: 7bit
   Subject: [PATCH fooFlag] test
   X-Mercurial-Node: ff2c9fa2018b15fa74b33363bda9527323e2a99f
-  Message-Id: <ff2c9fa2018b15fa74b3.60@
-  User-Agent: Mercurial-patchbomb
+  Message-Id: <ff2c9fa2018b15fa74b3.60@*> (glob)
+  User-Agent: Mercurial-patchbomb/* (glob)
   Date: Thu, 01 Jan 1970 00:01:00 +0000
   From: quux
   To: foo
@@ -1650,7 +1748,7 @@
 
 test single flag for multiple patches:
   $ hg email --date '1970-1-1 0:1' -n --flag fooFlag -f quux -t foo -c bar -s test \
-  >  -r 0:1 | fixheaders
+  >  -r 0:1
   This patch series consists of 2 patches.
   
   
@@ -1662,8 +1760,8 @@
   MIME-Version: 1.0
   Content-Transfer-Encoding: 7bit
   Subject: [PATCH 0 of 2 fooFlag] test
-  Message-Id: <patchbomb.60@
-  User-Agent: Mercurial-patchbomb
+  Message-Id: <patchbomb.60@*> (glob)
+  User-Agent: Mercurial-patchbomb/* (glob)
   Date: Thu, 01 Jan 1970 00:01:00 +0000
   From: quux
   To: foo
@@ -1676,10 +1774,10 @@
   Content-Transfer-Encoding: 7bit
   Subject: [PATCH 1 of 2 fooFlag] a
   X-Mercurial-Node: 8580ff50825a50c8f716709acdf8de0deddcd6ab
-  Message-Id: <8580ff50825a50c8f716.61@
-  In-Reply-To: <patchbomb.60@
-  References: <patchbomb.60@
-  User-Agent: Mercurial-patchbomb
+  Message-Id: <8580ff50825a50c8f716.61@*> (glob)
+  In-Reply-To: <patchbomb.60@*> (glob)
+  References: <patchbomb.60@*> (glob)
+  User-Agent: Mercurial-patchbomb/* (glob)
   Date: Thu, 01 Jan 1970 00:01:01 +0000
   From: quux
   To: foo
@@ -1704,10 +1802,10 @@
   Content-Transfer-Encoding: 7bit
   Subject: [PATCH 2 of 2 fooFlag] b
   X-Mercurial-Node: 97d72e5f12c7e84f85064aa72e5a297142c36ed9
-  Message-Id: <97d72e5f12c7e84f8506.62@
-  In-Reply-To: <patchbomb.60@
-  References: <patchbomb.60@
-  User-Agent: Mercurial-patchbomb
+  Message-Id: <97d72e5f12c7e84f8506.62@*> (glob)
+  In-Reply-To: <patchbomb.60@*> (glob)
+  References: <patchbomb.60@*> (glob)
+  User-Agent: Mercurial-patchbomb/* (glob)
   Date: Thu, 01 Jan 1970 00:01:02 +0000
   From: quux
   To: foo
@@ -1729,7 +1827,7 @@
 
 test mutiple flags for single patch:
   $ hg email --date '1970-1-1 0:1' -n --flag fooFlag --flag barFlag -f quux -t foo \
-  >  -c bar -s test -r 2 | fixheaders
+  >  -c bar -s test -r 2
   This patch series consists of 1 patches.
   
   
@@ -1739,8 +1837,8 @@
   Content-Transfer-Encoding: 7bit
   Subject: [PATCH fooFlag barFlag] test
   X-Mercurial-Node: ff2c9fa2018b15fa74b33363bda9527323e2a99f
-  Message-Id: <ff2c9fa2018b15fa74b3.60@
-  User-Agent: Mercurial-patchbomb
+  Message-Id: <ff2c9fa2018b15fa74b3.60@*> (glob)
+  User-Agent: Mercurial-patchbomb/* (glob)
   Date: Thu, 01 Jan 1970 00:01:00 +0000
   From: quux
   To: foo
@@ -1762,7 +1860,7 @@
 
 test multiple flags for multiple patches:
   $ hg email --date '1970-1-1 0:1' -n --flag fooFlag --flag barFlag -f quux -t foo \
-  >  -c bar -s test -r 0:1 | fixheaders
+  >  -c bar -s test -r 0:1
   This patch series consists of 2 patches.
   
   
@@ -1774,8 +1872,8 @@
   MIME-Version: 1.0
   Content-Transfer-Encoding: 7bit
   Subject: [PATCH 0 of 2 fooFlag barFlag] test
-  Message-Id: <patchbomb.60@
-  User-Agent: Mercurial-patchbomb
+  Message-Id: <patchbomb.60@*> (glob)
+  User-Agent: Mercurial-patchbomb/* (glob)
   Date: Thu, 01 Jan 1970 00:01:00 +0000
   From: quux
   To: foo
@@ -1788,10 +1886,10 @@
   Content-Transfer-Encoding: 7bit
   Subject: [PATCH 1 of 2 fooFlag barFlag] a
   X-Mercurial-Node: 8580ff50825a50c8f716709acdf8de0deddcd6ab
-  Message-Id: <8580ff50825a50c8f716.61@
-  In-Reply-To: <patchbomb.60@
-  References: <patchbomb.60@
-  User-Agent: Mercurial-patchbomb
+  Message-Id: <8580ff50825a50c8f716.61@*> (glob)
+  In-Reply-To: <patchbomb.60@*> (glob)
+  References: <patchbomb.60@*> (glob)
+  User-Agent: Mercurial-patchbomb/* (glob)
   Date: Thu, 01 Jan 1970 00:01:01 +0000
   From: quux
   To: foo
@@ -1816,10 +1914,10 @@
   Content-Transfer-Encoding: 7bit
   Subject: [PATCH 2 of 2 fooFlag barFlag] b
   X-Mercurial-Node: 97d72e5f12c7e84f85064aa72e5a297142c36ed9
-  Message-Id: <97d72e5f12c7e84f8506.62@
-  In-Reply-To: <patchbomb.60@
-  References: <patchbomb.60@
-  User-Agent: Mercurial-patchbomb
+  Message-Id: <97d72e5f12c7e84f8506.62@*> (glob)
+  In-Reply-To: <patchbomb.60@*> (glob)
+  References: <patchbomb.60@*> (glob)
+  User-Agent: Mercurial-patchbomb/* (glob)
   Date: Thu, 01 Jan 1970 00:01:02 +0000
   From: quux
   To: foo
@@ -1847,15 +1945,15 @@
   
   
   Writing [PATCH] test ...
-  $ fixheaders < tmp.mbox
+  $ cat < tmp.mbox
   From quux Tue Jan 01 00:01:01 1980
   Content-Type: text/plain; charset="us-ascii"
   MIME-Version: 1.0
   Content-Transfer-Encoding: 7bit
   Subject: [PATCH] test
   X-Mercurial-Node: 8580ff50825a50c8f716709acdf8de0deddcd6ab
-  Message-Id: <8580ff50825a50c8f716.315532860@
-  User-Agent: Mercurial-patchbomb
+  Message-Id: <8580ff50825a50c8f716.315532860@*> (glob)
+  User-Agent: Mercurial-patchbomb/* (glob)
   Date: Tue, 01 Jan 1980 00:01:00 +0000
   From: quux
   To: spam <spam>, eggs, toast
@@ -1895,7 +1993,7 @@
   Content-Transfer-Encoding: 7bit
   Subject: [PATCH] test
   X-Mercurial-Node: 8580ff50825a50c8f716709acdf8de0deddcd6ab
-  Message-Id: <8580ff50825a50c8f716.315532860@* (glob)
+  Message-Id: <8580ff50825a50c8f716.315532860@*> (glob)
   User-Agent: Mercurial-patchbomb/* (glob)
   Date: Tue, 01 Jan 1980 00:01:00 +0000
   From: quux
@@ -1942,7 +2040,7 @@
   MIME-Version: 1.0
   Content-Transfer-Encoding: 7bit
   Subject: [PATCH 0 of 8] test
-  Message-Id: <patchbomb.315532860@* (glob)
+  Message-Id: <patchbomb.315532860@*> (glob)
   User-Agent: Mercurial-patchbomb/* (glob)
   Date: Tue, 01 Jan 1980 00:01:00 +0000
   From: test
@@ -1955,9 +2053,9 @@
   Content-Transfer-Encoding: 7bit
   Subject: [PATCH 1 of 8] c
   X-Mercurial-Node: ff2c9fa2018b15fa74b33363bda9527323e2a99f
-  Message-Id: <ff2c9fa2018b15fa74b3.315532861@* (glob)
-  In-Reply-To: <patchbomb\.315532860@[^>]*> (re)
-  References: <patchbomb\.315532860@[^>]*> (re)
+  Message-Id: <ff2c9fa2018b15fa74b3.315532861@*> (glob)
+  In-Reply-To: <patchbomb.315532860@*> (glob)
+  References: <patchbomb.315532860@*> (glob)
   User-Agent: Mercurial-patchbomb/* (glob)
   Date: Tue, 01 Jan 1980 00:01:01 +0000
   From: test
@@ -1976,15 +2074,15 @@
   @@ -0,0 +1,1 @@
   +c
   
-  Displaying [PATCH 2 of 8] charset=utf-8; content-transfer-encoding: base64 ...
+  Displaying [PATCH 2 of 8] utf-8 content ...
   Content-Type: text/plain; charset="us-ascii"
   MIME-Version: 1.0
   Content-Transfer-Encoding: 8bit
-  Subject: [PATCH 2 of 8] charset=utf-8; content-transfer-encoding: base64
-  X-Mercurial-Node: c3c9e37db9f4fe4882cda39baf42fed6bad8b15a
-  Message-Id: <c3c9e37db9f4fe4882cd.315532862@* (glob)
-  In-Reply-To: <patchbomb\.315532860@[^>]*> (re)
-  References: <patchbomb\.315532860@[^>]*> (re)
+  Subject: [PATCH 2 of 8] utf-8 content
+  X-Mercurial-Node: 909a00e13e9d78b575aeee23dddbada46d5a143f
+  Message-Id: <909a00e13e9d78b575ae.315532862@*> (glob)
+  In-Reply-To: <patchbomb.315532860@*> (glob)
+  References: <patchbomb.315532860@*> (glob)
   User-Agent: Mercurial-patchbomb/* (glob)
   Date: Tue, 01 Jan 1980 00:01:02 +0000
   From: test
@@ -1993,33 +2091,32 @@
   # HG changeset patch
   # User test
   # Date 4 0
-  # Node ID c3c9e37db9f4fe4882cda39baf42fed6bad8b15a
+  # Node ID 909a00e13e9d78b575aeee23dddbada46d5a143f
   # Parent  ff2c9fa2018b15fa74b33363bda9527323e2a99f
-  charset=utf-8; content-transfer-encoding: base64
+  utf-8 content
   
-  diff -r ff2c9fa2018b -r c3c9e37db9f4 description
+  diff -r ff2c9fa2018b -r 909a00e13e9d description
   --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   +++ b/description	Thu Jan 01 00:00:04 1970 +0000
   @@ -0,0 +1,3 @@
   +a multiline
   +
   +description
-  diff -r ff2c9fa2018b -r c3c9e37db9f4 utf
+  diff -r ff2c9fa2018b -r 909a00e13e9d utf
   --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   +++ b/utf	Thu Jan 01 00:00:04 1970 +0000
   @@ -0,0 +1,1 @@
   +h\xc3\xb6mma! (esc)
   
-  Displaying [PATCH 3 of 8] charset=utf-8; content-transfer-encoding: quoted-printable ...
+  Displaying [PATCH 3 of 8] long line ...
   Content-Type: text/plain; charset="us-ascii"
   MIME-Version: 1.0
   Content-Transfer-Encoding: quoted-printable
-  Subject: [PATCH 3 of 8] charset=utf-8;
-   content-transfer-encoding: quoted-printable
-  X-Mercurial-Node: c655633f8c87700bb38cc6a59a2753bdc5a6c376
-  Message-Id: <c655633f8c87700bb38c.315532863@* (glob)
-  In-Reply-To: <patchbomb\.315532860@[^>]*> (re)
-  References: <patchbomb\.315532860@[^>]*> (re)
+  Subject: [PATCH 3 of 8] long line
+  X-Mercurial-Node: a2ea8fc83dd8b93cfd86ac97b28287204ab806e1
+  Message-Id: <a2ea8fc83dd8b93cfd86.315532863@*> (glob)
+  In-Reply-To: <patchbomb.315532860@*> (glob)
+  References: <patchbomb.315532860@*> (glob)
   User-Agent: Mercurial-patchbomb/* (glob)
   Date: Tue, 01 Jan 1980 00:01:03 +0000
   From: test
@@ -2028,13 +2125,13 @@
   # HG changeset patch
   # User test
   # Date 4 0
-  # Node ID c655633f8c87700bb38cc6a59a2753bdc5a6c376
-  # Parent  c3c9e37db9f4fe4882cda39baf42fed6bad8b15a
-  charset=3Dutf-8; content-transfer-encoding: quoted-printable
+  # Node ID a2ea8fc83dd8b93cfd86ac97b28287204ab806e1
+  # Parent  909a00e13e9d78b575aeee23dddbada46d5a143f
+  long line
   
-  diff -r c3c9e37db9f4 -r c655633f8c87 qp
+  diff -r 909a00e13e9d -r a2ea8fc83dd8 long
   --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
-  +++ b/qp	Thu Jan 01 00:00:04 1970 +0000
+  +++ b/long	Thu Jan 01 00:00:04 1970 +0000
   @@ -0,0 +1,4 @@
   +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
   xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
@@ -2054,15 +2151,15 @@
   +
   +bar
   
-  Displaying [PATCH 4 of 8] charset=us-ascii; content-transfer-encoding: 8bit ...
+  Displaying [PATCH 4 of 8] isolatin 8-bit encoding ...
   Content-Type: text/plain; charset="us-ascii"
   MIME-Version: 1.0
   Content-Transfer-Encoding: 8bit
-  Subject: [PATCH 4 of 8] charset=us-ascii; content-transfer-encoding: 8bit
-  X-Mercurial-Node: 22d0f96be12f5945fd67d101af58f7bc8263c835
-  Message-Id: <22d0f96be12f5945fd67.315532864@* (glob)
-  In-Reply-To: <patchbomb\.315532860@[^>]*> (re)
-  References: <patchbomb\.315532860@[^>]*> (re)
+  Subject: [PATCH 4 of 8] isolatin 8-bit encoding
+  X-Mercurial-Node: 240fb913fc1b7ff15ddb9f33e73d82bf5277c720
+  Message-Id: <240fb913fc1b7ff15ddb.315532864@*> (glob)
+  In-Reply-To: <patchbomb.315532860@*> (glob)
+  References: <patchbomb.315532860@*> (glob)
   User-Agent: Mercurial-patchbomb/* (glob)
   Date: Tue, 01 Jan 1980 00:01:04 +0000
   From: test
@@ -2071,11 +2168,11 @@
   # HG changeset patch
   # User test
   # Date 5 0
-  # Node ID 22d0f96be12f5945fd67d101af58f7bc8263c835
-  # Parent  c655633f8c87700bb38cc6a59a2753bdc5a6c376
-  charset=us-ascii; content-transfer-encoding: 8bit
+  # Node ID 240fb913fc1b7ff15ddb9f33e73d82bf5277c720
+  # Parent  a2ea8fc83dd8b93cfd86ac97b28287204ab806e1
+  isolatin 8-bit encoding
   
-  diff -r c655633f8c87 -r 22d0f96be12f isolatin
+  diff -r a2ea8fc83dd8 -r 240fb913fc1b isolatin
   --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   +++ b/isolatin	Thu Jan 01 00:00:05 1970 +0000
   @@ -0,0 +1,1 @@
@@ -2086,10 +2183,10 @@
   MIME-Version: 1.0
   Content-Transfer-Encoding: 7bit
   Subject: [PATCH 5 of 8] Added tag zero, zero.foo for changeset 8580ff50825a
-  X-Mercurial-Node: dd9c2b4b8a8a0934d5523c15f2c119b362360903
-  Message-Id: <dd9c2b4b8a8a0934d552.315532865@* (glob)
-  In-Reply-To: <patchbomb\.315532860@[^>]*> (re)
-  References: <patchbomb\.315532860@[^>]*> (re)
+  X-Mercurial-Node: 5d5ef15dfe5e7bd3a4ee154b5fff76c7945ec433
+  Message-Id: <5d5ef15dfe5e7bd3a4ee.315532865@*> (glob)
+  In-Reply-To: <patchbomb.315532860@*> (glob)
+  References: <patchbomb.315532860@*> (glob)
   User-Agent: Mercurial-patchbomb/* (glob)
   Date: Tue, 01 Jan 1980 00:01:05 +0000
   From: test
@@ -2098,11 +2195,11 @@
   # HG changeset patch
   # User test
   # Date 0 0
-  # Node ID dd9c2b4b8a8a0934d5523c15f2c119b362360903
-  # Parent  22d0f96be12f5945fd67d101af58f7bc8263c835
+  # Node ID 5d5ef15dfe5e7bd3a4ee154b5fff76c7945ec433
+  # Parent  240fb913fc1b7ff15ddb9f33e73d82bf5277c720
   Added tag zero, zero.foo for changeset 8580ff50825a
   
-  diff -r 22d0f96be12f -r dd9c2b4b8a8a .hgtags
+  diff -r 240fb913fc1b -r 5d5ef15dfe5e .hgtags
   --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   +++ b/.hgtags	Thu Jan 01 00:00:00 1970 +0000
   @@ -0,0 +1,2 @@
@@ -2114,10 +2211,10 @@
   MIME-Version: 1.0
   Content-Transfer-Encoding: 7bit
   Subject: [PATCH 6 of 8] Added tag one, one.patch for changeset 97d72e5f12c7
-  X-Mercurial-Node: eae5fcf795eee29d0e45ffc9f519a91cd79fc9ff
-  Message-Id: <eae5fcf795eee29d0e45.315532866@* (glob)
-  In-Reply-To: <patchbomb\.315532860@[^>]*> (re)
-  References: <patchbomb\.315532860@[^>]*> (re)
+  X-Mercurial-Node: 045ca29b1ea20e4940411e695e20e521f2f0f98e
+  Message-Id: <045ca29b1ea20e494041.315532866@*> (glob)
+  In-Reply-To: <patchbomb.315532860@*> (glob)
+  References: <patchbomb.315532860@*> (glob)
   User-Agent: Mercurial-patchbomb/* (glob)
   Date: Tue, 01 Jan 1980 00:01:06 +0000
   From: test
@@ -2126,11 +2223,11 @@
   # HG changeset patch
   # User test
   # Date 0 0
-  # Node ID eae5fcf795eee29d0e45ffc9f519a91cd79fc9ff
-  # Parent  dd9c2b4b8a8a0934d5523c15f2c119b362360903
+  # Node ID 045ca29b1ea20e4940411e695e20e521f2f0f98e
+  # Parent  5d5ef15dfe5e7bd3a4ee154b5fff76c7945ec433
   Added tag one, one.patch for changeset 97d72e5f12c7
   
-  diff -r dd9c2b4b8a8a -r eae5fcf795ee .hgtags
+  diff -r 5d5ef15dfe5e -r 045ca29b1ea2 .hgtags
   --- a/.hgtags	Thu Jan 01 00:00:00 1970 +0000
   +++ b/.hgtags	Thu Jan 01 00:00:00 1970 +0000
   @@ -1,2 +1,4 @@
@@ -2144,10 +2241,10 @@
   MIME-Version: 1.0
   Content-Transfer-Encoding: 7bit
   Subject: [PATCH 7 of 8] Added tag two, two.diff for changeset ff2c9fa2018b
-  X-Mercurial-Node: e317db6a6f288748d1f6cb064f3810fcba66b1b6
-  Message-Id: <e317db6a6f288748d1f6.315532867@* (glob)
-  In-Reply-To: <patchbomb\.315532860@[^>]*> (re)
-  References: <patchbomb\.315532860@[^>]*> (re)
+  X-Mercurial-Node: 7aead2484924c445ad8ce2613df91f52f9e502ed
+  Message-Id: <7aead2484924c445ad8c.315532867@*> (glob)
+  In-Reply-To: <patchbomb.315532860@*> (glob)
+  References: <patchbomb.315532860@*> (glob)
   User-Agent: Mercurial-patchbomb/* (glob)
   Date: Tue, 01 Jan 1980 00:01:07 +0000
   From: test
@@ -2156,11 +2253,11 @@
   # HG changeset patch
   # User test
   # Date 0 0
-  # Node ID e317db6a6f288748d1f6cb064f3810fcba66b1b6
-  # Parent  eae5fcf795eee29d0e45ffc9f519a91cd79fc9ff
+  # Node ID 7aead2484924c445ad8ce2613df91f52f9e502ed
+  # Parent  045ca29b1ea20e4940411e695e20e521f2f0f98e
   Added tag two, two.diff for changeset ff2c9fa2018b
   
-  diff -r eae5fcf795ee -r e317db6a6f28 .hgtags
+  diff -r 045ca29b1ea2 -r 7aead2484924 .hgtags
   --- a/.hgtags	Thu Jan 01 00:00:00 1970 +0000
   +++ b/.hgtags	Thu Jan 01 00:00:00 1970 +0000
   @@ -2,3 +2,5 @@
@@ -2176,9 +2273,9 @@
   Content-Transfer-Encoding: 7bit
   Subject: [PATCH 8 of 8] d
   X-Mercurial-Node: 2f9fa9b998c5fe3ac2bd9a2b14bfcbeecbc7c268
-  Message-Id: <2f9fa9b998c5fe3ac2bd\.315532868[^>]*> (re)
-  In-Reply-To: <patchbomb\.315532860@[^>]*> (re)
-  References: <patchbomb\.315532860@[^>]*> (re)
+  Message-Id: <2f9fa9b998c5fe3ac2bd.315532868@*> (glob)
+  In-Reply-To: <patchbomb.315532860@*> (glob)
+  References: <patchbomb.315532860@*> (glob)
   User-Agent: Mercurial-patchbomb/* (glob)
   Date: Tue, 01 Jan 1980 00:01:08 +0000
   From: test
@@ -2214,7 +2311,7 @@
   Content-Transfer-Encoding: 7bit
   Subject: [PATCH] test
   X-Mercurial-Node: 2f9fa9b998c5fe3ac2bd9a2b14bfcbeecbc7c268
-  Message-Id: <2f9fa9b998c5fe3ac2bd.315532860@* (glob)
+  Message-Id: <2f9fa9b998c5fe3ac2bd.315532860@*> (glob)
   User-Agent: Mercurial-patchbomb/* (glob)
   Date: Tue, 01 Jan 1980 00:01:00 +0000
   From: test
--- a/tests/test-paths.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-paths.t	Tue Nov 22 18:16:59 2011 +0100
@@ -7,29 +7,29 @@
   $ echo 'dupe = ../b' >> .hg/hgrc
   $ echo 'expand = $SOMETHING/bar' >> .hg/hgrc
   $ hg in dupe
-  comparing with $TESTTMP/b
+  comparing with $TESTTMP/b (glob)
   no changes found
   [1]
   $ cd ..
   $ hg -R a in dupe
-  comparing with $TESTTMP/b
+  comparing with $TESTTMP/b (glob)
   no changes found
   [1]
   $ cd a
   $ hg paths
-  dupe = $TESTTMP/b
-  expand = $TESTTMP/a/$SOMETHING/bar
+  dupe = $TESTTMP/b (glob)
+  expand = $TESTTMP/a/$SOMETHING/bar (glob)
   $ SOMETHING=foo hg paths
-  dupe = $TESTTMP/b
-  expand = $TESTTMP/a/foo/bar
+  dupe = $TESTTMP/b (glob)
+  expand = $TESTTMP/a/foo/bar (glob)
   $ SOMETHING=/foo hg paths
-  dupe = $TESTTMP/b
+  dupe = $TESTTMP/b (glob)
   expand = /foo/bar
   $ hg paths -q
   dupe
   expand
   $ hg paths dupe
-  $TESTTMP/b
+  $TESTTMP/b (glob)
   $ hg paths -q dupe
   $ hg paths unknown
   not found!
--- a/tests/test-pending.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-pending.t	Tue Nov 22 18:16:59 2011 +0100
@@ -1,3 +1,5 @@
+  $ "$TESTDIR/hghave" system-sh || exit 80
+
 Verify that pending changesets are seen by pretxn* hooks but not by other
 processes that access the destination repo while the hooks are running.
 
--- a/tests/test-permissions.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-permissions.t	Tue Nov 22 18:16:59 2011 +0100
@@ -1,3 +1,5 @@
+  $ "$TESTDIR/hghave" unix-permissions || exit 80
+
   $ hg init t
   $ cd t
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-phases-exchange.t	Tue Nov 22 18:16:59 2011 +0100
@@ -0,0 +1,112 @@
+  $ cat >> $HGRCPATH <<EOF
+  > [extensions]
+  > graphlog=
+  > EOF
+  $ alias hgph='hg log --template "{rev} {phase} {desc}\n"'
+
+  $ mkcommit() {
+  >    echo "$1" > "$1"
+  >    hg add "$1"
+  >    hg ci -m "$1"
+  > }
+
+  $ hg init alpha
+  $ cd alpha
+  $ mkcommit a-A
+  $ mkcommit a-B
+  $ mkcommit a-C
+  $ mkcommit a-D
+  $ hgph
+  3 1 a-D
+  2 1 a-C
+  1 1 a-B
+  0 1 a-A
+
+  $ hg init ../beta
+  $ hg push -r 1 ../beta
+  pushing to ../beta
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 2 changesets with 2 changes to 2 files
+  $ hgph
+  3 1 a-D
+  2 1 a-C
+  1 0 a-B
+  0 0 a-A
+
+  $ cd ../beta
+  $ hgph
+  1 0 a-B
+  0 0 a-A
+  $ hg up -q
+  $ mkcommit b-A
+  $ hgph
+  2 1 b-A
+  1 0 a-B
+  0 0 a-A
+  $ hg pull ../alpha
+  pulling from ../alpha
+  searching for changes
+  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)
+  $ hgph
+  4 0 a-D
+  3 0 a-C
+  2 1 b-A
+  1 0 a-B
+  0 0 a-A
+
+pull did not updated ../alpha state.
+push from alpha to beta should update phase even if nothing is transfered
+
+  $ cd ../alpha
+  $ hgph # not updated by remote pull
+  3 1 a-D
+  2 1 a-C
+  1 0 a-B
+  0 0 a-A
+  $ hg push ../beta
+  pushing to ../beta
+  searching for changes
+  no changes found
+  $ hgph
+  3 0 a-D
+  2 0 a-C
+  1 0 a-B
+  0 0 a-A
+
+update must update phase of common changeset too
+
+  $ hg pull ../beta # getting b-A
+  pulling from ../beta
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 1 changes to 1 files (+1 heads)
+  (run 'hg heads' to see heads, 'hg merge' to merge)
+
+  $ cd ../beta
+  $ hgph # not updated by remote pull
+  4 0 a-D
+  3 0 a-C
+  2 1 b-A
+  1 0 a-B
+  0 0 a-A
+  $ hg pull ../alpha
+  pulling from ../alpha
+  searching for changes
+  no changes found
+  $ hgph
+  4 0 a-D
+  3 0 a-C
+  2 0 b-A
+  1 0 a-B
+  0 0 a-A
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-phases.t	Tue Nov 22 18:16:59 2011 +0100
@@ -0,0 +1,10 @@
+  $ alias hglog='hg log --template "{rev} {phase} {desc}\n"'
+
+  $ hg init initialrepo
+  $ cd initialrepo
+  $ touch sam
+  $ hg add sam
+  $ hg ci -m 'first'
+
+  $ hglog
+  0 1 first
--- a/tests/test-pull-http.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-pull-http.t	Tue Nov 22 18:16:59 2011 +0100
@@ -1,3 +1,4 @@
+  $ "$TESTDIR/hghave" serve || exit 80
 
   $ hg init test
   $ cd test
--- a/tests/test-pull-permission.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-pull-permission.t	Tue Nov 22 18:16:59 2011 +0100
@@ -1,3 +1,5 @@
+  $ "$TESTDIR/hghave" unix-permissions || exit 80
+
   $ hg init a
   $ cd a
   $ echo foo > b
--- a/tests/test-pull-r.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-pull-r.t	Tue Nov 22 18:16:59 2011 +0100
@@ -43,7 +43,7 @@
   2:effea6de0384
   1:ed1b79f46b9a
   $ hg pull
-  pulling from $TESTTMP/repo2
+  pulling from $TESTTMP/repo2 (glob)
   searching for changes
   adding changesets
   adding manifests
--- a/tests/test-pull.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-pull.t	Tue Nov 22 18:16:59 2011 +0100
@@ -1,3 +1,5 @@
+  $ "$TESTDIR/hghave" serve || exit 80
+
   $ hg init test
   $ cd test
 
--- a/tests/test-push-http.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-push-http.t	Tue Nov 22 18:16:59 2011 +0100
@@ -1,3 +1,4 @@
+  $ "$TESTDIR/hghave" serve || exit 80
 
   $ hg init test
   $ cd test
--- a/tests/test-push-validation.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-push-validation.t	Tue Nov 22 18:16:59 2011 +0100
@@ -40,7 +40,7 @@
 Expected to fail:
 
   $ hg push
-  pushing to $TESTTMP/test
+  pushing to $TESTTMP/test (glob)
   searching for changes
   adding changesets
   adding manifests
--- a/tests/test-qrecord.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-qrecord.t	Tue Nov 22 18:16:59 2011 +0100
@@ -107,7 +107,7 @@
 
   $ echo "mq=nonexistant" >> $HGRCPATH
   $ hg help qrecord
-  *** failed to import extension mq from nonexistant: [Errno 2] No such file or directory
+  *** failed to import extension mq from nonexistant: [Errno 2] * (glob)
   hg qrecord [OPTION]... PATCH [FILE]...
   
   interactively record a new patch
--- a/tests/test-rebase-abort.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-rebase-abort.t	Tue Nov 22 18:16:59 2011 +0100
@@ -49,7 +49,7 @@
   $ hg rebase -s 3 -d 2
   merging common
   warning: conflicts during merge.
-  merging common failed!
+  merging common incomplete! (edit conflicts, then use 'hg resolve --mark')
   abort: unresolved conflicts (see hg resolve, then hg rebase --continue)
   [255]
 
@@ -117,7 +117,7 @@
   $ hg rebase -b 4 -d 2
   merging c
   warning: conflicts during merge.
-  merging c failed!
+  merging c incomplete! (edit conflicts, then use 'hg resolve --mark')
   abort: unresolved conflicts (see hg resolve, then hg rebase --continue)
   [255]
 
--- a/tests/test-rebase-check-restore.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-rebase-check-restore.t	Tue Nov 22 18:16:59 2011 +0100
@@ -63,7 +63,7 @@
   $ hg rebase -s 1 -d 4 --keep
   merging A
   warning: conflicts during merge.
-  merging A failed!
+  merging A incomplete! (edit conflicts, then use 'hg resolve --mark')
   abort: unresolved conflicts (see hg resolve, then hg rebase --continue)
   [255]
 
@@ -115,7 +115,7 @@
   $ hg rebase -s 5 -d 4 --keepbranches
   merging A
   warning: conflicts during merge.
-  merging A failed!
+  merging A incomplete! (edit conflicts, then use 'hg resolve --mark')
   abort: unresolved conflicts (see hg resolve, then hg rebase --continue)
   [255]
 
--- a/tests/test-rebase-conflicts.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-rebase-conflicts.t	Tue Nov 22 18:16:59 2011 +0100
@@ -58,7 +58,7 @@
   $ hg rebase -s 3 -d 2
   merging common
   warning: conflicts during merge.
-  merging common failed!
+  merging common incomplete! (edit conflicts, then use 'hg resolve --mark')
   abort: unresolved conflicts (see hg resolve, then hg rebase --continue)
   [255]
 
--- a/tests/test-rebase-detach.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-rebase-detach.t	Tue Nov 22 18:16:59 2011 +0100
@@ -283,7 +283,7 @@
   
 
   $ hg rebase -d 5 -s 7
-  saved backup bundle to $TESTTMP/a5/.hg/strip-backup/13547172c9c0-backup.hg
+  saved backup bundle to $TESTTMP/a5/.hg/strip-backup/13547172c9c0-backup.hg (glob)
   $ hg tglog
   @  8: 'D'
   |
@@ -367,12 +367,12 @@
   $ hg rebase -s 8 -d 7 --detach --config ui.merge=internal:fail
   merging H
   warning: conflicts during merge.
-  merging H failed!
+  merging H incomplete! (edit conflicts, then use 'hg resolve --mark')
   abort: unresolved conflicts (see hg resolve, then hg rebase --continue)
   [255]
   $ hg resolve --all -t internal:local
   $ hg rebase -c
-  saved backup bundle to $TESTTMP/a7/.hg/strip-backup/6215fafa5447-backup.hg
+  saved backup bundle to $TESTTMP/a7/.hg/strip-backup/6215fafa5447-backup.hg (glob)
   $ hg tglog
   @  8: 'H2'
   |
--- a/tests/test-rebase-interruptions.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-rebase-interruptions.t	Tue Nov 22 18:16:59 2011 +0100
@@ -56,7 +56,7 @@
   $ hg rebase -s 1 -d 4
   merging A
   warning: conflicts during merge.
-  merging A failed!
+  merging A incomplete! (edit conflicts, then use 'hg resolve --mark')
   abort: unresolved conflicts (see hg resolve, then hg rebase --continue)
   [255]
 
@@ -88,7 +88,7 @@
   $ hg rebase --continue
   merging A
   warning: conflicts during merge.
-  merging A failed!
+  merging A incomplete! (edit conflicts, then use 'hg resolve --mark')
   abort: unresolved conflicts (see hg resolve, then hg rebase --continue)
   [255]
 
@@ -142,7 +142,7 @@
   $ hg rebase -s 1 -d 4
   merging A
   warning: conflicts during merge.
-  merging A failed!
+  merging A incomplete! (edit conflicts, then use 'hg resolve --mark')
   abort: unresolved conflicts (see hg resolve, then hg rebase --continue)
   [255]
 
--- a/tests/test-rebase-mq.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-rebase-mq.t	Tue Nov 22 18:16:59 2011 +0100
@@ -62,7 +62,7 @@
   $ hg rebase -s 2 -d 1
   merging f
   warning: conflicts during merge.
-  merging f failed!
+  merging f incomplete! (edit conflicts, then use 'hg resolve --mark')
   abort: unresolved conflicts (see hg resolve, then hg rebase --continue)
   [255]
 
@@ -73,7 +73,7 @@
   $ hg rebase -c
   merging f
   warning: conflicts during merge.
-  merging f failed!
+  merging f incomplete! (edit conflicts, then use 'hg resolve --mark')
   abort: unresolved conflicts (see hg resolve, then hg rebase --continue)
   [255]
 
--- a/tests/test-rebase-pull.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-rebase-pull.t	Tue Nov 22 18:16:59 2011 +0100
@@ -48,7 +48,7 @@
 Now b has one revision to be pulled from a:
 
   $ hg pull --rebase
-  pulling from $TESTTMP/a
+  pulling from $TESTTMP/a (glob)
   searching for changes
   adding changesets
   adding manifests
@@ -68,7 +68,7 @@
 Re-run:
 
   $ hg pull --rebase
-  pulling from $TESTTMP/a
+  pulling from $TESTTMP/a (glob)
   searching for changes
   no changes found
 
@@ -78,7 +78,7 @@
   $ cd ../c
 
   $ hg pull --rebase
-  pulling from $TESTTMP/a
+  pulling from $TESTTMP/a (glob)
   searching for changes
   adding changesets
   adding manifests
@@ -94,7 +94,7 @@
 pull --rebase --update should ignore --update:
 
   $ hg pull --rebase --update
-  pulling from $TESTTMP/a
+  pulling from $TESTTMP/a (glob)
   searching for changes
   no changes found
 
@@ -103,7 +103,7 @@
   $ hg up -q 1
 
   $ hg pull --rebase
-  pulling from $TESTTMP/a
+  pulling from $TESTTMP/a (glob)
   searching for changes
   no changes found
 
--- a/tests/test-rebase-scenario-global.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-rebase-scenario-global.t	Tue Nov 22 18:16:59 2011 +0100
@@ -251,7 +251,7 @@
 C onto A - rebase onto an ancestor:
 
   $ hg rebase -d 0 -s 2
-  saved backup bundle to $TESTTMP/a7/.hg/strip-backup/5fddd98957c8-backup.hg
+  saved backup bundle to $TESTTMP/a7/.hg/strip-backup/5fddd98957c8-backup.hg (glob)
   $ hg tglog
   @  7: 'D'
   |
@@ -473,7 +473,7 @@
   $ hg clone -q -u . ah ah5
   $ cd ah5
   $ hg rebase -r '6::' -d 2
-  saved backup bundle to $TESTTMP/ah5/.hg/strip-backup/3d8a618087a7-backup.hg
+  saved backup bundle to $TESTTMP/ah5/.hg/strip-backup/3d8a618087a7-backup.hg (glob)
   $ hg tglog
   @  8: 'I'
   |
--- a/tests/test-rebuildstate.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-rebuildstate.t	Tue Nov 22 18:16:59 2011 +0100
@@ -17,8 +17,8 @@
 state dump after
 
   $ hg debugstate --nodates | sort
-  n 666         -1 bar
-  n 666         -1 foo
+  n 644         -1 bar
+  n 644         -1 foo
 
 status
 
--- a/tests/test-record.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-record.t	Tue Nov 22 18:16:59 2011 +0100
@@ -1,3 +1,5 @@
+  $ "$TESTDIR/hghave" execbit || exit 80
+
 Set up a repo
 
   $ echo "[ui]" >> $HGRCPATH
--- a/tests/test-relink.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-relink.t	Tue Nov 22 18:16:59 2011 +0100
@@ -39,7 +39,7 @@
 don't sit forever trying to double-lock the source repo
 
   $ hg relink .
-  relinking $TESTTMP/repo/.hg/store to $TESTTMP/repo/.hg/store
+  relinking $TESTTMP/repo/.hg/store to $TESTTMP/repo/.hg/store (glob)
   there is nothing to relink
 
 
--- a/tests/test-remove.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-remove.t	Tue Nov 22 18:16:59 2011 +0100
@@ -196,8 +196,8 @@
 
   $ rm test/bar
   $ remove test
-  removing test/bar
-  removing test/foo
+  removing test/bar (glob)
+  removing test/foo (glob)
   exit code: 0
   R test/bar
   R test/foo
@@ -208,8 +208,8 @@
 
   $ rm test/bar
   $ remove -f test
-  removing test/bar
-  removing test/foo
+  removing test/bar (glob)
+  removing test/foo (glob)
   exit code: 0
   R test/bar
   R test/foo
@@ -220,8 +220,8 @@
 
   $ rm test/bar
   $ remove -A test
-  not removing test/foo: file still exists (use -f to force removal)
-  removing test/bar
+  not removing test/foo: file still exists (use -f to force removal) (glob)
+  removing test/bar (glob)
   exit code: 1
   R test/bar
   ./foo
@@ -232,8 +232,8 @@
 
   $ rm test/bar
   $ remove -Af test
-  removing test/bar
-  removing test/foo
+  removing test/bar (glob)
+  removing test/foo (glob)
   exit code: 0
   R test/bar
   R test/foo
@@ -250,7 +250,7 @@
   adding issue1861/b/c/y
   adding issue1861/x
   $ hg rm issue1861/b
-  removing issue1861/b/c/y
+  removing issue1861/b/c/y (glob)
   $ hg ci -m remove
   $ ls issue1861
   x
--- a/tests/test-rename-dir-merge.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-rename-dir-merge.t	Tue Nov 22 18:16:59 2011 +0100
@@ -11,8 +11,8 @@
   $ hg co -C 0
   0 files updated, 0 files merged, 0 files removed, 0 files unresolved
   $ hg mv a b
-  moving a/a to b/a
-  moving a/b to b/b
+  moving a/a to b/a (glob)
+  moving a/b to b/b (glob)
   $ hg ci -m "1 mv a/ b/"
 
   $ hg co -C 0
@@ -75,7 +75,7 @@
   ? b/d
   $ hg ci -m "3 merge 2+1"
   $ hg debugrename b/c
-  b/c renamed from a/c:354ae8da6e890359ef49ade27b68bbc361f3ca88
+  b/c renamed from a/c:354ae8da6e890359ef49ade27b68bbc361f3ca88 (glob)
 
   $ hg co -C 1
   0 files updated, 0 files merged, 1 files removed, 0 files unresolved
@@ -111,7 +111,7 @@
   $ hg ci -m "4 merge 1+2"
   created new head
   $ hg debugrename b/c
-  b/c renamed from a/c:354ae8da6e890359ef49ade27b68bbc361f3ca88
+  b/c renamed from a/c:354ae8da6e890359ef49ade27b68bbc361f3ca88 (glob)
 
 
 Second scenario with two repos:
@@ -122,7 +122,7 @@
   $ mkdir a
   $ echo foo > a/f
   $ hg add a
-  adding a/f
+  adding a/f (glob)
   $ hg ci -m "a/f == foo"
   $ cd ..
 
@@ -131,7 +131,7 @@
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
   $ cd r2
   $ hg mv a b
-  moving a/f to b/f
+  moving a/f to b/f (glob)
   $ echo foo1 > b/f
   $ hg ci -m" a -> b, b/f == foo1"
   $ cd ..
@@ -140,7 +140,7 @@
   $ mkdir a/aa
   $ echo bar > a/aa/g
   $ hg add a/aa
-  adding a/aa/g
+  adding a/aa/g (glob)
   $ hg ci -m "a/aa/g"
   $ hg pull ../r2
   pulling from ../r2
--- a/tests/test-rename.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-rename.t	Tue Nov 22 18:16:59 2011 +0100
@@ -1,3 +1,5 @@
+  $ "$TESTDIR/hghave" symlink || exit 80
+
   $ hg init
   $ mkdir d1 d1/d11 d2
   $ echo d1/a > d1/a
@@ -69,7 +71,7 @@
 rename --after a single file to a nonexistant target filename
 
   $ hg rename --after d1/a dummy
-  d1/a: not recording move - dummy does not exist
+  d1/a: not recording move - dummy does not exist (glob)
 
 move a single file to an existing directory
 
@@ -119,10 +121,10 @@
 rename directory d1 as d3
 
   $ hg rename d1/ d3
-  moving d1/a to d3/a
-  moving d1/b to d3/b
-  moving d1/ba to d3/ba
-  moving d1/d11/a1 to d3/d11/a1
+  moving d1/a to d3/a (glob)
+  moving d1/b to d3/b (glob)
+  moving d1/ba to d3/ba (glob)
+  moving d1/d11/a1 to d3/d11/a1 (glob)
   $ hg status -C
   A d3/a
     d1/a
@@ -144,10 +146,10 @@
 
   $ mv d1 d3
   $ hg rename --after d1 d3
-  moving d1/a to d3/a
-  moving d1/b to d3/b
-  moving d1/ba to d3/ba
-  moving d1/d11/a1 to d3/d11/a1
+  moving d1/a to d3/a (glob)
+  moving d1/b to d3/b (glob)
+  moving d1/ba to d3/ba (glob)
+  moving d1/d11/a1 to d3/d11/a1 (glob)
   $ hg status -C
   A d3/a
     d1/a
@@ -168,7 +170,7 @@
 move a directory using a relative path
 
   $ (cd d2; mkdir d3; hg rename ../d1/d11 d3)
-  moving ../d1/d11/a1 to d3/d11/a1
+  moving ../d1/d11/a1 to d3/d11/a1 (glob)
   $ hg status -C
   A d2/d3/d11/a1
     d1/d11/a1
@@ -180,7 +182,7 @@
 move --after a directory using a relative path
 
   $ (cd d2; mkdir d3; mv ../d1/d11 d3; hg rename --after ../d1/d11 d3)
-  moving ../d1/d11/a1 to d3/d11/a1
+  moving ../d1/d11/a1 to d3/d11/a1 (glob)
   $ hg status -C
   A d2/d3/d11/a1
     d1/d11/a1
@@ -192,7 +194,7 @@
 move directory d1/d11 to an existing directory d2 (removes empty d1)
 
   $ hg rename d1/d11/ d2
-  moving d1/d11/a1 to d2/d11/a1
+  moving d1/d11/a1 to d2/d11/a1 (glob)
   $ hg status -C
   A d2/d11/a1
     d1/d11/a1
@@ -205,11 +207,11 @@
 
   $ mkdir d3
   $ hg rename d1 d2 d3
-  moving d1/a to d3/d1/a
-  moving d1/b to d3/d1/b
-  moving d1/ba to d3/d1/ba
-  moving d1/d11/a1 to d3/d1/d11/a1
-  moving d2/b to d3/d2/b
+  moving d1/a to d3/d1/a (glob)
+  moving d1/b to d3/d1/b (glob)
+  moving d1/ba to d3/d1/ba (glob)
+  moving d1/d11/a1 to d3/d1/d11/a1 (glob)
+  moving d2/b to d3/d2/b (glob)
   $ hg status -C
   A d3/d1/a
     d1/a
@@ -235,11 +237,11 @@
   $ mkdir d3
   $ mv d1 d2 d3
   $ hg rename --after d1 d2 d3
-  moving d1/a to d3/d1/a
-  moving d1/b to d3/d1/b
-  moving d1/ba to d3/d1/ba
-  moving d1/d11/a1 to d3/d1/d11/a1
-  moving d2/b to d3/d2/b
+  moving d1/a to d3/d1/a (glob)
+  moving d1/b to d3/d1/b (glob)
+  moving d1/ba to d3/d1/ba (glob)
+  moving d1/d11/a1 to d3/d1/d11/a1 (glob)
+  moving d2/b to d3/d2/b (glob)
   $ hg status -C
   A d3/d1/a
     d1/a
@@ -265,7 +267,7 @@
 
   $ hg rename d1/* d2
   d2/b: not overwriting - file exists
-  moving d1/d11/a1 to d2/d11/a1
+  moving d1/d11/a1 to d2/d11/a1 (glob)
   $ hg status -C
   A d2/a
     d1/a
@@ -306,10 +308,10 @@
 
   $ mkdir d2/d21
   $ hg rename 'glob:d1/**' d2/d21
-  moving d1/a to d2/d21/a
-  moving d1/b to d2/d21/b
-  moving d1/ba to d2/d21/ba
-  moving d1/d11/a1 to d2/d21/a1
+  moving d1/a to d2/d21/a (glob)
+  moving d1/b to d2/d21/b (glob)
+  moving d1/ba to d2/d21/ba (glob)
+  moving d1/d11/a1 to d2/d21/a1 (glob)
   $ hg status -C
   A d2/d21/a
     d1/a
@@ -332,10 +334,10 @@
   $ mkdir d2/d21
   $ mv d1/a d1/d11/a1 d2/d21
   $ hg rename --after 'glob:d1/**' d2/d21
-  moving d1/a to d2/d21/a
-  d1/b: not recording move - d2/d21/b does not exist
-  d1/ba: not recording move - d2/d21/ba does not exist
-  moving d1/d11/a1 to d2/d21/a1
+  moving d1/a to d2/d21/a (glob)
+  d1/b: not recording move - d2/d21/b does not exist (glob)
+  d1/ba: not recording move - d2/d21/ba does not exist (glob)
+  moving d1/d11/a1 to d2/d21/a1 (glob)
   $ hg status -C
   A d2/d21/a
     d1/a
@@ -351,8 +353,8 @@
 
   $ mkdir d2/d21
   $ hg rename 're:d1/([^a][^/]*/)*a.*' d2/d21
-  moving d1/a to d2/d21/a
-  moving d1/d11/a1 to d2/d21/a1
+  moving d1/a to d2/d21/a (glob)
+  moving d1/d11/a1 to d2/d21/a1 (glob)
   $ hg status -C
   A d2/d21/a
     d1/a
@@ -413,7 +415,7 @@
 
   $ mkdir d3
   $ hg rename d1/* d2/* d3
-  moving d1/d11/a1 to d3/d11/a1
+  moving d1/d11/a1 to d3/d11/a1 (glob)
   d3/b: not overwriting - d2/b collides with d1/b
   $ hg status -C
   A d3/a
@@ -439,7 +441,7 @@
   moving a to ../d3/d1/a
   moving b to ../d3/d1/b
   moving ba to ../d3/d1/ba
-  moving d11/a1 to ../d3/d1/d11/a1
+  moving d11/a1 to ../d3/d1/d11/a1 (glob)
   $ hg status -C
   A d3/d1/a
     d1/a
@@ -465,7 +467,7 @@
   moving a to ../d3/a
   moving b to ../d3/b
   moving ba to ../d3/ba
-  moving d11/a1 to ../d3/d11/a1
+  moving d11/a1 to ../d3/d11/a1 (glob)
   $ hg status -C
   A d3/a
     d1/a
@@ -486,9 +488,9 @@
 move the parent tree with "hg rename .."
 
   $ (cd d1/d11; hg rename .. ../../d3)
-  moving ../a to ../../d3/a
-  moving ../b to ../../d3/b
-  moving ../ba to ../../d3/ba
+  moving ../a to ../../d3/a (glob)
+  moving ../b to ../../d3/b (glob)
+  moving ../ba to ../../d3/ba (glob)
   moving a1 to ../../d3/d11/a1
   $ hg status -C
   A d3/a
@@ -511,9 +513,9 @@
 
   $ hg remove d1/b
   $ hg rename d1 d3
-  moving d1/a to d3/a
-  moving d1/ba to d3/ba
-  moving d1/d11/a1 to d3/d11/a1
+  moving d1/a to d3/a (glob)
+  moving d1/ba to d3/ba (glob)
+  moving d1/d11/a1 to d3/d11/a1 (glob)
   $ hg status -C
   A d3/a
     d1/a
@@ -587,7 +589,7 @@
 check illegal path components
 
   $ hg rename d1/d11/a1 .hg/foo
-  abort: path contains illegal component: .hg/foo
+  abort: path contains illegal component: .hg/foo (glob)
   [255]
   $ hg status -C
   $ hg rename d1/d11/a1 ../foo
@@ -597,7 +599,7 @@
 
   $ mv d1/d11/a1 .hg/foo
   $ hg rename --after d1/d11/a1 .hg/foo
-  abort: path contains illegal component: .hg/foo
+  abort: path contains illegal component: .hg/foo (glob)
   [255]
   $ hg status -C
   ! d1/d11/a1
@@ -606,17 +608,17 @@
   $ rm .hg/foo
 
   $ hg rename d1/d11/a1 .hg
-  abort: path contains illegal component: .hg/a1
+  abort: path contains illegal component: .hg/a1 (glob)
   [255]
   $ hg status -C
   $ hg rename d1/d11/a1 ..
-  abort: ../a1 not under root
+  abort: ../a1 not under root (glob)
   [255]
   $ hg status -C
 
   $ mv d1/d11/a1 .hg
   $ hg rename --after d1/d11/a1 .hg
-  abort: path contains illegal component: .hg/a1
+  abort: path contains illegal component: .hg/a1 (glob)
   [255]
   $ hg status -C
   ! d1/d11/a1
@@ -625,7 +627,7 @@
   $ rm .hg/a1
 
   $ (cd d1/d11; hg rename ../../d2/b ../../.hg/foo)
-  abort: path contains illegal component: .hg/foo
+  abort: path contains illegal component: .hg/foo (glob)
   [255]
   $ hg status -C
   $ (cd d1/d11; hg rename ../../d2/b ../../../foo)
--- a/tests/test-repair-strip.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-repair-strip.t	Tue Nov 22 18:16:59 2011 +0100
@@ -1,3 +1,4 @@
+  $ "$TESTDIR/hghave" unix-permissions || exit 80
 
   $ echo "[extensions]" >> $HGRCPATH
   $ echo "mq=">> $HGRCPATH
--- a/tests/test-revert.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-revert.t	Tue Nov 22 18:16:59 2011 +0100
@@ -1,3 +1,5 @@
+  $ "$TESTDIR/hghave" execbit || exit 80
+
   $ hg init repo
   $ cd repo
   $ echo 123 > a
@@ -80,7 +82,7 @@
 should not find b
 
   $ hg status b
-  b: No such file or directory
+  b: * (glob)
 
 should show a c e
 
@@ -214,11 +216,11 @@
   $ echo foo > newdir/newfile
   $ hg add newdir/newfile
   $ hg revert b newdir
-  reverting b/b
-  forgetting newdir/newfile
+  reverting b/b (glob)
+  forgetting newdir/newfile (glob)
   $ echo foobar > b/b
   $ hg revert .
-  reverting b/b
+  reverting b/b (glob)
 
 
 reverting a rename target should revert the source
@@ -259,8 +261,8 @@
 
   $ hg revert -a --no-backup
   reverting ignored
-  reverting ignoreddir/file
-  undeleting ignoreddir/removed
+  reverting ignoreddir/file (glob)
+  undeleting ignoreddir/removed (glob)
   undeleting removed
   $ hg st -mardi
 
--- a/tests/test-revset-outgoing.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-revset-outgoing.t	Tue Nov 22 18:16:59 2011 +0100
@@ -39,7 +39,7 @@
   $ cd b
   $ cat .hg/hgrc
   [paths]
-  default = $TESTTMP/a#stable
+  default = $TESTTMP/a#stable (glob)
 
   $ echo red >> a
   $ hg ci -qm3
@@ -60,7 +60,7 @@
   
 
   $ hg tout
-  comparing with $TESTTMP/a
+  comparing with $TESTTMP/a (glob)
   searching for changes
   2:1d4099801a4e: '3' stable
 
@@ -79,11 +79,11 @@
 
   $ cat .hg/hgrc
   [paths]
-  default = $TESTTMP/a#stable
+  default = $TESTTMP/a#stable (glob)
   green = ../a#default
 
   $ hg tout green
-  comparing with $TESTTMP/a
+  comparing with $TESTTMP/a (glob)
   searching for changes
   3:f0461977a3db: '4' 
 
--- a/tests/test-rollback.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-rollback.t	Tue Nov 22 18:16:59 2011 +0100
@@ -1,3 +1,5 @@
+  $ "$TESTDIR/hghave" serve || exit 80
+
 setup repo
   $ hg init t
   $ cd t
--- a/tests/test-run-tests.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-run-tests.t	Tue Nov 22 18:16:59 2011 +0100
@@ -16,6 +16,11 @@
   $ foo
   bar
 
+Return codes before inline python:
+
+  $ false
+  [1]
+
 Doctest commands:
 
   >>> print 'foo'
@@ -28,7 +33,7 @@
   y
   z
   >>> print
-  <BLANKLINE>
+  
 
 Regular expressions:
 
--- a/tests/test-schemes.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-schemes.t	Tue Nov 22 18:16:59 2011 +0100
@@ -1,3 +1,4 @@
+  $ "$TESTDIR/hghave" serve || exit 80
 
   $ cat <<EOF >> $HGRCPATH
   > [extensions]
--- a/tests/test-serve.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-serve.t	Tue Nov 22 18:16:59 2011 +0100
@@ -1,3 +1,4 @@
+  $ "$TESTDIR/hghave" serve || exit 80
 
   $ hgserve()
   > {
--- a/tests/test-share.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-share.t	Tue Nov 22 18:16:59 2011 +0100
@@ -1,3 +1,4 @@
+  $ "$TESTDIR/hghave" serve || exit 80
 
   $ echo "[extensions]"      >> $HGRCPATH
   $ echo "share = "          >> $HGRCPATH
@@ -26,14 +27,14 @@
 Some sed versions appends newline, some don't, and some just fails
 
   $ cat .hg/sharedpath; echo
-  $TESTTMP/repo1/.hg
+  $TESTTMP/repo1/.hg (glob)
 
 trailing newline on .hg/sharedpath is ok
   $ hg tip -q
   0:d3873e73d99e
   $ echo '' >> .hg/sharedpath
   $ cat .hg/sharedpath
-  $TESTTMP/repo1/.hg
+  $TESTTMP/repo1/.hg (glob)
   $ hg tip -q
   0:d3873e73d99e
 
--- a/tests/test-static-http.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-static-http.t	Tue Nov 22 18:16:59 2011 +0100
@@ -1,3 +1,4 @@
+  $ "$TESTDIR/hghave" serve || exit 80
 
   $ hg clone http://localhost:$HGPORT/ copy
   abort: error: Connection refused
--- a/tests/test-status-color.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-status-color.t	Tue Nov 22 18:16:59 2011 +0100
@@ -1,3 +1,5 @@
+  $ "$TESTDIR/hghave" tic || exit 80
+
   $ echo "[extensions]" >> $HGRCPATH
   $ echo "color=" >> $HGRCPATH
   $ echo "[color]" >> $HGRCPATH
@@ -134,7 +136,7 @@
 hg status modified added removed deleted unknown never-existed ignored:
 
   $ hg status --color=always modified added removed deleted unknown never-existed ignored
-  never-existed: No such file or directory
+  never-existed: * (glob)
   \x1b[0;32;1mA added\x1b[0m (esc)
   \x1b[0;31;1mR removed\x1b[0m (esc)
   \x1b[0;36;1;4m! deleted\x1b[0m (esc)
@@ -280,10 +282,10 @@
   $ hg merge
   merging a
   warning: conflicts during merge.
-  merging a failed!
+  merging a incomplete! (edit conflicts, then use 'hg resolve --mark')
   merging b
   warning: conflicts during merge.
-  merging b failed!
+  merging b incomplete! (edit conflicts, then use 'hg resolve --mark')
   0 files updated, 0 files merged, 0 files removed, 2 files unresolved
   use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
   [1]
--- a/tests/test-status.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-status.t	Tue Nov 22 18:16:59 2011 +0100
@@ -127,7 +127,7 @@
 hg status modified added removed deleted unknown never-existed ignored:
 
   $ hg status modified added removed deleted unknown never-existed ignored
-  never-existed: No such file or directory
+  never-existed: * (glob)
   A added
   R removed
   ! deleted
--- a/tests/test-subrepo-deep-nested-change.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-subrepo-deep-nested-change.t	Tue Nov 22 18:16:59 2011 +0100
@@ -3,7 +3,7 @@
   $ hg init sub2
   $ echo sub2 > sub2/sub2
   $ hg add -R sub2
-  adding sub2/sub2
+  adding sub2/sub2 (glob)
   $ hg commit -R sub2 -m "sub2 import"
 
 Preparing the 'sub1' repo which depends on the subrepo 'sub2'
@@ -15,8 +15,8 @@
   updating to branch default
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
   $ hg add -R sub1
-  adding sub1/.hgsub
-  adding sub1/sub1
+  adding sub1/.hgsub (glob)
+  adding sub1/sub1 (glob)
   $ hg commit -R sub1 -m "sub1 import"
   committing subrepository sub2
 
@@ -30,8 +30,8 @@
   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
-  adding main/main
+  adding main/.hgsub (glob)
+  adding main/main (glob)
   $ hg commit -R main -m "main import"
   committing subrepository sub1
 
@@ -51,7 +51,7 @@
   $ hg clone main cloned
   updating to branch default
   cloning subrepo sub1 from $TESTTMP/sub1
-  cloning subrepo sub1/sub2 from $TESTTMP/sub2
+  cloning subrepo sub1/sub2 from $TESTTMP/sub2 (glob)
   3 files updated, 0 files merged, 0 files removed, 0 files unresolved
 
 Checking cloned repo ids
@@ -79,7 +79,7 @@
   $ echo modified > cloned/sub1/sub2/sub2
   $ hg commit --subrepos -m "deep nested modif should trigger a commit" -R cloned
   committing subrepository sub1
-  committing subrepository sub1/sub2
+  committing subrepository sub1/sub2 (glob)
 
 Checking modified node ids
 
--- a/tests/test-subrepo-paths.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-subrepo-paths.t	Tue Nov 22 18:16:59 2011 +0100
@@ -55,5 +55,5 @@
   > .* = \1
   > EOF
   $ hg debugsub
-  abort: bad subrepository pattern in $TESTTMP/outer/.hg/hgrc:2: invalid group reference
+  abort: bad subrepository pattern in $TESTTMP/outer/.hg/hgrc:2: invalid group reference (glob)
   [255]
--- a/tests/test-subrepo-recursion.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-subrepo-recursion.t	Tue Nov 22 18:16:59 2011 +0100
@@ -23,10 +23,10 @@
   $ hg add -S .hgsub
   $ hg add -S foo/.hgsub
   $ hg add -S foo/bar
-  adding foo/bar/z.txt
+  adding foo/bar/z.txt (glob)
   $ hg add -S
   adding x.txt
-  adding foo/y.txt
+  adding foo/y.txt (glob)
 
 Test recursive status without committing anything:
 
@@ -67,7 +67,7 @@
 
   $ hg commit -m 0-0-0 --config ui.commitsubrepos=No --subrepos
   committing subrepository foo
-  committing subrepository foo/bar
+  committing subrepository foo/bar (glob)
 
   $ cd foo
   $ echo y2 >> y.txt
@@ -186,7 +186,7 @@
   $ rm -r dir
   $ hg commit --subrepos -m 2-3-2
   committing subrepository foo
-  committing subrepository foo/bar
+  committing subrepository foo/bar (glob)
 
 Log with the relationships between repo and its subrepo:
 
@@ -265,10 +265,10 @@
   archiving (foo) [====================================>] 3/3
   archiving (foo) [====================================>] 3/3
                                                               
-  archiving (foo/bar) [                                 ] 0/1
-  archiving (foo/bar) [                                 ] 0/1
-  archiving (foo/bar) [================================>] 1/1
-  archiving (foo/bar) [================================>] 1/1
+  archiving (foo/bar) [                                 ] 0/1 (glob)
+  archiving (foo/bar) [                                 ] 0/1 (glob)
+  archiving (foo/bar) [================================>] 1/1 (glob)
+  archiving (foo/bar) [================================>] 1/1 (glob)
                                                               \r (esc)
   $ find ../archive | sort
   ../archive
@@ -305,10 +305,10 @@
   archiving (foo) [====================================>] 3/3
   archiving (foo) [====================================>] 3/3
                                                               
-  archiving (foo/bar) [                                 ] 0/1
-  archiving (foo/bar) [                                 ] 0/1
-  archiving (foo/bar) [================================>] 1/1
-  archiving (foo/bar) [================================>] 1/1
+  archiving (foo/bar) [                                 ] 0/1 (glob)
+  archiving (foo/bar) [                                 ] 0/1 (glob)
+  archiving (foo/bar) [================================>] 1/1 (glob)
+  archiving (foo/bar) [================================>] 1/1 (glob)
                                                               \r (esc)
 
 Test archiving a revision that references a subrepo that is not yet
@@ -336,13 +336,13 @@
   archiving (foo) [====================================>] 3/3
   archiving (foo) [====================================>] 3/3
                                                               
-  archiving (foo/bar) [                                 ] 0/1
-  archiving (foo/bar) [                                 ] 0/1
-  archiving (foo/bar) [================================>] 1/1
-  archiving (foo/bar) [================================>] 1/1
+  archiving (foo/bar) [                                 ] 0/1 (glob)
+  archiving (foo/bar) [                                 ] 0/1 (glob)
+  archiving (foo/bar) [================================>] 1/1 (glob)
+  archiving (foo/bar) [================================>] 1/1 (glob)
                                                               
   cloning subrepo foo from $TESTTMP/repo/foo
-  cloning subrepo foo/bar from $TESTTMP/repo/foo/bar
+  cloning subrepo foo/bar from $TESTTMP/repo/foo/bar (glob)
   
 The newly cloned subrepos contain no working copy:
 
@@ -365,7 +365,7 @@
   $ echo f > foo/f
   $ hg archive --subrepos -r tip archive
   cloning subrepo foo from $TESTTMP/empty/foo
-  abort: destination '$TESTTMP/almost-empty/foo' is not empty
+  abort: destination '$TESTTMP/almost-empty/foo' is not empty (glob)
   [255]
 
 Clone and test outgoing:
@@ -374,11 +374,11 @@
   $ hg clone repo repo2
   updating to branch default
   cloning subrepo foo from $TESTTMP/repo/foo
-  cloning subrepo foo/bar from $TESTTMP/repo/foo/bar
+  cloning subrepo foo/bar from $TESTTMP/repo/foo/bar (glob)
   3 files updated, 0 files merged, 0 files removed, 0 files unresolved
   $ cd repo2
   $ hg outgoing -S
-  comparing with $TESTTMP/repo
+  comparing with $TESTTMP/repo (glob)
   searching for changes
   no changes found
   comparing with $TESTTMP/repo/foo
@@ -404,7 +404,7 @@
   $ hg commit --subrepos -m 3-4-2
   committing subrepository foo
   $ hg outgoing -S
-  comparing with $TESTTMP/repo
+  comparing with $TESTTMP/repo (glob)
   searching for changes
   changeset:   3:2655b8ecc4ee
   tag:         tip
@@ -434,7 +434,7 @@
 Test incoming:
 
   $ hg incoming -S
-  comparing with $TESTTMP/repo2
+  comparing with $TESTTMP/repo2 (glob)
   searching for changes
   changeset:   3:2655b8ecc4ee
   tag:         tip
--- a/tests/test-subrepo-relative-path.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-subrepo-relative-path.t	Tue Nov 22 18:16:59 2011 +0100
@@ -1,9 +1,11 @@
+  $ "$TESTDIR/hghave" serve || exit 80
+
 Preparing the subrepository 'sub'
 
   $ hg init sub
   $ echo sub > sub/sub
   $ hg add -R sub
-  adding sub/sub
+  adding sub/sub (glob)
   $ hg commit -R sub -m "sub import"
 
 Preparing the 'main' repo which depends on the subrepo 'sub'
@@ -15,8 +17,8 @@
   updating to branch default
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
   $ hg add -R main
-  adding main/.hgsub
-  adding main/main
+  adding main/.hgsub (glob)
+  adding main/main (glob)
   $ hg commit -R main -m "main import"
   committing subrepository sub
 
--- a/tests/test-subrepo.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-subrepo.t	Tue Nov 22 18:16:59 2011 +0100
@@ -49,7 +49,7 @@
 
   $ hg revert -a
   $ hg revert -R s -a -C
-  reverting s/a
+  reverting s/a (glob)
 
 Issue2022: update -C
 
@@ -92,7 +92,7 @@
   update: (current)
   $ hg ci -m2
   committing subrepository s
-  committing subrepository s/ss
+  committing subrepository s/ss (glob)
   $ hg sum
   parent: 2:df30734270ae tip
    2
@@ -147,7 +147,7 @@
   $ hg init t
   $ echo t > t/t
   $ hg -R t add t
-  adding t/t
+  adding t/t (glob)
 
 5
 
@@ -245,7 +245,7 @@
   merging t
   my t@20a0db6fbf6c+ other t@7af322bc1198 ancestor t@6747d179aa9a
   warning: conflicts during merge.
-  merging t failed!
+  merging t incomplete! (edit conflicts, then use 'hg resolve --mark')
   0 files updated, 0 files merged, 0 files removed, 1 files unresolved
   use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
   0 files updated, 0 files merged, 0 files removed, 0 files unresolved
@@ -265,9 +265,9 @@
   $ cd ..
   $ hg clone t tc
   updating to branch default
-  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
+  cloning subrepo s from $TESTTMP/sub/t/s (glob)
+  cloning subrepo s/ss from $TESTTMP/sub/t/s/ss (glob)
+  cloning subrepo t from $TESTTMP/sub/t/t (glob)
   3 files updated, 0 files merged, 0 files removed, 0 files unresolved
   $ cd tc
   $ hg debugsub
@@ -284,14 +284,14 @@
   $ hg ci -m11
   committing subrepository t
   $ hg push
-  pushing to $TESTTMP/sub/t
-  pushing subrepo s/ss to $TESTTMP/sub/t/s/ss
+  pushing to $TESTTMP/sub/t (glob)
+  pushing subrepo s/ss to $TESTTMP/sub/t/s/ss (glob)
   searching for changes
   no changes found
-  pushing subrepo s to $TESTTMP/sub/t/s
+  pushing subrepo s to $TESTTMP/sub/t/s (glob)
   searching for changes
   no changes found
-  pushing subrepo t to $TESTTMP/sub/t/t
+  pushing subrepo t to $TESTTMP/sub/t/t (glob)
   searching for changes
   adding changesets
   adding manifests
@@ -309,27 +309,27 @@
   $ hg ci -m12
   committing subrepository s
   $ hg push
-  pushing to $TESTTMP/sub/t
-  pushing subrepo s/ss to $TESTTMP/sub/t/s/ss
+  pushing to $TESTTMP/sub/t (glob)
+  pushing subrepo s/ss to $TESTTMP/sub/t/s/ss (glob)
   searching for changes
   no changes found
-  pushing subrepo s to $TESTTMP/sub/t/s
+  pushing subrepo s to $TESTTMP/sub/t/s (glob)
   searching for changes
   abort: push creates new remote head 12a213df6fa9!
   (did you forget to merge? use push -f to force)
   [255]
   $ hg push -f
-  pushing to $TESTTMP/sub/t
-  pushing subrepo s/ss to $TESTTMP/sub/t/s/ss
+  pushing to $TESTTMP/sub/t (glob)
+  pushing subrepo s/ss to $TESTTMP/sub/t/s/ss (glob)
   searching for changes
   no changes found
-  pushing subrepo s to $TESTTMP/sub/t/s
+  pushing subrepo s to $TESTTMP/sub/t/s (glob)
   searching for changes
   adding changesets
   adding manifests
   adding file changes
   added 1 changesets with 1 changes to 1 files (+1 heads)
-  pushing subrepo t to $TESTTMP/sub/t/t
+  pushing subrepo t to $TESTTMP/sub/t/t (glob)
   searching for changes
   no changes found
   searching for changes
@@ -351,7 +351,7 @@
 
   $ cd ../tc
   $ hg pull
-  pulling from $TESTTMP/sub/t
+  pulling from $TESTTMP/sub/t (glob)
   searching for changes
   adding changesets
   adding manifests
@@ -362,7 +362,7 @@
 should pull t
 
   $ hg up
-  pulling subrepo t from $TESTTMP/sub/t/t
+  pulling subrepo t from $TESTTMP/sub/t/t (glob)
   searching for changes
   adding changesets
   adding manifests
@@ -507,15 +507,15 @@
   $ echo test > testdelete/nested/foo
   $ echo test > testdelete/nested2/foo
   $ hg -R testdelete/nested add
-  adding testdelete/nested/foo
+  adding testdelete/nested/foo (glob)
   $ hg -R testdelete/nested2 add
-  adding testdelete/nested2/foo
+  adding testdelete/nested2/foo (glob)
   $ hg -R testdelete/nested ci -m test
   $ hg -R testdelete/nested2 ci -m test
   $ echo nested = nested > testdelete/.hgsub
   $ echo nested2 = nested2 >> testdelete/.hgsub
   $ hg -R testdelete add
-  adding testdelete/.hgsub
+  adding testdelete/.hgsub (glob)
   $ hg -R testdelete ci -m "nested 1 & 2 added"
   committing subrepository nested
   committing subrepository nested2
@@ -534,19 +534,19 @@
   $ hg init nested_absolute
   $ echo test > nested_absolute/foo
   $ hg -R nested_absolute add
-  adding nested_absolute/foo
+  adding nested_absolute/foo (glob)
   $ hg -R nested_absolute ci -mtest
   $ cd mercurial
   $ hg init nested_relative
   $ echo test2 > nested_relative/foo2
   $ hg -R nested_relative add
-  adding nested_relative/foo2
+  adding nested_relative/foo2 (glob)
   $ hg -R nested_relative ci -mtest2
   $ hg init main
   $ echo "nested_relative = ../nested_relative" > main/.hgsub
   $ echo "nested_absolute = `pwd`/nested_absolute" >> main/.hgsub
   $ hg -R main add
-  adding main/.hgsub
+  adding main/.hgsub (glob)
   $ hg -R main ci -m "add subrepos"
   committing subrepository nested_absolute
   committing subrepository nested_relative
@@ -575,7 +575,7 @@
   committing subrepository s
   $ hg clone repo repo2
   updating to branch default
-  cloning subrepo s from $TESTTMP/sub/repo/s
+  cloning subrepo s from $TESTTMP/sub/repo/s (glob)
   2 files updated, 0 files merged, 0 files removed, 0 files unresolved
   $ hg -q -R repo2 pull -u
   $ echo 1 > repo2/s/a
@@ -609,10 +609,10 @@
   $ echo sub/repo = sub/repo > .hgsub
   $ hg add .hgsub
   $ hg ci -mtest
-  committing subrepository sub/repo
+  committing subrepository sub/repo (glob)
   $ echo test >> sub/repo/foo
   $ hg ci -mtest
-  committing subrepository sub/repo
+  committing subrepository sub/repo (glob)
   $ cd ..
 
 Create repo without default path, pull top repo, and see what happens on update
@@ -627,7 +627,7 @@
   added 2 changesets with 3 changes to 2 files
   (run 'hg update' to get a working copy)
   $ hg -R issue1852b update
-  abort: default path for subrepository sub/repo not found
+  abort: default path for subrepository sub/repo not found (glob)
   [255]
 
 Pull -u now doesn't help
@@ -646,14 +646,14 @@
   adding manifests
   adding file changes
   added 1 changesets with 2 changes to 2 files
-  cloning subrepo sub/repo from issue1852a/sub/repo
+  cloning subrepo sub/repo from issue1852a/sub/repo (glob)
   2 files updated, 0 files merged, 0 files removed, 0 files unresolved
 
 Try to push from the other side
 
   $ hg -R issue1852a push `pwd`/issue1852c
   pushing to $TESTTMP/sub/issue1852c
-  pushing subrepo sub/repo to $TESTTMP/sub/issue1852c/sub/repo
+  pushing subrepo sub/repo to $TESTTMP/sub/issue1852c/sub/repo (glob)
   searching for changes
   no changes found
   searching for changes
@@ -883,3 +883,135 @@
   rm2
   
   
+Test behavior of add for explicit path in subrepo:
+  $ cd ..
+  $ hg init explicit
+  $ cd explicit
+  $ echo s = s > .hgsub
+  $ hg add .hgsub
+  $ hg init s
+  $ hg ci -m0
+  committing subrepository s
+Adding with an explicit path in a subrepo adds the file
+  $ echo c1 > f1
+  $ echo c2 > s/f2
+  $ hg st -S
+  ? f1
+  ? s/f2
+  $ hg add s/f2
+  $ hg st -S
+  A s/f2
+  ? f1
+  $ hg ci -R s -m0
+  $ hg ci -Am1
+  adding f1
+  committing subrepository s
+Adding with an explicit path in a subrepo with -S has the same behavior
+  $ echo c3 > f3
+  $ echo c4 > s/f4
+  $ hg st -S
+  ? f3
+  ? s/f4
+  $ hg add -S s/f4
+  $ hg st -S
+  A s/f4
+  ? f3
+  $ hg ci -R s -m1
+  $ hg ci -Ama2
+  adding f3
+  committing subrepository s
+Adding without a path or pattern silently ignores subrepos
+  $ echo c5 > f5
+  $ echo c6 > s/f6
+  $ echo c7 > s/f7
+  $ hg st -S
+  ? f5
+  ? s/f6
+  ? s/f7
+  $ hg add
+  adding f5
+  $ hg st -S
+  A f5
+  ? s/f6
+  ? s/f7
+  $ hg ci -R s -Am2
+  adding f6
+  adding f7
+  $ hg ci -m3
+  committing subrepository s
+Adding without a path or pattern with -S also adds files in subrepos
+  $ echo c8 > f8
+  $ echo c9 > s/f9
+  $ echo c10 > s/f10
+  $ hg st -S
+  ? f8
+  ? s/f10
+  ? s/f9
+  $ hg add -S
+  adding f8
+  adding s/f10 (glob)
+  adding s/f9 (glob)
+  $ hg st -S
+  A f8
+  A s/f10
+  A s/f9
+  $ hg ci -R s -m3
+  $ hg ci -m4
+  committing subrepository s
+Adding with a pattern silently ignores subrepos
+  $ echo c11 > fm11
+  $ echo c12 > fn12
+  $ echo c13 > s/fm13
+  $ echo c14 > s/fn14
+  $ hg st -S
+  ? fm11
+  ? fn12
+  ? s/fm13
+  ? s/fn14
+  $ hg add 'glob:**fm*'
+  adding fm11
+  $ hg st -S
+  A fm11
+  ? fn12
+  ? s/fm13
+  ? s/fn14
+  $ hg ci -R s -Am4
+  adding fm13
+  adding fn14
+  $ hg ci -Am5
+  adding fn12
+  committing subrepository s
+Adding with a pattern with -S also adds matches in subrepos
+  $ echo c15 > fm15
+  $ echo c16 > fn16
+  $ echo c17 > s/fm17
+  $ echo c18 > s/fn18
+  $ hg st -S
+  ? fm15
+  ? fn16
+  ? s/fm17
+  ? s/fn18
+  $ hg add -S 'glob:**fm*'
+  adding fm15
+  adding s/fm17 (glob)
+  $ hg st -S
+  A fm15
+  A s/fm17
+  ? fn16
+  ? s/fn18
+  $ hg ci -R s -Am5
+  adding fn18
+  $ hg ci -Am6
+  adding fn16
+  committing subrepository s
+
+Test behavior of forget for explicit path in subrepo:
+Forgetting an explicit path in a subrepo untracks the file
+  $ echo c19 > s/f19
+  $ hg add s/f19
+  $ hg st -S
+  A s/f19
+  $ hg forget s/f19
+  $ hg st -S
+  ? s/f19
+  $ rm s/f19
--- a/tests/test-symlink-placeholder.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-symlink-placeholder.t	Tue Nov 22 18:16:59 2011 +0100
@@ -1,3 +1,5 @@
+  $ "$TESTDIR/hghave" symlink || exit 80
+
 Create extension that can disable symlink support:
 
   $ cat > nolink.py <<EOF
--- a/tests/test-tag.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-tag.t	Tue Nov 22 18:16:59 2011 +0100
@@ -1,3 +1,5 @@
+  $ "$TESTDIR/hghave" system-sh || exit 80
+
   $ hg init test
   $ cd test
 
--- a/tests/test-tags.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-tags.t	Tue Nov 22 18:16:59 2011 +0100
@@ -1,3 +1,5 @@
+  $ "$TESTDIR/hghave" unix-permissions || exit 80
+
 Helper functions:
 
   $ cacheexists() {
--- a/tests/test-transplant.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-transplant.t	Tue Nov 22 18:16:59 2011 +0100
@@ -1,3 +1,5 @@
+  $ "$TESTDIR/hghave" serve || exit 80
+
   $ cat <<EOF >> $HGRCPATH
   > [extensions]
   > transplant=
--- a/tests/test-treediscovery-legacy.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-treediscovery-legacy.t	Tue Nov 22 18:16:59 2011 +0100
@@ -1,3 +1,5 @@
+  $ "$TESTDIR/hghave" serve || exit 80
+
 Tests discovery against servers without getbundle support:
 
   $ cat >> $HGRCPATH <<EOF
--- a/tests/test-treediscovery.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-treediscovery.t	Tue Nov 22 18:16:59 2011 +0100
@@ -1,3 +1,5 @@
+  $ "$TESTDIR/hghave" serve || exit 80
+
 Tests discovery against servers without getbundle support:
 
   $ CAP=getbundle
--- a/tests/test-unbundlehash.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-unbundlehash.t	Tue Nov 22 18:16:59 2011 +0100
@@ -1,3 +1,4 @@
+  $ "$TESTDIR/hghave" serve || exit 80
 
 Test wire protocol unbundle with hashed heads (capability: unbundlehash)
 
--- a/tests/test-update-issue1456.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-update-issue1456.t	Tue Nov 22 18:16:59 2011 +0100
@@ -1,3 +1,5 @@
+  $ "$TESTDIR/hghave" execbit || exit 80
+
   $ rm -rf a
   $ hg init a
   $ cd a
--- a/tests/test-update-renames.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-update-renames.t	Tue Nov 22 18:16:59 2011 +0100
@@ -21,7 +21,7 @@
   $ hg up
   merging a and b to b
   warning: conflicts during merge.
-  merging b failed!
+  merging b incomplete! (edit conflicts, then use 'hg resolve --mark')
   0 files updated, 0 files merged, 0 files removed, 1 files unresolved
   use 'hg resolve' to retry unresolved file merges
   [1]
--- a/tests/test-url-rev.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-url-rev.t	Tue Nov 22 18:16:59 2011 +0100
@@ -41,7 +41,7 @@
   
   $ cat clone/.hg/hgrc
   [paths]
-  default = $TESTTMP/repo#foo
+  default = $TESTTMP/repo#foo (glob)
 
 Changing original repo:
 
--- a/tests/test-url.py	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-url.py	Tue Nov 22 18:16:59 2011 +0100
@@ -219,7 +219,7 @@
     >>> u
     <url scheme: 'file', path: 'f:oo/bar/baz'>
     >>> str(u)
-    'file:f%3Aoo/bar/baz'
+    'file:f:oo/bar/baz'
     >>> u.localpath()
     'f:oo/bar/baz'
 
@@ -227,7 +227,7 @@
     >>> u
     <url scheme: 'file', host: 'localhost', path: 'f:oo/bar/baz'>
     >>> str(u)
-    'file://localhost/f%3Aoo/bar/baz'
+    'file://localhost/f:oo/bar/baz'
     >>> u.localpath()
     'f:oo/bar/baz'
 
--- a/tests/test-walk.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-walk.t	Tue Nov 22 18:16:59 2011 +0100
@@ -1,3 +1,5 @@
+  $ "$TESTDIR/hghave" no-windows || exit 80
+
   $ hg init t
   $ cd t
   $ mkdir -p beans
@@ -272,7 +274,7 @@
   f  mammals/skunk                   mammals/skunk
   $ hg debugwalk 'glob:j*'
   $ hg debugwalk NOEXIST
-  NOEXIST: No such file or directory
+  NOEXIST: * (glob)
 
   $ mkfifo fifo
   $ hg debugwalk fifo
--- a/tests/test-win32text.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-win32text.t	Tue Nov 22 18:16:59 2011 +0100
@@ -112,7 +112,7 @@
   abort: pretxncommit.crlf hook failed
   [255]
   $ hg revert -a
-  forgetting d/f2
+  forgetting d/f2 (glob)
   $ rm d/f2
 
   $ hg rem f
@@ -177,10 +177,10 @@
 
   $ for x in a b c d; do echo content > dupe/$x; done
   $ hg -R dupe add
-  adding dupe/a
-  adding dupe/b
-  adding dupe/c
-  adding dupe/d
+  adding dupe/a (glob)
+  adding dupe/b (glob)
+  adding dupe/c (glob)
+  adding dupe/d (glob)
   $ python unix2dos.py dupe/b dupe/c dupe/d
   $ hg -R dupe ci -m a dupe/a
   $ hg -R dupe ci -m b/c dupe/[bc]
@@ -385,7 +385,7 @@
   WARNING: f4.bat already has CRLF line endings
   and does not need EOL conversion by the win32text plugin.
   Before your next commit, please reconsider your encode/decode settings in 
-  Mercurial.ini or $TESTTMP/t/.hg/hgrc.
+  Mercurial.ini or $TESTTMP/t/.hg/hgrc. (glob)
   3 files updated, 0 files merged, 0 files removed, 0 files unresolved
   $ cat bin
   hello\x00\r (esc)
--- a/tests/test-wireproto.t	Tue Nov 22 17:51:43 2011 +0100
+++ b/tests/test-wireproto.t	Tue Nov 22 18:16:59 2011 +0100
@@ -1,3 +1,4 @@
+  $ "$TESTDIR/hghave" serve || exit 80
 
 Test wire protocol argument passing