merge with stable
authorMads Kiilerich <madski@unity3d.com>
Wed, 06 Feb 2013 13:22:01 +0100
changeset 18562 37010a55922a
parent 18560 acf4a405e440 (diff)
parent 18561 7365d031d457 (current diff)
child 18564 2fefd1170bf2
merge with stable
--- a/hgext/largefiles/basestore.py	Tue Feb 05 12:58:21 2013 +0100
+++ b/hgext/largefiles/basestore.py	Wed Feb 06 13:22:01 2013 +0100
@@ -96,10 +96,10 @@
         '''Verify the existence (and, optionally, contents) of every big
         file revision referenced by every changeset in revs.
         Return 0 if all is well, non-zero on any errors.'''
-        write = self.ui.write
         failed = False
 
-        write(_('searching %d changesets for largefiles\n') % len(revs))
+        self.ui.status(_('searching %d changesets for largefiles\n') %
+                       len(revs))
         verified = set()                # set of (filename, filenode) tuples
 
         for rev in revs:
@@ -113,12 +113,13 @@
         numrevs = len(verified)
         numlfiles = len(set([fname for (fname, fnode) in verified]))
         if contents:
-            write(_('verified contents of %d revisions of %d largefiles\n')
-                  % (numrevs, numlfiles))
+            self.ui.status(
+                _('verified contents of %d revisions of %d largefiles\n')
+                % (numrevs, numlfiles))
         else:
-            write(_('verified existence of %d revisions of %d largefiles\n')
-                  % (numrevs, numlfiles))
-
+            self.ui.status(
+                _('verified existence of %d revisions of %d largefiles\n')
+                % (numrevs, numlfiles))
         return int(failed)
 
     def _getfile(self, tmpfile, filename, hash):
--- a/hgext/largefiles/localstore.py	Tue Feb 05 12:58:21 2013 +0100
+++ b/hgext/largefiles/localstore.py	Wed Feb 06 13:22:01 2013 +0100
@@ -63,23 +63,19 @@
             return False
 
         expecthash = fctx.data()[0:40]
+        storepath = lfutil.storepath(self.remote, expecthash)
         verified.add(key)
         if not lfutil.instore(self.remote, expecthash):
             self.ui.warn(
-                _('changeset %s: %s missing\n'
-                  '  (looked for hash %s)\n')
-                % (cset, filename, expecthash))
+                _('changeset %s: %s references missing %s\n')
+                % (cset, filename, storepath))
             return True                 # failed
 
         if contents:
-            storepath = lfutil.storepath(self.remote, expecthash)
             actualhash = lfutil.hashfile(storepath)
             if actualhash != expecthash:
                 self.ui.warn(
-                    _('changeset %s: %s: contents differ\n'
-                      '  (%s:\n'
-                      '  expected hash %s,\n'
-                      '  but got %s)\n')
-                    % (cset, filename, storepath, expecthash, actualhash))
+                    _('changeset %s: %s references corrupted %s\n')
+                    % (cset, filename, storepath))
                 return True             # failed
         return False
--- a/hgext/largefiles/overrides.py	Tue Feb 05 12:58:21 2013 +0100
+++ b/hgext/largefiles/overrides.py	Wed Feb 06 13:22:01 2013 +0100
@@ -274,7 +274,7 @@
     contents = opts.pop('lfc', False)
 
     result = orig(ui, repo, *pats, **opts)
-    if large:
+    if large or all or contents:
         result = result or lfcommands.verifylfiles(ui, repo, all, contents)
     return result
 
@@ -368,7 +368,7 @@
         if overwrite:
             processed.append(action)
             continue
-        f, m = action[:2]
+        f, m, args, msg = action
 
         choices = (_('&Largefile'), _('&Normal file'))
         if m == "g" and lfutil.splitstandin(f) in p1 and f in p2:
@@ -379,10 +379,10 @@
             msg = _('%s has been turned into a largefile\n'
                     'use (l)argefile or keep as (n)ormal file?') % lfile
             if repo.ui.promptchoice(msg, choices, 0) == 0:
-                processed.append((lfile, "r"))
-                processed.append((standin, "g", p2.flags(standin)))
+                processed.append((lfile, "r", None, msg))
+                processed.append((standin, "g", (p2.flags(standin),), msg))
             else:
-                processed.append((standin, "r"))
+                processed.append((standin, "r", None, msg))
         elif m == "g" and lfutil.standin(f) in p1 and f in p2:
             # Case 2: largefile in the working copy, normal file in
             # the second parent
@@ -391,10 +391,10 @@
             msg = _('%s has been turned into a normal file\n'
                     'keep as (l)argefile or use (n)ormal file?') % lfile
             if repo.ui.promptchoice(msg, choices, 0) == 0:
-                processed.append((lfile, "r"))
+                processed.append((lfile, "r", None, msg))
             else:
-                processed.append((standin, "r"))
-                processed.append((lfile, "g", p2.flags(lfile)))
+                processed.append((standin, "r", None, msg))
+                processed.append((lfile, "g", (p2.flags(lfile),), msg))
         else:
             processed.append(action)
 
--- a/hgext/largefiles/uisetup.py	Tue Feb 05 12:58:21 2013 +0100
+++ b/hgext/largefiles/uisetup.py	Wed Feb 06 13:22:01 2013 +0100
@@ -52,11 +52,12 @@
     entry = extensions.wrapcommand(commands.table, 'verify',
                                    overrides.overrideverify)
 
-    verifyopt = [('', 'large', None, _('verify largefiles')),
+    verifyopt = [('', 'large', None,
+                  _('verify that all largefiles in current revision exists')),
                  ('', 'lfa', None,
-                     _('verify all revisions of largefiles not just current')),
+                  _('verify largefiles in all revisions, not just current')),
                  ('', 'lfc', None,
-                     _('verify largefile contents not just existence'))]
+                  _('verify local largefile contents, not just existence'))]
     entry[1].extend(verifyopt)
 
     entry = extensions.wrapcommand(commands.table, 'debugstate',
--- a/mercurial/bdiff.c	Tue Feb 05 12:58:21 2013 +0100
+++ b/mercurial/bdiff.c	Wed Feb 06 13:22:01 2013 +0100
@@ -347,6 +347,11 @@
 	if (!PyArg_ParseTuple(args, "s#s#:bdiff", &sa, &la, &sb, &lb))
 		return NULL;
 
+	if (la > UINT_MAX || lb > UINT_MAX) {
+		PyErr_SetString(PyExc_ValueError, "bdiff inputs too large");
+		return NULL;
+	}
+
 	_save = PyEval_SaveThread();
 	an = splitlines(sa, la, &al);
 	bn = splitlines(sb, lb, &bl);
@@ -381,18 +386,9 @@
 	for (h = l.next; h; h = h->next) {
 		if (h->a1 != la || h->b1 != lb) {
 			len = bl[h->b1].l - bl[lb].l;
-
-#define checkputbe32(__x, __c) \
-	if (__x > UINT_MAX) { \
-		PyErr_SetString(PyExc_ValueError, \
-		                "bdiff: value too large for putbe32"); \
-		goto nomem; \
-	} \
-	putbe32((uint32_t)(__x), __c);
-
-			checkputbe32(al[la].l - al->l, rb);
-			checkputbe32(al[h->a1].l - al->l, rb + 4);
-			checkputbe32(len, rb + 8);
+			putbe32((uint32_t)(al[la].l - al->l), rb);
+			putbe32((uint32_t)(al[h->a1].l - al->l), rb + 4);
+			putbe32((uint32_t)len, rb + 8);
 			memcpy(rb + 12, bl[lb].l, len);
 			rb += 12 + len;
 		}
--- a/mercurial/cmdutil.py	Tue Feb 05 12:58:21 2013 +0100
+++ b/mercurial/cmdutil.py	Wed Feb 06 13:22:01 2013 +0100
@@ -12,6 +12,7 @@
 import match as matchmod
 import subrepo, context, repair, graphmod, revset, phases, obsolete
 import changelog
+import bookmarks
 import lock as lockmod
 
 def parsealiases(cmd):
@@ -1793,6 +1794,8 @@
         edittext.append(_("HG: branch merge"))
     if ctx.branch():
         edittext.append(_("HG: branch '%s'") % ctx.branch())
+    if bookmarks.iscurrent(repo):
+        edittext.append(_("HG: bookmark '%s'") % repo._bookmarkcurrent)
     edittext.extend([_("HG: subrepo %s") % s for s in subs])
     edittext.extend([_("HG: added %s") % f for f in added])
     edittext.extend([_("HG: changed %s") % f for f in modified])
--- a/mercurial/dispatch.py	Tue Feb 05 12:58:21 2013 +0100
+++ b/mercurial/dispatch.py	Wed Feb 06 13:22:01 2013 +0100
@@ -748,6 +748,7 @@
 def lsprofile(ui, func, fp):
     format = ui.config('profiling', 'format', default='text')
     field = ui.config('profiling', 'sort', default='inlinetime')
+    limit = ui.configint('profiling', 'limit', default=30)
     climit = ui.configint('profiling', 'nested', default=5)
 
     if format not in ['text', 'kcachegrind']:
@@ -776,7 +777,7 @@
             # format == 'text'
             stats = lsprof.Stats(p.getstats())
             stats.sort(field)
-            stats.pprint(limit=30, file=fp, climit=climit)
+            stats.pprint(limit=limit, file=fp, climit=climit)
 
 def statprofile(ui, func, fp):
     try:
--- a/mercurial/help/config.txt	Tue Feb 05 12:58:21 2013 +0100
+++ b/mercurial/help/config.txt	Wed Feb 06 13:22:01 2013 +0100
@@ -996,6 +996,10 @@
     ``inlinetime``.
     Default: inlinetime.
 
+``limit``
+    Number of lines to show. Specific to the ``ls`` instrumenting profiler.
+    Default: 30.
+
 ``nested``
     Show at most this number of lines of drill-down info in a tree structure
     after each main entry. This can help explain the difference between Total
--- a/mercurial/help/dates.txt	Tue Feb 05 12:58:21 2013 +0100
+++ b/mercurial/help/dates.txt	Wed Feb 06 13:22:01 2013 +0100
@@ -18,6 +18,8 @@
 - ``12-6``
 - ``12/6``
 - ``12/6/6`` (Dec 6 2006)
+- ``today`` (midnight)
+- ``yesterday`` (midnight)
 
 Lastly, there is Mercurial's internal format:
 
--- a/mercurial/merge.py	Tue Feb 05 12:58:21 2013 +0100
+++ b/mercurial/merge.py	Wed Feb 06 13:22:01 2013 +0100
@@ -176,12 +176,12 @@
     state = branchmerge and 'r' or 'f'
     for f in wctx.deleted():
         if f not in mctx:
-            actions.append((f, state))
+            actions.append((f, state, None, "forget deleted"))
 
     if not branchmerge:
         for f in wctx.removed():
             if f not in mctx:
-                actions.append((f, "f"))
+                actions.append((f, "f", None, "forget removed"))
 
     return actions
 
@@ -193,10 +193,6 @@
     partial = function to filter file lists
     """
 
-    def act(msg, m, f, *args):
-        repo.ui.debug(" %s: %s -> %s\n" % (f, msg, m))
-        actions.append((f, m) + args)
-
     actions, copy, movewithdir = [], {}, {}
 
     if overwrite:
@@ -207,9 +203,9 @@
         ret = copies.mergecopies(repo, p1, p2, pa)
         copy, movewithdir, diverge, renamedelete = ret
         for of, fl in diverge.iteritems():
-            act("divergent renames", "dr", of, fl)
+            actions.append((of, "dr", (fl,), "divergent renames"))
         for of, fl in renamedelete.iteritems():
-            act("rename and delete", "rd", of, fl)
+            actions.append((of, "rd", (fl,), "rename and delete"))
 
     repo.ui.note(_("resolving manifests\n"))
     repo.ui.debug(" overwrite: %s, partial: %s\n"
@@ -227,11 +223,9 @@
                 m1['.hgsubstate'] += "+"
                 break
 
+    prompts = []
     # Compare manifests
-    visit = m1.iteritems()
-    if repo.ui.debugflag:
-        visit = sorted(visit)
-    for f, n in visit:
+    for f, n in m1.iteritems():
         if partial and not partial(f):
             continue
         if f in m2:
@@ -245,72 +239,76 @@
                 pass # remote unchanged - keep local
             elif n == a and fl1 == fla: # local unchanged - use remote
                 if n == n2: # optimization: keep local content
-                    act("update permissions", "e", f, fl2)
+                    actions.append((f, "e", (fl2,), "update permissions"))
                 else:
-                    act("remote is newer", "g", f, fl2)
+                    actions.append((f, "g", (fl2,), "remote is newer"))
             elif nol and n2 == a: # remote only changed 'x'
-                act("update permissions", "e", f, fl2)
+                actions.append((f, "e", (fl2,), "update permissions"))
             elif nol and n == a: # local only changed 'x'
-                act("remote is newer", "g", f, fl1)
+                actions.append((f, "g", (fl1,), "remote is newer"))
             else: # both changed something
-                act("versions differ", "m", f, f, f, False)
+                actions.append((f, "m", (f, f, False), "versions differ"))
         elif f in copied: # files we'll deal with on m2 side
             pass
         elif f in movewithdir: # directory rename
             f2 = movewithdir[f]
-            act("remote renamed directory to " + f2, "d", f, None, f2,
-                m1.flags(f))
+            actions.append((f, "d", (None, f2, m1.flags(f)),
+                            "remote renamed directory to " + f2))
         elif f in copy:
             f2 = copy[f]
-            act("local copied/moved to " + f2, "m", f, f2, f, False)
+            actions.append((f, "m", (f2, f, False),
+                            "local copied/moved to " + f2))
         elif f in ma: # clean, a different, no remote
             if n != ma[f]:
-                if repo.ui.promptchoice(
-                    _(" local changed %s which remote deleted\n"
-                      "use (c)hanged version or (d)elete?") % f,
-                    (_("&Changed"), _("&Delete")), 0):
-                    act("prompt delete", "r", f)
-                else:
-                    act("prompt keep", "a", f)
+                prompts.append((f, "cd")) # prompt changed/deleted
             elif n[20:] == "a": # added, no remote
-                act("remote deleted", "f", f)
+                actions.append((f, "f", None, "remote deleted"))
             else:
-                act("other deleted", "r", f)
+                actions.append((f, "r", None, "other deleted"))
 
-    visit = m2.iteritems()
-    if repo.ui.debugflag:
-        visit = sorted(visit)
-    for f, n in visit:
+    for f, n in m2.iteritems():
         if partial and not partial(f):
             continue
         if f in m1 or f in copied: # files already visited
             continue
         if f in movewithdir:
             f2 = movewithdir[f]
-            act("local renamed directory to " + f2, "d", None, f, f2,
-                m2.flags(f))
+            actions.append((None, "d", (f, f2, m2.flags(f)),
+                            "local renamed directory to " + f2))
         elif f in copy:
             f2 = copy[f]
             if f2 in m2:
-                act("remote copied to " + f, "m",
-                    f2, f, f, False)
+                actions.append((f2, "m", (f, f, False),
+                                "remote copied to " + f))
             else:
-                act("remote moved to " + f, "m",
-                    f2, f, f, True)
+                actions.append((f2, "m", (f, f, True),
+                                "remote moved to " + f))
         elif f not in ma:
             if (not overwrite
                 and _checkunknownfile(repo, p1, p2, f)):
-                act("remote differs from untracked local",
-                    "m", f, f, f, False)
+                actions.append((f, "m", (f, f, False),
+                                "remote differs from untracked local"))
             else:
-                act("remote created", "g", f, m2.flags(f))
+                actions.append((f, "g", (m2.flags(f),), "remote created"))
         elif n != ma[f]:
+            prompts.append((f, "dc")) # prompt deleted/changed
+
+    for f, m in sorted(prompts):
+        if m == "cd":
+            if repo.ui.promptchoice(
+                _("local changed %s which remote deleted\n"
+                  "use (c)hanged version or (d)elete?") % f,
+                (_("&Changed"), _("&Delete")), 0):
+                actions.append((f, "r", None, "prompt delete"))
+            else:
+                actions.append((f, "a", None, "prompt keep"))
+        elif m == "dc":
             if repo.ui.promptchoice(
                 _("remote changed %s which local deleted\n"
                   "use (c)hanged version or leave (d)eleted?") % f,
                 (_("&Changed"), _("&Deleted")), 0) == 0:
-                act("prompt recreating", "g", f, m2.flags(f))
-
+                actions.append((f, "g", (m2.flags(f),), "prompt recreating"))
+        else: assert False, m
     return actions
 
 def actionkey(a):
@@ -335,12 +333,13 @@
 
     # prescan for merges
     for a in actions:
-        f, m = a[:2]
+        f, m, args, msg = a
+        repo.ui.debug(" %s: %s -> %s\n" % (f, msg, m))
         if m == "m": # merge
-            f2, fd, move = a[2:]
+            f2, fd, move = args
             if fd == '.hgsubstate': # merged internally
                 continue
-            repo.ui.debug("preserving %s for resolve of %s\n" % (f, fd))
+            repo.ui.debug("  preserving %s for resolve of %s\n" % (f, fd))
             fcl = wctx[f]
             fco = mctx[f2]
             if mctx == actx: # backwards, use working dir parent as ancestor
@@ -367,7 +366,7 @@
 
     numupdates = len(actions)
     for i, a in enumerate(actions):
-        f, m = a[:2]
+        f, m, args, msg = a
         repo.ui.progress(_('updating'), i + 1, item=f, total=numupdates,
                          unit=_('files'))
         if m == "r": # remove
@@ -386,7 +385,7 @@
                 subrepo.submerge(repo, wctx, mctx, wctx.ancestor(mctx),
                                  overwrite)
                 continue
-            f2, fd, move = a[2:]
+            f2, fd, move = args
             audit(fd)
             r = ms.resolve(fd, wctx, mctx)
             if r is not None and r > 0:
@@ -397,14 +396,14 @@
                 else:
                     merged += 1
         elif m == "g": # get
-            flags = a[2]
+            flags, = args
             repo.ui.note(_("getting %s\n") % f)
             repo.wwrite(f, mctx.filectx(f).data(), flags)
             updated += 1
             if f == '.hgsubstate': # subrepo states need updating
                 subrepo.submerge(repo, wctx, mctx, wctx, overwrite)
         elif m == "d": # directory rename
-            f2, fd, flags = a[2:]
+            f2, fd, flags = args
             if f:
                 repo.ui.note(_("moving %s to %s\n") % (f, fd))
                 audit(f)
@@ -415,19 +414,19 @@
                 repo.wwrite(fd, mctx.filectx(f2).data(), flags)
             updated += 1
         elif m == "dr": # divergent renames
-            fl = a[2]
+            fl, = args
             repo.ui.warn(_("note: possible conflict - %s was renamed "
                            "multiple times to:\n") % f)
             for nf in fl:
                 repo.ui.warn(" %s\n" % nf)
         elif m == "rd": # rename and delete
-            fl = a[2]
+            fl, = args
             repo.ui.warn(_("note: possible conflict - %s was deleted "
                            "and renamed to:\n") % f)
             for nf in fl:
                 repo.ui.warn(" %s\n" % nf)
         elif m == "e": # exec
-            flags = a[2]
+            flags, = args
             audit(f)
             util.setflags(repo.wjoin(f), 'l' in flags, 'x' in flags)
             updated += 1
@@ -461,7 +460,7 @@
     "record merge actions to the dirstate"
 
     for a in actions:
-        f, m = a[:2]
+        f, m, args, msg = a
         if m == "r": # remove
             if branchmerge:
                 repo.dirstate.remove(f)
@@ -480,7 +479,7 @@
             else:
                 repo.dirstate.normal(f)
         elif m == "m": # merge
-            f2, fd, move = a[2:]
+            f2, fd, move = args
             if branchmerge:
                 # We've done a branch merge, mark this file as merged
                 # so that we properly record the merger later
@@ -503,7 +502,7 @@
                 if move:
                     repo.dirstate.drop(f)
         elif m == "d": # directory rename
-            f2, fd, flag = a[2:]
+            f2, fd, flag = args
             if not f2 and f not in repo.dirstate:
                 # untracked file moved
                 continue
--- a/mercurial/revset.py	Tue Feb 05 12:58:21 2013 +0100
+++ b/mercurial/revset.py	Wed Feb 06 13:22:01 2013 +0100
@@ -277,20 +277,32 @@
     return checkstatus(repo, subset, pat, 1)
 
 def ancestor(repo, subset, x):
-    """``ancestor(single, single)``
-    Greatest common ancestor of the two changesets.
+    """``ancestor(*changeset)``
+    Greatest common ancestor of the changesets.
+
+    Accepts 0 or more changesets.
+    Will return empty list when passed no args.
+    Greatest common ancestor of a single changeset is that changeset.
     """
     # i18n: "ancestor" is a keyword
-    l = getargs(x, 2, 2, _("ancestor requires two arguments"))
-    r = list(repo)
-    a = getset(repo, r, l[0])
-    b = getset(repo, r, l[1])
-    if len(a) != 1 or len(b) != 1:
-        # i18n: "ancestor" is a keyword
-        raise error.ParseError(_("ancestor arguments must be single revisions"))
-    an = [repo[a[0]].ancestor(repo[b[0]]).rev()]
+    l = getlist(x)
+    rl = list(repo)
+    anc = None
 
-    return [r for r in an if r in subset]
+    # (getset(repo, rl, i) for i in l) generates a list of lists
+    rev = repo.changelog.rev
+    ancestor = repo.changelog.ancestor
+    node = repo.changelog.node
+    for revs in (getset(repo, rl, i) for i in l):
+        for r in revs:
+            if anc is None:
+                anc = r
+            else:
+                anc = rev(ancestor(node(anc), node(r)))
+
+    if anc is not None and anc in subset:
+        return [anc]
+    return []
 
 def _ancestors(repo, subset, x, followfirst=False):
     args = getset(repo, list(repo), x)
--- a/mercurial/scmutil.py	Tue Feb 05 12:58:21 2013 +0100
+++ b/mercurial/scmutil.py	Wed Feb 06 13:22:01 2013 +0100
@@ -733,29 +733,33 @@
     rejected = []
     m.bad = lambda x, y: rejected.append(x)
 
-    for abs in repo.walk(m):
-        target = repo.wjoin(abs)
+    ctx = repo[None]
+    walkresults = repo.dirstate.walk(m, sorted(ctx.substate), True, False)
+    for abs in sorted(walkresults):
         good = True
         try:
             audit_path(abs)
         except (OSError, util.Abort):
             good = False
-        rel = m.rel(abs)
-        exact = m.exact(abs)
-        if good and abs not in repo.dirstate:
+
+        st = walkresults[abs]
+        dstate = repo.dirstate[abs]
+        if good and dstate == '?':
             unknown.append(abs)
-            if repo.ui.verbose or not exact:
+            if repo.ui.verbose or not m.exact(abs):
+                rel = m.rel(abs)
                 repo.ui.status(_('adding %s\n') % ((pats and rel) or abs))
-        elif (repo.dirstate[abs] != 'r' and
-              (not good or not os.path.lexists(target) or
-               (os.path.isdir(target) and not os.path.islink(target)))):
+        elif (dstate != 'r' and
+              (not good or not st or
+               (stat.S_ISDIR(st.st_mode) and not stat.S_ISLNK(st.st_mode)))):
             deleted.append(abs)
-            if repo.ui.verbose or not exact:
+            if repo.ui.verbose or not m.exact(abs):
+                rel = m.rel(abs)
                 repo.ui.status(_('removing %s\n') % ((pats and rel) or abs))
         # for finding renames
-        elif repo.dirstate[abs] == 'r':
+        elif dstate == 'r':
             removed.append(abs)
-        elif repo.dirstate[abs] == 'a':
+        elif dstate == 'a':
             added.append(abs)
     copies = {}
     if similarity > 0:
--- a/mercurial/util.py	Tue Feb 05 12:58:21 2013 +0100
+++ b/mercurial/util.py	Wed Feb 06 13:22:01 2013 +0100
@@ -1027,6 +1027,14 @@
 
     The date may be a "unixtime offset" string or in one of the specified
     formats. If the date already is a (unixtime, offset) tuple, it is returned.
+
+    >>> parsedate(' today ') == parsedate(\
+                                  datetime.date.today().strftime('%b %d'))
+    True
+    >>> parsedate( 'yesterday ') == parsedate((datetime.date.today() -\
+                                               datetime.timedelta(days=1)\
+                                              ).strftime('%b %d'))
+    True
     """
     if not date:
         return 0, 0
@@ -1035,6 +1043,13 @@
     if not formats:
         formats = defaultdateformats
     date = date.strip()
+
+    if date == _('today'):
+        date = datetime.date.today().strftime('%b %d')
+    elif date == _('yesterday'):
+        date = (datetime.date.today() -
+                datetime.timedelta(days=1)).strftime('%b %d')
+
     try:
         when, offset = map(int, date.split(' '))
     except ValueError:
--- a/tests/test-commit.t	Tue Feb 05 12:58:21 2013 +0100
+++ b/tests/test-commit.t	Wed Feb 06 13:22:01 2013 +0100
@@ -263,6 +263,7 @@
   $ cd commitmsg
   $ echo changed > changed
   $ echo removed > removed
+  $ hg book currentbookmark
   $ hg ci -qAm init
 
   $ hg rm removed
@@ -277,6 +278,7 @@
   HG: --
   HG: user: test
   HG: branch 'default'
+  HG: bookmark 'currentbookmark'
   HG: added added
   HG: changed changed
   HG: removed removed
--- a/tests/test-copy-move-merge.t	Tue Feb 05 12:58:21 2013 +0100
+++ b/tests/test-copy-move-merge.t	Wed Feb 06 13:22:01 2013 +0100
@@ -32,9 +32,9 @@
    overwrite: False, partial: False
    ancestor: b8bf91eeebbc, local: add3f11052fa+, remote: 17c05bb7fcb6
    a: remote moved to b -> m
+    preserving a for resolve of b
    a: remote moved to c -> m
-  preserving a for resolve of b
-  preserving a for resolve of c
+    preserving a for resolve of c
   removing a
   updating: a 1/2 files (50.00%)
   picked tool 'internal:merge' for b (binary False symlink False)
--- a/tests/test-double-merge.t	Tue Feb 05 12:58:21 2013 +0100
+++ b/tests/test-double-merge.t	Wed Feb 06 13:22:01 2013 +0100
@@ -35,10 +35,10 @@
   resolving manifests
    overwrite: False, partial: False
    ancestor: e6dc8efe11cc, local: 6a0df1dad128+, remote: 484bf6903104
+   foo: remote copied to bar -> m
+    preserving foo for resolve of bar
    foo: versions differ -> m
-   foo: remote copied to bar -> m
-  preserving foo for resolve of bar
-  preserving foo for resolve of foo
+    preserving foo for resolve of foo
   updating: foo 1/2 files (50.00%)
   picked tool 'internal:merge' for bar (binary False symlink False)
   merging foo and bar to bar
--- a/tests/test-graft.t	Tue Feb 05 12:58:21 2013 +0100
+++ b/tests/test-graft.t	Wed Feb 06 13:22:01 2013 +0100
@@ -137,7 +137,7 @@
    overwrite: False, partial: False
    ancestor: 68795b066622, local: ef0ef43d49e7+, remote: 5d205f8b35b6
    b: local copied/moved to a -> m
-  preserving b for resolve of b
+    preserving b for resolve of b
   updating: b 1/1 files (100.00%)
   picked tool 'internal:merge' for b (binary False symlink False)
   merging b and a to b
@@ -160,7 +160,7 @@
    ancestor: 4c60f11aa304, local: 1905859650ec+, remote: 9c233e8e184d
    d: remote is newer -> g
    e: versions differ -> m
-  preserving e for resolve of e
+    preserving e for resolve of e
   updating: d 1/2 files (50.00%)
   getting d
   updating: e 2/2 files (100.00%)
--- a/tests/test-issue672.t	Tue Feb 05 12:58:21 2013 +0100
+++ b/tests/test-issue672.t	Wed Feb 06 13:22:01 2013 +0100
@@ -66,7 +66,7 @@
    overwrite: False, partial: False
    ancestor: c64f439569a9, local: e327dca35ac8+, remote: 746e9549ea96
    1a: local copied/moved to 1 -> m
-  preserving 1a for resolve of 1a
+    preserving 1a for resolve of 1a
   updating: 1a 1/1 files (100.00%)
   picked tool 'internal:merge' for 1a (binary False symlink False)
   merging 1a and 1 to 1a
@@ -89,7 +89,7 @@
    overwrite: False, partial: False
    ancestor: c64f439569a9, local: 746e9549ea96+, remote: e327dca35ac8
    1: remote moved to 1a -> m
-  preserving 1 for resolve of 1a
+    preserving 1 for resolve of 1a
   removing 1
   updating: 1 1/1 files (100.00%)
   picked tool 'internal:merge' for 1a (binary False symlink False)
--- a/tests/test-largefiles.t	Tue Feb 05 12:58:21 2013 +0100
+++ b/tests/test-largefiles.t	Wed Feb 06 13:22:01 2013 +0100
@@ -1210,20 +1210,14 @@
   checking files
   10 files, 10 changesets, 28 total revisions
   searching 1 changesets for largefiles
-  changeset 9:598410d3eb9a: sub/large4 missing
-    (looked for hash e166e74c7303192238d60af5a9c4ce9bef0b7928)
+  changeset 9:598410d3eb9a: sub/large4 references missing $TESTTMP/d/.hg/largefiles/e166e74c7303192238d60af5a9c4ce9bef0b7928 (glob)
   verified existence of 3 revisions of 3 largefiles
   [1]
 
 - introduce corruption and make sure that it is caught when checking content:
   $ echo '5 cents' > $TESTTMP/d/.hg/largefiles/e166e74c7303192238d60af5a9c4ce9bef0b7928
   $ hg verify -q --large --lfc
-  searching 1 changesets for largefiles
-  changeset 9:598410d3eb9a: sub/large4: contents differ
-    ($TESTTMP/d/.hg/largefiles/e166e74c7303192238d60af5a9c4ce9bef0b7928: (glob)
-    expected hash e166e74c7303192238d60af5a9c4ce9bef0b7928,
-    but got 1f19b76d5b3cad1472c87efb42b582c97e040060)
-  verified contents of 3 revisions of 3 largefiles
+  changeset 9:598410d3eb9a: sub/large4 references corrupted $TESTTMP/d/.hg/largefiles/e166e74c7303192238d60af5a9c4ce9bef0b7928 (glob)
   [1]
 
 - cleanup
@@ -1231,31 +1225,14 @@
 
 - verifying all revisions will fail because we didn't clone all largefiles to d:
   $ echo 'T-shirt' > $TESTTMP/d/.hg/largefiles/eb7338044dc27f9bc59b8dd5a246b065ead7a9c4
-  $ hg verify -q --large --lfa --lfc
-  searching 10 changesets for largefiles
-  changeset 0:30d30fe6a5be: large1 missing
-    (looked for hash 4669e532d5b2c093a78eca010077e708a071bb64)
-  changeset 0:30d30fe6a5be: sub/large2 missing
-    (looked for hash 1deebade43c8c498a3c8daddac0244dc55d1331d)
-  changeset 1:ce8896473775: large1 missing
-    (looked for hash 5f78770c0e77ba4287ad6ef3071c9bf9c379742f)
-  changeset 1:ce8896473775: sub/large2: contents differ
-    ($TESTTMP/d/.hg/largefiles/eb7338044dc27f9bc59b8dd5a246b065ead7a9c4: (glob)
-    expected hash eb7338044dc27f9bc59b8dd5a246b065ead7a9c4,
-    but got cfef678f24d3e339944138ecdd8fd85ca21d820f)
-  changeset 3:9e8fbc4bce62: large1: contents differ
-    ($TESTTMP/d/.hg/largefiles/eb7338044dc27f9bc59b8dd5a246b065ead7a9c4: (glob)
-    expected hash eb7338044dc27f9bc59b8dd5a246b065ead7a9c4,
-    but got cfef678f24d3e339944138ecdd8fd85ca21d820f)
-  changeset 4:74c02385b94c: large3: contents differ
-    ($TESTTMP/d/.hg/largefiles/eb7338044dc27f9bc59b8dd5a246b065ead7a9c4: (glob)
-    expected hash eb7338044dc27f9bc59b8dd5a246b065ead7a9c4,
-    but got cfef678f24d3e339944138ecdd8fd85ca21d820f)
-  changeset 4:74c02385b94c: sub/large4: contents differ
-    ($TESTTMP/d/.hg/largefiles/eb7338044dc27f9bc59b8dd5a246b065ead7a9c4: (glob)
-    expected hash eb7338044dc27f9bc59b8dd5a246b065ead7a9c4,
-    but got cfef678f24d3e339944138ecdd8fd85ca21d820f)
-  verified contents of 15 revisions of 6 largefiles
+  $ hg verify -q --lfa --lfc
+  changeset 0:30d30fe6a5be: large1 references missing $TESTTMP/d/.hg/largefiles/4669e532d5b2c093a78eca010077e708a071bb64 (glob)
+  changeset 0:30d30fe6a5be: sub/large2 references missing $TESTTMP/d/.hg/largefiles/1deebade43c8c498a3c8daddac0244dc55d1331d (glob)
+  changeset 1:ce8896473775: large1 references missing $TESTTMP/d/.hg/largefiles/5f78770c0e77ba4287ad6ef3071c9bf9c379742f (glob)
+  changeset 1:ce8896473775: sub/large2 references corrupted $TESTTMP/d/.hg/largefiles/eb7338044dc27f9bc59b8dd5a246b065ead7a9c4 (glob)
+  changeset 3:9e8fbc4bce62: large1 references corrupted $TESTTMP/d/.hg/largefiles/eb7338044dc27f9bc59b8dd5a246b065ead7a9c4 (glob)
+  changeset 4:74c02385b94c: large3 references corrupted $TESTTMP/d/.hg/largefiles/eb7338044dc27f9bc59b8dd5a246b065ead7a9c4 (glob)
+  changeset 4:74c02385b94c: sub/large4 references corrupted $TESTTMP/d/.hg/largefiles/eb7338044dc27f9bc59b8dd5a246b065ead7a9c4 (glob)
   [1]
 
 - cleanup
@@ -1664,8 +1641,6 @@
   [1]
   $ mv 02a439e5c31c526465ab1a0ca1f431f76b827b90 empty/.hg/largefiles/
   $ hg -R http-clone -q verify --large --lfa
-  searching 1 changesets for largefiles
-  verified existence of 1 revisions of 1 largefiles
 
 largefiles pulled on update - a largefile missing on the server:
   $ mv empty/.hg/largefiles/02a439e5c31c526465ab1a0ca1f431f76b827b90 .
--- a/tests/test-lfconvert.t	Tue Feb 05 12:58:21 2013 +0100
+++ b/tests/test-lfconvert.t	Wed Feb 06 13:22:01 2013 +0100
@@ -317,18 +317,12 @@
   checking files
   8 files, 7 changesets, 12 total revisions
   searching 7 changesets for largefiles
-  changeset 0:d4892ec57ce2: large missing
-    (looked for hash 2e000fa7e85759c7f4c254d4d9c33ef481e459a7)
-  changeset 1:334e5237836d: sub/maybelarge.dat missing
-    (looked for hash 34e163be8e43c5631d8b92e9c43ab0bf0fa62b9c)
-  changeset 2:261ad3f3f037: stuff/maybelarge.dat missing
-    (looked for hash 34e163be8e43c5631d8b92e9c43ab0bf0fa62b9c)
-  changeset 3:55759520c76f: sub/maybelarge.dat missing
-    (looked for hash 76236b6a2c6102826c61af4297dd738fb3b1de38)
-  changeset 5:9cc5aa7204f0: stuff/maybelarge.dat missing
-    (looked for hash 76236b6a2c6102826c61af4297dd738fb3b1de38)
-  changeset 6:17126745edfd: anotherlarge missing
-    (looked for hash 3b71f43ff30f4b15b5cd85dd9e95ebc7e84eb5a3)
+  changeset 0:d4892ec57ce2: large references missing $TESTTMP/largefiles-repo-hg/.hg/largefiles/2e000fa7e85759c7f4c254d4d9c33ef481e459a7 (glob)
+  changeset 1:334e5237836d: sub/maybelarge.dat references missing $TESTTMP/largefiles-repo-hg/.hg/largefiles/34e163be8e43c5631d8b92e9c43ab0bf0fa62b9c (glob)
+  changeset 2:261ad3f3f037: stuff/maybelarge.dat references missing $TESTTMP/largefiles-repo-hg/.hg/largefiles/34e163be8e43c5631d8b92e9c43ab0bf0fa62b9c (glob)
+  changeset 3:55759520c76f: sub/maybelarge.dat references missing $TESTTMP/largefiles-repo-hg/.hg/largefiles/76236b6a2c6102826c61af4297dd738fb3b1de38 (glob)
+  changeset 5:9cc5aa7204f0: stuff/maybelarge.dat references missing $TESTTMP/largefiles-repo-hg/.hg/largefiles/76236b6a2c6102826c61af4297dd738fb3b1de38 (glob)
+  changeset 6:17126745edfd: anotherlarge references missing $TESTTMP/largefiles-repo-hg/.hg/largefiles/3b71f43ff30f4b15b5cd85dd9e95ebc7e84eb5a3 (glob)
   verified existence of 6 revisions of 4 largefiles
   [1]
   $ hg -R largefiles-repo-hg showconfig paths
--- a/tests/test-merge-commit.t	Tue Feb 05 12:58:21 2013 +0100
+++ b/tests/test-merge-commit.t	Wed Feb 06 13:22:01 2013 +0100
@@ -72,7 +72,7 @@
    overwrite: False, partial: False
    ancestor: 0f2ff26688b9, local: 2263c1be0967+, remote: 0555950ead28
    bar: versions differ -> m
-  preserving bar for resolve of bar
+    preserving bar for resolve of bar
   updating: bar 1/1 files (100.00%)
   picked tool 'internal:merge' for bar (binary False symlink False)
   merging bar
@@ -159,7 +159,7 @@
    overwrite: False, partial: False
    ancestor: 0f2ff26688b9, local: 2263c1be0967+, remote: 3ffa6b9e35f0
    bar: versions differ -> m
-  preserving bar for resolve of bar
+    preserving bar for resolve of bar
   updating: bar 1/1 files (100.00%)
   picked tool 'internal:merge' for bar (binary False symlink False)
   merging bar
--- a/tests/test-merge-prompt.t	Tue Feb 05 12:58:21 2013 +0100
+++ b/tests/test-merge-prompt.t	Wed Feb 06 13:22:01 2013 +0100
@@ -42,7 +42,7 @@
 Non-interactive merge:
 
   $ hg merge -y
-   local changed file1 which remote deleted
+  local changed file1 which remote deleted
   use (c)hanged version or (d)elete? c
   remote changed file2 which local deleted
   use (c)hanged version or leave (d)eleted? c
@@ -70,7 +70,7 @@
   > c
   > d
   > EOF
-   local changed file1 which remote deleted
+  local changed file1 which remote deleted
   use (c)hanged version or (d)elete? remote changed file2 which local deleted
   use (c)hanged version or leave (d)eleted? 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
   (branch merge, don't forget to commit)
@@ -97,11 +97,11 @@
   > baz
   > c
   > EOF
-   local changed file1 which remote deleted
+  local changed file1 which remote deleted
   use (c)hanged version or (d)elete? unrecognized response
-   local changed file1 which remote deleted
+  local changed file1 which remote deleted
   use (c)hanged version or (d)elete? unrecognized response
-   local changed file1 which remote deleted
+  local changed file1 which remote deleted
   use (c)hanged version or (d)elete? remote changed file2 which local deleted
   use (c)hanged version or leave (d)eleted? unrecognized response
   remote changed file2 which local deleted
@@ -126,7 +126,7 @@
   $ hg merge --config ui.interactive=true <<EOF
   > d
   > EOF
-   local changed file1 which remote deleted
+  local changed file1 which remote deleted
   use (c)hanged version or (d)elete? remote changed file2 which local deleted
   use (c)hanged version or leave (d)eleted? abort: response expected
   [255]
--- a/tests/test-merge-types.t	Tue Feb 05 12:58:21 2013 +0100
+++ b/tests/test-merge-types.t	Wed Feb 06 13:22:01 2013 +0100
@@ -35,7 +35,7 @@
    overwrite: False, partial: False
    ancestor: c334dc3be0da, local: 521a1e40188f+, remote: 3574f3e69b1c
    a: versions differ -> m
-  preserving a for resolve of a
+    preserving a for resolve of a
   updating: a 1/1 files (100.00%)
   picked tool 'internal:merge' for a (binary False symlink True)
   merging a
@@ -68,7 +68,7 @@
    overwrite: False, partial: False
    ancestor: c334dc3be0da, local: 3574f3e69b1c+, remote: 521a1e40188f
    a: versions differ -> m
-  preserving a for resolve of a
+    preserving a for resolve of a
   updating: a 1/1 files (100.00%)
   picked tool 'internal:merge' for a (binary False symlink True)
   merging a
@@ -102,7 +102,7 @@
    overwrite: False, partial: False
    ancestor: c334dc3be0da, local: c334dc3be0da+, remote: 521a1e40188f
    a: versions differ -> m
-  preserving a for resolve of a
+    preserving a for resolve of a
   updating: a 1/1 files (100.00%)
   (couldn't find merge tool hgmerge|tool hgmerge can't handle symlinks) (re)
   picked tool 'internal:prompt' for a (binary False symlink True)
--- a/tests/test-merge7.t	Tue Feb 05 12:58:21 2013 +0100
+++ b/tests/test-merge7.t	Wed Feb 06 13:22:01 2013 +0100
@@ -84,7 +84,7 @@
    overwrite: False, partial: False
    ancestor: 96b70246a118, local: 50c3a7e29886+, remote: 40d11a4173a8
    test.txt: versions differ -> m
-  preserving test.txt for resolve of test.txt
+    preserving test.txt for resolve of test.txt
   updating: test.txt 1/1 files (100.00%)
   picked tool 'internal:merge' for test.txt (binary False symlink False)
   merging test.txt
--- a/tests/test-parse-date.t	Tue Feb 05 12:58:21 2013 +0100
+++ b/tests/test-parse-date.t	Wed Feb 06 13:22:01 2013 +0100
@@ -234,3 +234,20 @@
   Sat Apr 15 13:30:00 2006 +0000
   Wed Feb 01 13:00:30 2006 -0500
   Wed Feb 01 13:00:30 2006 +0000
+
+Test issue 3764 (interpreting 'today' and 'yesterday')
+  $ echo "hello" >> a
+  >>> import datetime
+  >>> today = datetime.date.today().strftime("%b %d")
+  >>> yesterday = (datetime.date.today() - datetime.timedelta(days=1)).strftime("%b %d")
+  >>> dates = open('dates', 'w')
+  >>> dates.write(today + '\n')
+  >>> dates.write(yesterday)
+  >>> dates.close()
+  $ hg ci -d "`sed -n '1p' dates`" -m "today is a good day to code"
+  $ hg log -d today --template '{desc}\n'
+  today is a good day to code
+  $ echo "goodbye" >> a
+  $ hg ci -d "`sed -n '2p' dates`" -m "the time traveler's code"
+  $ hg log -d yesterday --template '{desc}\n'
+  the time traveler's code
--- a/tests/test-rename-merge1.t	Tue Feb 05 12:58:21 2013 +0100
+++ b/tests/test-rename-merge1.t	Wed Feb 06 13:22:01 2013 +0100
@@ -33,13 +33,13 @@
      src: 'a2' -> dst: 'b2' !
      src: 'a2' -> dst: 'c2' !
     checking for directory renames
-   a2: divergent renames -> dr
   resolving manifests
    overwrite: False, partial: False
    ancestor: af1939970a1c, local: 044f8520aeeb+, remote: 85c198ef2f6c
    a: remote moved to b -> m
+    preserving a for resolve of b
+   a2: divergent renames -> dr
    b2: remote created -> g
-  preserving a for resolve of b
   removing a
   updating: a 1/3 files (33.33%)
   picked tool 'internal:merge' for b (binary False symlink False)
@@ -178,10 +178,10 @@
     all copies found (* = to merge, ! = divergent, % = renamed and deleted):
      src: 'file' -> dst: 'newfile' %
     checking for directory renames
-   file: rename and delete -> rd
   resolving manifests
    overwrite: False, partial: False
    ancestor: 19d7f95df299, local: 0084274f6b67+, remote: 5d32493049f0
+   file: rename and delete -> rd
    newfile: remote created -> g
   updating: file 1/2 files (50.00%)
   note: possible conflict - file was deleted and renamed to:
--- a/tests/test-rename-merge2.t	Tue Feb 05 12:58:21 2013 +0100
+++ b/tests/test-rename-merge2.t	Wed Feb 06 13:22:01 2013 +0100
@@ -86,10 +86,10 @@
   resolving manifests
    overwrite: False, partial: False
    ancestor: 924404dff337, local: e300d1c794ec+, remote: 4ce40f5aca24
+   a: remote copied to b -> m
+    preserving a for resolve of b
    rev: versions differ -> m
-   a: remote copied to b -> m
-  preserving a for resolve of b
-  preserving rev for resolve of rev
+    preserving rev for resolve of rev
   updating: a 1/2 files (50.00%)
   picked tool 'python ../merge' for b (binary False symlink False)
   merging a and b to b
@@ -123,9 +123,9 @@
    ancestor: 924404dff337, local: 86a2aa42fc76+, remote: f4db7e329e71
    a: remote is newer -> g
    b: local copied/moved to a -> m
+    preserving b for resolve of b
    rev: versions differ -> m
-  preserving b for resolve of b
-  preserving rev for resolve of rev
+    preserving rev for resolve of rev
   updating: a 1/3 files (33.33%)
   getting a
   updating: b 2/3 files (66.67%)
@@ -159,10 +159,10 @@
   resolving manifests
    overwrite: False, partial: False
    ancestor: 924404dff337, local: e300d1c794ec+, remote: bdb19105162a
+   a: remote moved to b -> m
+    preserving a for resolve of b
    rev: versions differ -> m
-   a: remote moved to b -> m
-  preserving a for resolve of b
-  preserving rev for resolve of rev
+    preserving rev for resolve of rev
   removing a
   updating: a 1/2 files (50.00%)
   picked tool 'python ../merge' for b (binary False symlink False)
@@ -195,9 +195,9 @@
    overwrite: False, partial: False
    ancestor: 924404dff337, local: 02963e448370+, remote: f4db7e329e71
    b: local copied/moved to a -> m
+    preserving b for resolve of b
    rev: versions differ -> m
-  preserving b for resolve of b
-  preserving rev for resolve of rev
+    preserving rev for resolve of rev
   updating: b 1/2 files (50.00%)
   picked tool 'python ../merge' for b (binary False symlink False)
   merging b and a to b
@@ -228,9 +228,9 @@
   resolving manifests
    overwrite: False, partial: False
    ancestor: 924404dff337, local: 94b33a1b7f2d+, remote: 4ce40f5aca24
+   b: remote created -> g
    rev: versions differ -> m
-   b: remote created -> g
-  preserving rev for resolve of rev
+    preserving rev for resolve of rev
   updating: b 1/2 files (50.00%)
   getting b
   updating: rev 2/2 files (100.00%)
@@ -259,7 +259,7 @@
    overwrite: False, partial: False
    ancestor: 924404dff337, local: 86a2aa42fc76+, remote: 97c705ade336
    rev: versions differ -> m
-  preserving rev for resolve of rev
+    preserving rev for resolve of rev
   updating: rev 1/1 files (100.00%)
   picked tool 'python ../merge' for rev (binary False symlink False)
   merging rev
@@ -286,9 +286,9 @@
    overwrite: False, partial: False
    ancestor: 924404dff337, local: 94b33a1b7f2d+, remote: bdb19105162a
    a: other deleted -> r
+   b: remote created -> g
    rev: versions differ -> m
-   b: remote created -> g
-  preserving rev for resolve of rev
+    preserving rev for resolve of rev
   updating: a 1/3 files (33.33%)
   removing a
   updating: b 2/3 files (66.67%)
@@ -318,7 +318,7 @@
    overwrite: False, partial: False
    ancestor: 924404dff337, local: 02963e448370+, remote: 97c705ade336
    rev: versions differ -> m
-  preserving rev for resolve of rev
+    preserving rev for resolve of rev
   updating: rev 1/1 files (100.00%)
   picked tool 'python ../merge' for rev (binary False symlink False)
   merging rev
@@ -339,9 +339,9 @@
    overwrite: False, partial: False
    ancestor: 924404dff337, local: 62e7bf090eba+, remote: 49b6d8032493
    b: versions differ -> m
+    preserving b for resolve of b
    rev: versions differ -> m
-  preserving b for resolve of b
-  preserving rev for resolve of rev
+    preserving rev for resolve of rev
   updating: b 1/2 files (50.00%)
   picked tool 'python ../merge' for b (binary False symlink False)
   merging b
@@ -373,13 +373,13 @@
      src: 'a' -> dst: 'b' !
      src: 'a' -> dst: 'c' !
     checking for directory renames
-   a: divergent renames -> dr
   resolving manifests
    overwrite: False, partial: False
    ancestor: 924404dff337, local: 02963e448370+, remote: fe905ef2c33e
-   rev: versions differ -> m
+   a: divergent renames -> dr
    c: remote created -> g
-  preserving rev for resolve of rev
+   rev: versions differ -> m
+    preserving rev for resolve of rev
   updating: a 1/3 files (33.33%)
   note: possible conflict - a was renamed multiple times to:
    b
@@ -407,9 +407,9 @@
    overwrite: False, partial: False
    ancestor: 924404dff337, local: 86a2aa42fc76+, remote: af30c7647fc7
    b: versions differ -> m
+    preserving b for resolve of b
    rev: versions differ -> m
-  preserving b for resolve of b
-  preserving rev for resolve of rev
+    preserving rev for resolve of rev
   updating: b 1/2 files (50.00%)
   picked tool 'python ../merge' for b (binary False symlink False)
   merging b
@@ -436,9 +436,9 @@
    ancestor: 924404dff337, local: 59318016310c+, remote: bdb19105162a
    a: other deleted -> r
    b: versions differ -> m
+    preserving b for resolve of b
    rev: versions differ -> m
-  preserving b for resolve of b
-  preserving rev for resolve of rev
+    preserving rev for resolve of rev
   updating: a 1/3 files (33.33%)
   removing a
   updating: b 2/3 files (66.67%)
@@ -466,9 +466,9 @@
    ancestor: 924404dff337, local: 86a2aa42fc76+, remote: 8dbce441892a
    a: remote is newer -> g
    b: versions differ -> m
+    preserving b for resolve of b
    rev: versions differ -> m
-  preserving b for resolve of b
-  preserving rev for resolve of rev
+    preserving rev for resolve of rev
   updating: a 1/3 files (33.33%)
   getting a
   updating: b 2/3 files (66.67%)
@@ -497,9 +497,9 @@
    ancestor: 924404dff337, local: 59318016310c+, remote: bdb19105162a
    a: other deleted -> r
    b: versions differ -> m
+    preserving b for resolve of b
    rev: versions differ -> m
-  preserving b for resolve of b
-  preserving rev for resolve of rev
+    preserving rev for resolve of rev
   updating: a 1/3 files (33.33%)
   removing a
   updating: b 2/3 files (66.67%)
@@ -527,9 +527,9 @@
    ancestor: 924404dff337, local: 86a2aa42fc76+, remote: 8dbce441892a
    a: remote is newer -> g
    b: versions differ -> m
+    preserving b for resolve of b
    rev: versions differ -> m
-  preserving b for resolve of b
-  preserving rev for resolve of rev
+    preserving rev for resolve of rev
   updating: a 1/3 files (33.33%)
   getting a
   updating: b 2/3 files (66.67%)
@@ -557,9 +557,9 @@
    overwrite: False, partial: False
    ancestor: 924404dff337, local: 0b76e65c8289+, remote: 4ce40f5aca24
    b: versions differ -> m
+    preserving b for resolve of b
    rev: versions differ -> m
-  preserving b for resolve of b
-  preserving rev for resolve of rev
+    preserving rev for resolve of rev
   updating: b 1/2 files (50.00%)
   picked tool 'python ../merge' for b (binary False symlink False)
   merging b
@@ -584,13 +584,13 @@
   resolving manifests
    overwrite: False, partial: False
    ancestor: 924404dff337, local: 02963e448370+, remote: 8dbce441892a
-   b: versions differ -> m
-   rev: versions differ -> m
   remote changed a which local deleted
   use (c)hanged version or leave (d)eleted? c
    a: prompt recreating -> g
-  preserving b for resolve of b
-  preserving rev for resolve of rev
+   b: versions differ -> m
+    preserving b for resolve of b
+   rev: versions differ -> m
+    preserving rev for resolve of rev
   updating: a 1/3 files (33.33%)
   getting a
   updating: b 2/3 files (66.67%)
@@ -617,13 +617,13 @@
   resolving manifests
    overwrite: False, partial: False
    ancestor: 924404dff337, local: 0b76e65c8289+, remote: bdb19105162a
-   local changed a which remote deleted
+  local changed a which remote deleted
   use (c)hanged version or (d)elete? c
    a: prompt keep -> a
    b: versions differ -> m
+    preserving b for resolve of b
    rev: versions differ -> m
-  preserving b for resolve of b
-  preserving rev for resolve of rev
+    preserving rev for resolve of rev
   updating: a 1/3 files (33.33%)
   updating: b 2/3 files (66.67%)
   picked tool 'python ../merge' for b (binary False symlink False)
@@ -654,10 +654,10 @@
   resolving manifests
    overwrite: False, partial: False
    ancestor: 924404dff337, local: e300d1c794ec+, remote: 49b6d8032493
+   a: remote moved to b -> m
+    preserving a for resolve of b
    rev: versions differ -> m
-   a: remote moved to b -> m
-  preserving a for resolve of b
-  preserving rev for resolve of rev
+    preserving rev for resolve of rev
   removing a
   updating: a 1/2 files (50.00%)
   picked tool 'python ../merge' for b (binary False symlink False)
@@ -689,9 +689,9 @@
    overwrite: False, partial: False
    ancestor: 924404dff337, local: 62e7bf090eba+, remote: f4db7e329e71
    b: local copied/moved to a -> m
+    preserving b for resolve of b
    rev: versions differ -> m
-  preserving b for resolve of b
-  preserving rev for resolve of rev
+    preserving rev for resolve of rev
   updating: b 1/2 files (50.00%)
   picked tool 'python ../merge' for b (binary False symlink False)
   merging b and a to b
@@ -727,10 +727,10 @@
    overwrite: False, partial: False
    ancestor: 924404dff337, local: 02963e448370+, remote: 2b958612230f
    b: local copied/moved to a -> m
-   rev: versions differ -> m
+    preserving b for resolve of b
    c: remote created -> g
-  preserving b for resolve of b
-  preserving rev for resolve of rev
+   rev: versions differ -> m
+    preserving rev for resolve of rev
   updating: b 1/3 files (33.33%)
   picked tool 'python ../merge' for b (binary False symlink False)
   merging b and a to b
--- a/tests/test-revset.t	Tue Feb 05 12:58:21 2013 +0100
+++ b/tests/test-revset.t	Wed Feb 06 13:22:01 2013 +0100
@@ -218,17 +218,29 @@
   $ log 'date(2005) and 1::'
   4
 
+ancestor can accept 0 or more arguments
+
+  $ log 'ancestor()'
   $ log 'ancestor(1)'
-  hg: parse error: ancestor requires two arguments
-  [255]
+  1
   $ log 'ancestor(4,5)'
   1
   $ log 'ancestor(4,5) and 4'
+  $ log 'ancestor(0,0,1,3)'
+  0
+  $ log 'ancestor(3,1,5,3,5,1)'
+  1
+  $ log 'ancestor(0,1,3,5)'
+  0
+  $ log 'ancestor(1,2,3,4,5)'
+  1
   $ log 'ancestors(5)'
   0
   1
   3
   5
+  $ log 'ancestor(ancestors(5))'
+  0
   $ log 'author(bob)'
   2
   $ log 'author("re:bob|test")'
--- a/tests/test-subrepo.t	Tue Feb 05 12:58:21 2013 +0100
+++ b/tests/test-subrepo.t	Wed Feb 06 13:22:01 2013 +0100
@@ -244,7 +244,7 @@
    overwrite: False, partial: False
    ancestor: 6747d179aa9a, local: 20a0db6fbf6c+, remote: 7af322bc1198
    t: versions differ -> m
-  preserving t for resolve of t
+    preserving t for resolve of t
   updating: t 1/1 files (100.00%)
   picked tool 'internal:merge' for t (binary False symlink False)
   merging t
--- a/tests/test-up-local-change.t	Tue Feb 05 12:58:21 2013 +0100
+++ b/tests/test-up-local-change.t	Wed Feb 06 13:22:01 2013 +0100
@@ -47,8 +47,8 @@
    overwrite: False, partial: False
    ancestor: c19d34741b0a, local: c19d34741b0a+, remote: 1e71731e6fbb
    a: versions differ -> m
+    preserving a for resolve of a
    b: remote created -> g
-  preserving a for resolve of a
   updating: a 1/2 files (50.00%)
   picked tool 'true' for a (binary False symlink False)
   merging a
@@ -67,9 +67,9 @@
   resolving manifests
    overwrite: False, partial: False
    ancestor: 1e71731e6fbb, local: 1e71731e6fbb+, remote: c19d34741b0a
+   b: other deleted -> r
    a: versions differ -> m
-   b: other deleted -> r
-  preserving a for resolve of a
+    preserving a for resolve of a
   updating: b 1/2 files (50.00%)
   removing b
   updating: a 2/2 files (100.00%)
@@ -101,8 +101,8 @@
    overwrite: False, partial: False
    ancestor: c19d34741b0a, local: c19d34741b0a+, remote: 1e71731e6fbb
    a: versions differ -> m
+    preserving a for resolve of a
    b: remote created -> g
-  preserving a for resolve of a
   updating: a 1/2 files (50.00%)
   picked tool 'true' for a (binary False symlink False)
   merging a
@@ -179,9 +179,9 @@
    overwrite: False, partial: False
    ancestor: c19d34741b0a, local: 1e71731e6fbb+, remote: 83c51d0caff4
    a: versions differ -> m
+    preserving a for resolve of a
    b: versions differ -> m
-  preserving a for resolve of a
-  preserving b for resolve of b
+    preserving b for resolve of b
   updating: a 1/2 files (50.00%)
   picked tool 'true' for a (binary False symlink False)
   merging a