changeset 1512:c40108ae8fb0

merge with stable
author Pierre-Yves David <pierre-yves.david@fb.com>
date Mon, 12 Oct 2015 01:23:59 -0700
parents b86eea66ed02 (diff) 91b6a30424a3 (current diff)
children 4f7e0e0318a5
files README hgext/evolve.py
diffstat 23 files changed, 862 insertions(+), 369 deletions(-) [+]
line wrap: on
line diff
--- a/README	Mon Oct 12 01:22:41 2015 -0700
+++ b/README	Mon Oct 12 01:23:59 2015 -0700
@@ -51,6 +51,11 @@
 Changelog
 =========
 
+5.3.0 --
+
+- split: add a new command to split changesets
+- add some progress data during changesets discovery
+
 5.2.1 --
 
 - add compatibility with Mercurial 3.6
--- a/hgext/directaccess.py	Mon Oct 12 01:22:41 2015 -0700
+++ b/hgext/directaccess.py	Mon Oct 12 01:23:59 2015 -0700
@@ -129,6 +129,8 @@
 
 hashre = util.re.compile('[0-9a-fA-F]{1,40}')
 
+_listtuple = ('symbol', '_list')
+
 def gethashsymbols(tree):
     # Returns the list of symbols of the tree that look like hashes
     # for example for the revset 3::abe3ff it will return ('abe3ff')
@@ -143,8 +145,18 @@
             if hashre.match(tree[1]):
                 return [tree[1]]
             return []
-    elif len(tree) == 3:
-        return gethashsymbols(tree[1]) + gethashsymbols(tree[2])
+    elif tree[0] == "func" and tree[1] == _listtuple:
+        # the optimiser will group sequence of hash request
+        result = []
+        for entry in tree[2][1].split('\0'):
+            if hashre.match(entry):
+                result.append(entry)
+        return result
+    elif len(tree) >= 3:
+        results = []
+        for subtree in tree[1:]:
+            results += gethashsymbols(subtree)
+        return results
     else:
         return []
 
--- a/hgext/evolve.py	Mon Oct 12 01:22:41 2015 -0700
+++ b/hgext/evolve.py	Mon Oct 12 01:23:59 2015 -0700
@@ -805,74 +805,82 @@
     nodeid was actually created. If created is False, nodeid
     references a changeset existing before the rewrite call.
     """
-    if len(old.parents()) > 1: #XXX remove this unecessary limitation.
-        raise error.Abort(_('cannot amend merge changesets'))
-    base = old.p1()
-    updatebookmarks = _bookmarksupdater(repo, old.node())
-
-    # commit a new version of the old changeset, including the update
-    # collect all files which might be affected
-    files = set(old.files())
-    for u in updates:
-        files.update(u.files())
-
-    # Recompute copies (avoid recording a -> b -> a)
-    copied = copies.pathcopies(base, head)
-
-
-    # prune files which were reverted by the updates
-    def samefile(f):
-        if f in head.manifest():
-            a = head.filectx(f)
-            if f in base.manifest():
-                b = base.filectx(f)
-                return (a.data() == b.data()
-                        and a.flags() == b.flags())
+    wlock = lock = tr = None
+    try:
+        wlock = repo.wlock()
+        lock = repo.lock()
+        tr = repo.transaction('rewrite')
+        if len(old.parents()) > 1: #XXX remove this unecessary limitation.
+            raise error.Abort(_('cannot amend merge changesets'))
+        base = old.p1()
+        updatebookmarks = _bookmarksupdater(repo, old.node(), tr)
+
+        # commit a new version of the old changeset, including the update
+        # collect all files which might be affected
+        files = set(old.files())
+        for u in updates:
+            files.update(u.files())
+
+        # Recompute copies (avoid recording a -> b -> a)
+        copied = copies.pathcopies(base, head)
+
+
+        # prune files which were reverted by the updates
+        def samefile(f):
+            if f in head.manifest():
+                a = head.filectx(f)
+                if f in base.manifest():
+                    b = base.filectx(f)
+                    return (a.data() == b.data()
+                            and a.flags() == b.flags())
+                else:
+                    return False
             else:
-                return False
-        else:
-            return f not in base.manifest()
-    files = [f for f in files if not samefile(f)]
-    # commit version of these files as defined by head
-    headmf = head.manifest()
-    def filectxfn(repo, ctx, path):
-        if path in headmf:
-            fctx = head[path]
-            flags = fctx.flags()
-            mctx = memfilectx(repo, fctx.path(), fctx.data(),
-                              islink='l' in flags,
-                              isexec='x' in flags,
-                              copied=copied.get(path))
-            return mctx
-        return None
-
-    message = cmdutil.logmessage(repo.ui, commitopts)
-    if not message:
-        message = old.description()
-
-    user = commitopts.get('user') or old.user()
-    date = commitopts.get('date') or None # old.date()
-    extra = dict(commitopts.get('extra', {}))
-    extra['branch'] = head.branch()
-
-    new = context.memctx(repo,
-                         parents=newbases,
-                         text=message,
-                         files=files,
-                         filectxfn=filectxfn,
-                         user=user,
-                         date=date,
-                         extra=extra)
-
-    if commitopts.get('edit'):
-        new._text = cmdutil.commitforceeditor(repo, new, [])
-    revcount = len(repo)
-    newid = repo.commitctx(new)
-    new = repo[newid]
-    created = len(repo) != revcount
-    updatebookmarks(newid)
-
-    return newid, created
+                return f not in base.manifest()
+        files = [f for f in files if not samefile(f)]
+        # commit version of these files as defined by head
+        headmf = head.manifest()
+        def filectxfn(repo, ctx, path):
+            if path in headmf:
+                fctx = head[path]
+                flags = fctx.flags()
+                mctx = memfilectx(repo, fctx.path(), fctx.data(),
+                                  islink='l' in flags,
+                                  isexec='x' in flags,
+                                  copied=copied.get(path))
+                return mctx
+            return None
+
+        message = cmdutil.logmessage(repo.ui, commitopts)
+        if not message:
+            message = old.description()
+
+        user = commitopts.get('user') or old.user()
+        date = commitopts.get('date') or None # old.date()
+        extra = dict(commitopts.get('extra', old.extra()))
+        extra['branch'] = head.branch()
+
+        new = context.memctx(repo,
+                             parents=newbases,
+                             text=message,
+                             files=files,
+                             filectxfn=filectxfn,
+                             user=user,
+                             date=date,
+                             extra=extra)
+
+        if commitopts.get('edit'):
+            new._text = cmdutil.commitforceeditor(repo, new, [])
+        revcount = len(repo)
+        newid = repo.commitctx(new)
+        new = repo[newid]
+        created = len(repo) != revcount
+        updatebookmarks(newid)
+
+        tr.close()
+        return newid, created
+    finally:
+        lockmod.release(lock, wlock, tr)
 
 class MergeFailure(util.Abort):
     pass
@@ -935,7 +943,10 @@
                         'unresolved merge conflicts (see hg help resolve)')
             if commitmsg is None:
                 commitmsg = orig.description()
-            extra = {'rebase_source': orig.hex()}
+            extra = dict(orig.extra())
+            if 'branch' in extra:
+                del extra['branch']
+            extra['rebase_source'] = orig.hex()
 
             backup = repo.ui.backupconfig('phases', 'new-commit')
             try:
@@ -971,13 +982,13 @@
         for book in destbookmarks: # restore bookmark that rebase move
             repo._bookmarks[book] = dest.node()
         if oldbookmarks or destbookmarks:
-            repo._bookmarks.write()
+            repo._bookmarks.recordchange(tr)
         tr.close()
     finally:
         tr.release()
     return nodenew
 
-def _bookmarksupdater(repo, oldid):
+def _bookmarksupdater(repo, oldid, tr):
     """Return a callable update(newid) updating the current bookmark
     and bookmarks bound to oldid to newid.
     """
@@ -989,7 +1000,7 @@
                 repo._bookmarks[b] = newid
             dirty = True
         if dirty:
-            repo._bookmarks.write()
+            repo._bookmarks.recordchange(tr)
     return updatebookmarks
 
 ### bookmarks api compatibility layer ###
@@ -1081,8 +1092,8 @@
         fn, opts, _syn = entry
     else:
         fn, opts, = entry
-    deprecationwarning = _('%s have been deprecated in favor of %s\n' % (
-        oldalias, newalias))
+    deprecationwarning = _('%s have been deprecated in favor of %s\n') % (
+        oldalias, newalias)
     def newfn(*args, **kwargs):
         ui = args[0]
         ui.warn(deprecationwarning)
@@ -1500,17 +1511,17 @@
 
 @command('^evolve|stabilize|solve',
     [('n', 'dry-run', False,
-        'do not perform actions, just print what would be done'),
+        _('do not perform actions, just print what would be done')),
      ('', 'confirm', False,
-        'ask for confirmation before performing the action'),
-    ('A', 'any', False, 'also consider troubled changesets unrelated to current working directory'),
-    ('r', 'rev', [], 'solves troubles of these revisions'),
-    ('', 'bumped', False, 'solves only bumped changesets'),
-    ('', 'divergent', False, 'solves only divergent changesets'),
-    ('', 'unstable', False, 'solves only unstable changesets (default)'),
-    ('a', 'all', False, 'evolve all troubled changesets related to the current '
-                         'working directory and its descendants'),
-    ('c', 'continue', False, 'continue an interrupted evolution'),
+        _('ask for confirmation before performing the action')),
+    ('A', 'any', False, _('also consider troubled changesets unrelated to current working directory')),
+    ('r', 'rev', [], _('solves troubles of these revisions')),
+    ('', 'bumped', False, _('solves only bumped changesets')),
+    ('', 'divergent', False, _('solves only divergent changesets')),
+    ('', 'unstable', False, _('solves only unstable changesets (default)')),
+    ('a', 'all', False, _('evolve all troubled changesets related to the current '
+                         'working directory and its descendants')),
+    ('c', 'continue', False, _('continue an interrupted evolution')),
     ] + mergetoolopts,
     _('[OPTIONS]...'))
 def evolve(ui, repo, **opts):
@@ -1706,16 +1717,23 @@
         obs = obs.parents()[0]
         newer = obsolete.successorssets(repo, obs.node())
     if len(newer) > 1:
-        msg = _("skipping %s: divergent rewriting. can't choose destination\n" % obs)
+        msg = _("skipping %s: divergent rewriting. can't choose destination\n") % obs
         ui.write_err(msg)
         return 2
     targets = newer[0]
     assert targets
     if len(targets) > 1:
-        msg = _("does not handle split parents yet\n")
-        ui.write_err(msg)
-        return 2
-    target = targets[0]
+        # split target, figure out which one to pick, are they all in line?
+        targetrevs = [repo[r].rev() for r in targets]
+        roots = repo.revs('roots(%ld)', targetrevs)
+        heads = repo.revs('heads(%ld)', targetrevs)
+        if len(roots) > 1 or len(heads) > 1:
+            msg = "cannot solve split accross two branches\n"
+            ui.write_err(msg)
+            return 2
+        target = repo[heads.first()]
+    else:
+        target = targets[0]
     displayer = cmdutil.show_changeset(ui, repo, {'template': shorttemplate})
     target = repo[target]
     if not ui.quiet or confirm:
@@ -1750,13 +1768,13 @@
     bumped = repo[bumped.rev()]
     # For now we deny bumped merge
     if len(bumped.parents()) > 1:
-        msg = _('skipping %s : we do not handle merge yet\n' % bumped)
+        msg = _('skipping %s : we do not handle merge yet\n') % bumped
         ui.write_err(msg)
         return 2
     prec = repo.set('last(allprecursors(%d) and public())', bumped).next()
     # For now we deny target merge
     if len(prec.parents()) > 1:
-        msg = _('skipping: %s: public version is a merge, this not handled yet\n' % prec)
+        msg = _('skipping: %s: public version is a merge, this not handled yet\n') % prec
         ui.write_err(msg)
         return 2
 
@@ -1778,9 +1796,9 @@
     if progresscb: progresscb()
     newid = tmpctx = None
     tmpctx = bumped
-    bmupdate = _bookmarksupdater(repo, bumped.node())
     # Basic check for common parent. Far too complicated and fragile
     tr = repo.transaction('bumped-stabilize')
+    bmupdate = _bookmarksupdater(repo, bumped.node(), tr)
     try:
         if not list(repo.set('parents(%d) and parents(%d)', bumped, prec)):
             # Need to rebase the changeset at the right place
@@ -1904,7 +1922,7 @@
         displayer.show(other)
         ui.write(_('base: '))
         displayer.show(base)
-    if confirm and ui.prompt('perform evolve? [Ny]', 'n') != 'y':
+    if confirm and ui.prompt(_('perform evolve? [Ny]'), 'n') != 'y':
         raise util.Abort(_('evolve aborted by user'))
     if dryrun:
         ui.write('hg update -c %s &&\n' % divergent)
@@ -1984,13 +2002,15 @@
 
 @command('^previous',
          [('B', 'move-bookmark', False,
-             _('Move active bookmark after update')),
-          ('', 'merge', False, _('bring uncommited change along'))],
-         '[-B]')
+             _('move active bookmark after update')),
+          ('', 'merge', False, _('bring uncommitted change along')),
+          ('n', 'dry-run', False, _('do not perform actions, just print what would be done'))],
+         '[OPTION]...')
 def cmdprevious(ui, repo, **opts):
     """update to parent and display summary lines"""
     wkctx = repo[None]
     wparents = wkctx.parents()
+    dryrunopt = opts['dry_run']
     if len(wparents) != 1:
         raise util.Abort('merge in progress')
     if not opts['merge']:
@@ -2006,17 +2026,22 @@
         p = parents[0]
         bm = bmactive(repo)
         shouldmove = opts.get('move_bookmark') and bm is not None
-        ret = hg.update(repo, p.rev())
-        if not ret:
-            wlock = repo.wlock()
-            try:
-                if shouldmove:
-                    repo._bookmarks[bm] = p.node()
-                    repo._bookmarks.write()
-                else:
-                    bmdeactivate(repo)
-            finally:
-                wlock.release()
+        if dryrunopt:
+            ui.write('hg update %s;\n' % p.rev())
+            if shouldmove:
+                ui.write('hg bookmark %s -r %s;\n' % (bm, p.rev()))
+        else:
+            ret = hg.update(repo, p.rev())
+            if not ret:
+                wlock = repo.wlock()
+                try:
+                    if shouldmove:
+                        repo._bookmarks[bm] = p.node()
+                        repo._bookmarks.write()
+                    else:
+                        bmdeactivate(repo)
+                finally:
+                    wlock.release()
         displayer.show(p)
         return 0
     else:
@@ -2027,10 +2052,11 @@
 
 @command('^next',
          [('B', 'move-bookmark', False,
-             _('Move active bookmark after update')),
-          ('', 'merge', False, _('bring uncommited change along')),
-          ('', 'evolve', False, _('evolve the next changeset if necessary'))],
-         '[-B]')
+             _('move active bookmark after update')),
+          ('', 'merge', False, _('bring uncommitted change along')),
+          ('', 'evolve', False, _('evolve the next changeset if necessary')),
+          ('n', 'dry-run', False, _('do not perform actions, just print what would be done'))],
+         '[OPTION]...')
 def cmdnext(ui, repo, **opts):
     """update to next child
 
@@ -2039,6 +2065,7 @@
     The summary line of the destination is displayed for clarity"""
     wkctx = repo[None]
     wparents = wkctx.parents()
+    dryrunopt = opts['dry_run']
     if len(wparents) != 1:
         raise util.Abort('merge in progress')
     if not opts['merge']:
@@ -2054,17 +2081,22 @@
         c = children[0]
         bm = bmactive(repo)
         shouldmove = opts.get('move_bookmark') and bm is not None
-        ret = hg.update(repo, c.rev())
-        if not ret:
-            wlock = repo.wlock()
-            try:
-                if shouldmove:
-                    repo._bookmarks[bm] = c.node()
-                    repo._bookmarks.write()
-                else:
-                    bmdeactivate(repo)
-            finally:
-                wlock.release()
+        if dryrunopt:
+            ui.write('hg update %s;\n' % c.rev())
+            if shouldmove:
+                ui.write('hg bookmark %s -r %s;\n' % (bm, c.rev()))
+        else:
+            ret = hg.update(repo, c.rev())
+            if not ret:
+                wlock = repo.wlock()
+                try:
+                    if shouldmove:
+                        repo._bookmarks[bm] = c.node()
+                        repo._bookmarks.write()
+                    else:
+                        bmdeactivate(repo)
+                finally:
+                    wlock.release()
         displayer.show(c)
         result = 0
     elif children:
@@ -2083,14 +2115,14 @@
                 ui.warn(msg % len(aspchildren))
             result = 1
         elif 1 < len(aspchildren):
-            ui.warn("ambigious next (unstable) changeset:\n")
+            ui.warn(_("ambigious next (unstable) changeset:\n"))
             for c in aspchildren:
                 displayer.show(repo[c])
             ui.warn(_('(run "hg evolve --rev REV" on one of them)\n'))
             return 1
         else:
             cmdutil.bailifchanged(repo)
-            result = _solveone(ui, repo, repo[aspchildren[0]], False,
+            result = _solveone(ui, repo, repo[aspchildren[0]], dryrunopt,
                                False, lambda:None, category='unstable')
             if not result:
                 ui.status(_('working directory now at %s\n') % repo['.'])
@@ -2157,6 +2189,8 @@
      ('r', 'rev', [], _("revisions to prune")),
      ('k', 'keep', None, _("does not modify working copy during prune")),
      ('', 'biject', False, _("do a 1-1 map between rev and successor ranges")),
+     ('', 'fold', False, _("record a fold (multiple precursors, one successors)")),
+     ('', 'split', False, _("record a split (on precursor, multiple successors)")),
      ('B', 'bookmark', '', _("remove revs only reachable from given"
                              " bookmark"))] + metadataopts,
     _('[OPTION] [-r] REV...'))
@@ -2179,12 +2213,22 @@
     revisions to prune and successor changesets. This option may be removed in
     a future release (with the functionality absorbed automatically).
 
+    If you specify multiple revisions in --succ, you are recording a "split"
+    and have to acknowledge it by usng --split. The same logic apply when you
+    prune multiple changesets with a single successors, this will record a
+    "fold" requires a --fold flag.
     """
     revs = scmutil.revrange(repo, list(revs) + opts.get('rev'))
     succs = opts['new'] + opts['succ']
     bookmark = opts.get('bookmark')
     metadata = _getmetadata(**opts)
     biject = opts.get('biject')
+    fold = opts.get('fold')
+    split = opts.get('split')
+
+    options = [o for o in ('biject', 'fold', 'split') if opts.get(o)]
+    if 1 < len(options):
+        raise util.Abort(_("can only specify one of %s") % ', '.join(options))
 
     if bookmark:
         marks,revs = _reachablefrombookmark(repo, revs, bookmark)
@@ -2224,15 +2268,20 @@
         if not biject and len(sucs) > 1 and len(precs) > 1:
             msg = "Can't use multiple successors for multiple precursors"
             raise util.Abort(msg)
-
-        if biject and len(sucs) != len(precs):
+        elif biject and len(sucs) != len(precs):
             msg = "Can't use %d successors for %d precursors" \
                 % (len(sucs), len(precs))
             raise util.Abort(msg)
-
-        relations = [(p, sucs) for p in precs]
-        if biject:
+        elif (len(precs) == 1 and len(sucs) > 1) and not split:
+            msg = "please add --split if you want to do a split"
+            raise util.Abort(msg)
+        elif len(sucs) == 1 and len(precs) > 1 and not fold:
+            msg = "please add --fold if you want to do a fold"
+            raise util.Abort(msg)
+        elif biject:
             relations = [(p, (s,)) for p, s in zip(precs, sucs)]
+        else:
+            relations = [(p, sucs) for p in precs]
 
         wdp = repo['.']
 
@@ -2303,7 +2352,7 @@
             # slower. The new forms makes as much sense and a much faster.
             for dest in ctx.ancestors():
                 if not dest.obsolete():
-                    updatebookmarks = _bookmarksupdater(repo, ctx.node())
+                    updatebookmarks = _bookmarksupdater(repo, ctx.node(), tr)
                     updatebookmarks(dest.node())
                     break
 
@@ -2488,7 +2537,6 @@
         if len(old.parents()) > 1:
             raise util.Abort(_("cannot uncommit merge changeset"))
         oldphase = old.phase()
-        updatebookmarks = _bookmarksupdater(repo, old.node())
 
 
         rev = None
@@ -2505,6 +2553,7 @@
 
         # Recommit the filtered changeset
         tr = repo.transaction('uncommit')
+        updatebookmarks = _bookmarksupdater(repo, old.node(), tr)
         newid = None
         includeorexclude = opts.get('include') or opts.get('exclude')
         if (pats or includeorexclude or opts.get('all')):
@@ -2557,6 +2606,84 @@
     finally:
         lockmod.release(lock, wlock)
 
+@command('^split',
+    [('r', 'rev', [], _("revision to fold")),
+    ] + commitopts + commitopts2,
+    _('hg split [OPTION]... [-r] REV'))
+def cmdsplit(ui, repo, *revs, **opts):
+    """Split the current commit using interactive selection
+
+    By default, split the current revision by prompting for all its hunk to be
+    redistributed into new changesets.
+
+    Use --rev for splitting a given changeset instead.
+    """
+    tr = wlock = lock = None
+    newcommits = []
+
+    revopt = opts.get('rev')
+    if revopt:
+        revs = scmutil.revrange(repo, revopt)
+        if len(revs) != 1:
+            raise util.Abort(_("you can only specify one revision to split"))
+        else:
+            rev = list(revs)[0]
+    else:
+        rev = '.'
+
+    try:
+        wlock = repo.wlock()
+        lock = repo.lock()
+        cmdutil.bailifchanged(repo)
+        tr = repo.transaction('split')
+        ctx = repo[rev]
+        r = ctx.rev()
+        disallowunstable = not obsolete.isenabled(repo,
+                                                  obsolete.allowunstableopt)
+        if disallowunstable:
+            # XXX We should check head revs
+            if repo.revs("(%d::) - %d", rev, rev):
+                raise util.Abort(_("cannot split commit: %s not a head") % ctx)
+
+        if len(ctx.parents()) > 1:
+            raise util.Abort(_("cannot split merge commits"))
+        prev = ctx.p1()
+        bmupdate = _bookmarksupdater(repo, ctx.node(), tr)
+        bookactive = bmactive(repo)
+        if bookactive is not None:
+            repo.ui.status(_("(leaving bookmark %s)\n") % bmactive(repo))
+        bmdeactivate(repo)
+        hg.update(repo, prev)
+
+        commands.revert(ui, repo, rev=r, all=True)
+        def haschanges():
+            modified, added, removed, deleted = repo.status()[:4]
+            return modified or added or removed or deleted
+        while haschanges():
+            pats = ()
+            cmdutil.dorecord(ui, repo, commands.commit, 'commit', False,
+                             cmdutil.recordfilter, *pats, **opts)
+            # TODO: Does no seem like the best way to do this
+            # We should make dorecord return the newly created commit
+            newcommits.append(repo['.'])
+            if haschanges():
+                if ui.prompt('Done splitting? [yN]', default='n') == 'y':
+                    commands.commit(ui, repo, **opts)
+                    newcommits.append(repo['.'])
+                    break
+            else:
+                ui.status("no more change to split\n")
+
+        tip = repo[newcommits[-1]]
+        bmupdate(tip.node())
+        if bookactive is not None:
+            bmactivate(repo, bookactive)
+        obsolete.createmarkers(repo, [(repo[r], newcommits)])
+        tr.close()
+    finally:
+        lockmod.release(tr, lock, wlock)
+
+
 @eh.wrapcommand('strip', extension='strip', opts=[
     ('', 'bundle', None, _("delete the commit entirely and move it to a "
         "backup bundle")),
@@ -2940,6 +3067,8 @@
     missing = set()
     common = set()
     undecided = set(probeset)
+    totalnb = len(undecided)
+    ui.progress("comparing with other", 0, total=totalnb)
     _takefullsample = setdiscovery._takefullsample
     if remote.capable('_evoext_obshash_1'):
         getremotehash = remote.evoext_obshash1
@@ -2957,6 +3086,8 @@
             sample = _takefullsample(dag, undecided, size=fullsamplesize)
 
         roundtrips += 1
+        ui.progress("comparing with other", totalnb - len(undecided),
+                    total=totalnb)
         ui.debug("query %i; still undecided: %i, sample size is: %i\n"
                  % (roundtrips, len(undecided), len(sample)))
         # indices between sample and externalized version must match
@@ -2976,6 +3107,7 @@
         undecided.difference_update(common)
 
 
+    ui.progress("comparing with other", None, total=totalnb)
     result = dag.headsetofconnecteds(common)
     ui.debug("%d total queries\n" % roundtrips)
 
@@ -3294,6 +3426,7 @@
     cache = []
     unfi = repo.unfiltered()
     markercache = {}
+    repo.ui.progress("preparing locally", 0, total=len(unfi))
     for i in unfi:
         ctx = unfi[i]
         entry = 0
@@ -3323,6 +3456,8 @@
             cache.append((ctx.node(), sha.digest()))
         else:
             cache.append((ctx.node(), nullid))
+        repo.ui.progress("preparing locally", i, total=len(unfi))
+    repo.ui.progress("preparing locally", None)
     return cache
 
 @command('debugobsrelsethashtree',
@@ -3368,11 +3503,11 @@
     [('', 'new-format', _bestformat, _('Destination format for markers.'))],
     '')
 def debugobsconvert(ui, repo, new_format):
+    origmarkers = repo.obsstore._all  # settle version
     if new_format == repo.obsstore._version:
         msg = _('New format is the same as the old format, not upgrading!')
         raise util.Abort(msg)
     f = repo.svfs('obsstore', 'wb', atomictemp=True)
-    origmarkers = repo.obsstore._all
     known = set()
     markers = []
     for m in origmarkers:
@@ -3418,7 +3553,8 @@
         return capabilities(oldcap, repo, proto)
     wireproto.commands['capabilities'] = (newcap, args)
 
-def _helploader():
+# Mercurial >= 3.6 passes ui
+def _helploader(ui=None):
     return help.gettext(evolutionhelptext)
 
 @eh.uisetup
--- a/hgext/inhibit.py	Mon Oct 12 01:22:41 2015 -0700
+++ b/hgext/inhibit.py	Mon Oct 12 01:23:59 2015 -0700
@@ -208,8 +208,11 @@
     try:
         extensions.find('directaccess')
     except KeyError:
-        errormsg = _('Cannot use inhibit without the direct access extension')
-        raise error.Abort(errormsg)
+        errormsg = _('cannot use inhibit without the direct access extension\n')
+        hint = _("(please enable it or inhibit won\'t work)\n")
+        ui.warn(errormsg)
+        ui.warn(hint)
+        return
 
     # Wrapping this to inhibit obsolete revs resulting from a transaction
     extensions.wrapfunction(localrepo.localrepository,
--- a/tests/test-amend.t	Mon Oct 12 01:22:41 2015 -0700
+++ b/tests/test-amend.t	Mon Oct 12 01:23:59 2015 -0700
@@ -115,6 +115,7 @@
   branch: foo
   commit: 1 unknown (clean)
   update: (current)
+  phases: 3 draft
 
 Check the help
   $ hg amend -h
--- a/tests/test-corrupt.t	Mon Oct 12 01:22:41 2015 -0700
+++ b/tests/test-corrupt.t	Mon Oct 12 01:23:59 2015 -0700
@@ -101,7 +101,7 @@
      summary:     add A
   
 
-  $ hg kill -n -1 -- -2 -3
+  $ hg kill --fold -n -1 -- -2 -3
   2 changesets pruned
   $ hg push ../other
   pushing to ../other
@@ -110,8 +110,7 @@
   adding manifests
   adding file changes
   added 1 changesets with 2 changes to 2 files
-  pushing 2 obsolescence markers (*) (glob)
-  2 obsolescence markers added
+  2 new obsolescence markers
   $ hg -R ../other verify
   checking changesets
   checking manifests
--- a/tests/test-evolve-bumped.t	Mon Oct 12 01:22:41 2015 -0700
+++ b/tests/test-evolve-bumped.t	Mon Oct 12 01:23:59 2015 -0700
@@ -49,7 +49,6 @@
   adding manifests
   adding file changes
   added 1 changesets with 1 changes to 1 files
-  pull obsolescence markers
   (run 'hg update' to get a working copy)
   $ hg log -r 'draft()'
   1:4d1169d82e47@default(draft) modify a
@@ -68,7 +67,6 @@
   pulling from ../public
   searching for changes
   no changes found
-  pull obsolescence markers
   1 new bumped changesets
 
   $ hg evolve -a -A --bumped
--- a/tests/test-evolve-order.t	Mon Oct 12 01:22:41 2015 -0700
+++ b/tests/test-evolve-order.t	Mon Oct 12 01:23:59 2015 -0700
@@ -110,13 +110,13 @@
   atop:[13] bprime
   move:[8] add _d
   atop:[14] add _c
-  working directory is now at 225d2cc5d3fc
+  working directory is now at 739f18ac1d03
   $ hg log -G
-  @  15:225d2cc5d3fc@default(draft) add _d
+  @  15:739f18ac1d03@default(draft) add _d
   |
-  o  14:0fc229278e4d@default(draft) add _c
+  o  14:e5960578d158@default(draft) add _c
   |
-  o  13:c3741b9eafae@default(draft) bprime
+  o  13:4ad33fa88946@default(draft) bprime
   |
   o  12:9a584314f3f3@default(draft) asecond
   |
@@ -139,21 +139,21 @@
   1 changesets pruned
   1 new unstable changesets
   $ hg log -G -r "desc(_d)::"
-  @  22:a329855d0bc1@default(draft) add c1second
+  @  22:dcf786e878fd@default(draft) add c1second
   |
-  | o  21:072276ece1bf@default(draft) add c2prime
+  | o  21:507d52d715f6@default(draft) add c2prime
   | |
-  | x  20:f137acd06692@default(draft) add c1prime
+  | x  20:c995cb124ddc@default(draft) add c1prime
   |/
-  | o  19:0a1d9b2ce733@default(draft) add c4_
+  | o  19:d096a2437fd0@default(draft) add c4_
   | |
-  | o  18:e2874f41c56c@default(draft) add c3_
+  | o  18:cde95c6cba7a@default(draft) add c3_
   | |
-  | x  17:3247c33339fa@default(draft) add c2_
+  | x  17:e0d9f7a099fe@default(draft) add c2_
   | |
-  | x  16:df322257c182@default(draft) add c1_
+  | x  16:43b7c338b1f8@default(draft) add c1_
   |/
-  o  15:225d2cc5d3fc@default(draft) add _d
+  o  15:739f18ac1d03@default(draft) add _d
   |
 
 Second set of stack with no successor for b2_:
@@ -168,45 +168,45 @@
   1 changesets pruned
 
   $ hg log -G -r "desc(_d)::"
-  @  28:ba4c348b6d5e@default(draft) add b3prime
+  @  28:b253ff5b65d1@default(draft) add b3prime
   |
-  o  27:8fe985f5d0aa@default(draft) add b1prime
+  o  27:4acf61f11dfb@default(draft) add b1prime
   |
-  | o  26:1d9ba2e75c93@default(draft) add b4_
+  | o  26:594e1fbbd61f@default(draft) add b4_
   | |
-  | x  25:aec6a9657b6c@default(draft) add b3_
+  | x  25:be27500cfc76@default(draft) add b3_
   | |
-  | x  24:a69b58575918@default(draft) add b2_
+  | x  24:b54f77dc5831@default(draft) add b2_
   | |
-  | x  23:3564eb18e448@default(draft) add b1_
+  | x  23:0e1eba27e9aa@default(draft) add b1_
   |/
-  | o  22:a329855d0bc1@default(draft) add c1second
+  | o  22:dcf786e878fd@default(draft) add c1second
   |/
-  | o  21:072276ece1bf@default(draft) add c2prime
+  | o  21:507d52d715f6@default(draft) add c2prime
   | |
-  | x  20:f137acd06692@default(draft) add c1prime
+  | x  20:c995cb124ddc@default(draft) add c1prime
   |/
-  | o  19:0a1d9b2ce733@default(draft) add c4_
+  | o  19:d096a2437fd0@default(draft) add c4_
   | |
-  | o  18:e2874f41c56c@default(draft) add c3_
+  | o  18:cde95c6cba7a@default(draft) add c3_
   | |
-  | x  17:3247c33339fa@default(draft) add c2_
+  | x  17:e0d9f7a099fe@default(draft) add c2_
   | |
-  | x  16:df322257c182@default(draft) add c1_
+  | x  16:43b7c338b1f8@default(draft) add c1_
   |/
-  o  15:225d2cc5d3fc@default(draft) add _d
+  o  15:739f18ac1d03@default(draft) add _d
   |
 
 Solve the full second stack and only part of the first one
   $ echo "(desc(_d)::) - desc(c3_)"
   (desc(_d)::) - desc(c3_)
   $ hg evolve --rev "(desc(_d)::) - desc(c3_)"
-  cannot solve instability of 0a1d9b2ce733, skipping
+  cannot solve instability of d096a2437fd0, skipping
   move:[21] add c2prime
   atop:[22] add c1second
   move:[26] add b4_
   atop:[28] add b3prime
-  working directory is now at 4897c8ed7645
+  working directory is now at ea93190a9cd1
 
 Cleanup
   $ hg evolve --rev "(desc(_d)::)"
@@ -214,23 +214,23 @@
   atop:[29] add c2prime
   move:[19] add c4_
   atop:[31] add c3_
-  working directory is now at 4ee8feb52325
+  working directory is now at 35e7b797ace5
   $ hg log -G -r "desc(_d)::"
-  @  32:4ee8feb52325@default(draft) add c4_
+  @  32:35e7b797ace5@default(draft) add c4_
   |
-  o  31:08a530ce67e1@default(draft) add c3_
+  o  31:0b9488394e89@default(draft) add c3_
   |
-  | o  30:4897c8ed7645@default(draft) add b4_
+  | o  30:ea93190a9cd1@default(draft) add b4_
   | |
-  o |  29:3abc7618dd5f@default(draft) add c2prime
+  o |  29:881b9c092e53@default(draft) add c2prime
   | |
-  | o  28:ba4c348b6d5e@default(draft) add b3prime
+  | o  28:b253ff5b65d1@default(draft) add b3prime
   | |
-  | o  27:8fe985f5d0aa@default(draft) add b1prime
+  | o  27:4acf61f11dfb@default(draft) add b1prime
   | |
-  o |  22:a329855d0bc1@default(draft) add c1second
+  o |  22:dcf786e878fd@default(draft) add c1second
   |/
-  o  15:225d2cc5d3fc@default(draft) add _d
+  o  15:739f18ac1d03@default(draft) add _d
   |
 
 Test multiple revision with some un-evolvable because parent is splitted
@@ -258,6 +258,6 @@
   $ hg evolve --rev 'unstable()'
   move:[30] add b4_
   atop:[35] b3second
-  skipping 08a530ce67e1: divergent rewriting. can't choose destination
-  working directory is now at a51a8a82fdba
+  skipping 0b9488394e89: divergent rewriting. can't choose destination
+  working directory is now at 31809a198477
 
--- a/tests/test-evolve-split.t	Mon Oct 12 01:22:41 2015 -0700
+++ b/tests/test-evolve-split.t	Mon Oct 12 01:23:59 2015 -0700
@@ -43,7 +43,7 @@
   $ printf "pp" > pp;
   $ hg add pp
   $ hg commit -m "_pp"
-  $ hg prune --succ "desc(_oo) + desc(_pp)" -r "desc('oo+pp')"
+  $ hg prune --succ "desc(_oo) + desc(_pp)" -r "desc('oo+pp')" --split
   1 changesets pruned
   1 new unstable changesets
   $ hg log -G
@@ -58,4 +58,6 @@
   o  0:58663bb03074@default(draft) add aa
   
   $ hg evolve --rev "0::"
-  does not handle split parents yet
+  move:[2] add uu
+  atop:[4] _pp
+  working directory is now at 6f5bbe2e3df3
--- a/tests/test-evolve.t	Mon Oct 12 01:22:41 2015 -0700
+++ b/tests/test-evolve.t	Mon Oct 12 01:23:59 2015 -0700
@@ -335,7 +335,7 @@
   move:[4] another feature (child of 568a468b60fc)
   atop:[6] a nifty feature
   merging main-file-1
-  working directory is now at 5c9c8d9c2e4e
+  working directory is now at 99833d22b0c6
   $ hg log
   7	feature-B: another feature (child of ba0ec09b1bab) - test
   6	feature-A: a nifty feature - test
@@ -376,10 +376,10 @@
   recreate:[8] another feature that rox
   atop:[7] another feature (child of ba0ec09b1bab)
   computing new diff
-  committed as 476d0454d60e
-  working directory is now at 476d0454d60e
+  committed as 2d8c5414e9f0
+  working directory is now at 2d8c5414e9f0
   $ hg glog
-  @  9	feature-B: bumped update to 5c9c8d9c2e4e: - test
+  @  9	feature-B: bumped update to 99833d22b0c6: - test
   |
   o  7	: another feature (child of ba0ec09b1bab) - test
   |
@@ -436,7 +436,7 @@
   move:[11] dansk 3!
   atop:[14] dansk 2!
   merging main-file-1
-  working directory is now at cfb5ebed336d
+  working directory is now at 536984593824
   $ hg glog
   @  15	: dansk 3! - test
   |
@@ -474,7 +474,6 @@
   adding manifests
   adding file changes
   added 1 changesets with 1 changes to 1 files
-  pull obsolescence markers
   $ cd alpha
 
   $ cat << EOF > A
@@ -531,8 +530,7 @@
   adding manifests
   adding file changes
   added 1 changesets with 1 changes to 1 files
-  pull obsolescence markers
-  2 obsolescence markers added
+  2 new obsolescence markers
   (run 'hg update' to get a working copy)
   $ hg up
   2 files updated, 0 files merged, 0 files removed, 0 files unresolved
@@ -811,11 +809,11 @@
   2 changesets folded
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
   $ glog
-  @  16:d6239ff09c9f@default(draft) Folding with custom commit message
+  @  16:d1297ecc971f@default(draft) Folding with custom commit message
   |
-  o  13:56ade053f46d@default(draft) dansk!
+  o  13:27b934eaf1f9@default(draft) dansk!
   |
-  o  7:5c9c8d9c2e4e@default(public) another feature (child of ba0ec09b1bab)
+  o  7:99833d22b0c6@default(public) another feature (child of ba0ec09b1bab)
   |
   o  6:ba0ec09b1bab@default(public) a nifty feature
   |
@@ -830,9 +828,9 @@
   2 changesets folded
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
   $ hg qlog
-  17 - dba606655966 A longer
+  17 - 0b1eca0e871b A longer
                     commit message (draft)
-  7 - 5c9c8d9c2e4e another feature (child of ba0ec09b1bab) (public)
+  7 - 99833d22b0c6 another feature (child of ba0ec09b1bab) (public)
   6 - ba0ec09b1bab a nifty feature (public)
   0 - e55e0562ee93 base (public)
 
@@ -897,11 +895,11 @@
   $ hg evolve
   move:[5] a2
   atop:[7] a1_
-  working directory is now at 5406c5cfee42
+  working directory is now at eb07e22a0e63
   $ hg evolve
   move:[6] a3
   atop:[8] a2
-  working directory is now at c7661e655801
+  working directory is now at 777c26ca5e78
   $ hg log -G --template '{rev} [{branch}] {desc|firstline}\n'
   @  9 [mybranch] a3
   |
@@ -950,7 +948,7 @@
   move:[8] a2
   atop:[10] a1__
   (leaving bookmark testbookmark)
-  working directory is now at f37ed7a60f43
+  working directory is now at d952e93add6f
   $ ls .hg/bookmarks*
   .hg/bookmarks
 
@@ -1016,12 +1014,12 @@
   recreate:[12] add new file bumped
   atop:[11] a2
   computing new diff
-  committed as d66b1e328488
-  working directory is now at d66b1e328488
+  committed as f15d32934071
+  working directory is now at f15d32934071
   $ hg evolve --any
   move:[9] a3
-  atop:[13] bumped update to f37ed7a60f43:
-  working directory is now at 7d2ce5f38f9b
+  atop:[13] bumped update to d952e93add6f:
+  working directory is now at cce26b684bfe
 Check that we can resolve troubles in a revset with more than one commit
   $ hg up 14 -C
   0 files updated, 0 files merged, 0 files removed, 0 files unresolved
@@ -1040,7 +1038,7 @@
   |/
   @  14	: a3 - test
   |
-  o  13	: bumped update to f37ed7a60f43: - test
+  o  13	: bumped update to d952e93add6f: - test
   |
   o  11	: a2 - test
   |
@@ -1059,7 +1057,7 @@
   | |/
   | x  14	: a3 - test
   |/
-  o  13	: bumped update to f37ed7a60f43: - test
+  o  13	: bumped update to d952e93add6f: - test
   |
   o  11	: a2 - test
   |
@@ -1082,7 +1080,7 @@
   atop:[18] a3
   move:[16] add gh
   atop:[18] a3
-  working directory is now at db3d894869b0
+  working directory is now at e02107f98737
   $ hg glog
   @  20	: add gh - test
   |
@@ -1090,7 +1088,7 @@
   |/
   o  18	: a3 - test
   |
-  o  13	: bumped update to f37ed7a60f43: - test
+  o  13	: bumped update to d952e93add6f: - test
   |
   o  11	: a2 - test
   |
@@ -1212,26 +1210,26 @@
   $ hg amend
   2 new unstable changesets
   $ glog -r "18::"
-  @  25:4c0bc042ef3b@default(draft) add j1
+  @  25:8dc373be86d9@default(draft) add j1
   |
-  | o  23:c70048fd3350@default(draft) add j3
+  | o  23:d7eadcf6eccd@default(draft) add j3
   | |
-  | o  22:714e60ca57b7@default(draft) add j2
+  | o  22:2223ea564144@default(draft) add j2
   | |
-  | x  21:b430835af718@default(draft) add j1
+  | x  21:48490698b269@default(draft) add j1
   |/
-  | o  20:db3d894869b0@default(draft) add gh
+  | o  20:e02107f98737@default(draft) add gh
   | |
-  o |  19:10ffdd7e3cc9@default(draft) add gg
+  o |  19:24e63b319adf@default(draft) add gg
   |/
-  o  18:0bb66d4c1968@default(draft) a3
+  o  18:edc3c9de504e@default(draft) a3
   |
 
   $ hg evolve --rev 23 --any
   abort: cannot specify both "--rev" and "--any"
   [255]
   $ hg evolve --rev 23
-  cannot solve instability of c70048fd3350, skipping
+  cannot solve instability of d7eadcf6eccd, skipping
 
 Check that uncommit respects the allowunstable option
 With only createmarkers we can only uncommit on a head
@@ -1239,30 +1237,30 @@
   > [experimental]
   > evolution=createmarkers, allnewcommands
   > EOF
-  $ hg up 4c0bc042ef3b^
+  $ hg up 8dc373be86d9^
   0 files updated, 0 files merged, 2 files removed, 0 files unresolved
   $ hg uncommit --all
   abort: cannot uncommit in the middle of a stack
   [255]
-  $ hg up 4c0bc042ef3b
+  $ hg up 8dc373be86d9
   2 files updated, 0 files merged, 0 files removed, 0 files unresolved
   $ hg uncommit --all
   new changeset is empty
   (use "hg prune ." to remove it)
   $ glog -r "18::"
-  @  26:04b32348803e@default(draft) add j1
+  @  26:044804d0c10d@default(draft) add j1
   |
-  | o  23:c70048fd3350@default(draft) add j3
+  | o  23:d7eadcf6eccd@default(draft) add j3
   | |
-  | o  22:714e60ca57b7@default(draft) add j2
+  | o  22:2223ea564144@default(draft) add j2
   | |
-  | x  21:b430835af718@default(draft) add j1
+  | x  21:48490698b269@default(draft) add j1
   |/
-  | o  20:db3d894869b0@default(draft) add gh
+  | o  20:e02107f98737@default(draft) add gh
   | |
-  o |  19:10ffdd7e3cc9@default(draft) add gg
+  o |  19:24e63b319adf@default(draft) add gg
   |/
-  o  18:0bb66d4c1968@default(draft) a3
+  o  18:edc3c9de504e@default(draft) a3
   |
 
 Check that prune respects the allowunstable option
@@ -1279,19 +1277,19 @@
   atop:[26] add j1
   move:[23] add j3
   atop:[27] add j2
-  working directory is now at 920a35e8dbd0
+  working directory is now at c9a20e2d74aa
   $ glog -r "18::"
-  @  28:920a35e8dbd0@default(draft) add j3
+  @  28:c9a20e2d74aa@default(draft) add j3
   |
-  o  27:31e050d895dd@default(draft) add j2
+  o  27:b0e3066231e2@default(draft) add j2
   |
-  o  26:04b32348803e@default(draft) add j1
+  o  26:044804d0c10d@default(draft) add j1
   |
-  | o  20:db3d894869b0@default(draft) add gh
+  | o  20:e02107f98737@default(draft) add gh
   | |
-  o |  19:10ffdd7e3cc9@default(draft) add gg
+  o |  19:24e63b319adf@default(draft) add gg
   |/
-  o  18:0bb66d4c1968@default(draft) a3
+  o  18:edc3c9de504e@default(draft) a3
   |
   $ hg up 19
   0 files updated, 0 files merged, 2 files removed, 0 files unresolved
@@ -1306,30 +1304,30 @@
   $ hg prune '26::'
   3 changesets pruned
   $ glog -r "18::"
-  @  29:5a6c53544778@default(draft) add c5_
+  @  29:2251801b6c91@default(draft) add c5_
   |
-  | o  20:db3d894869b0@default(draft) add gh
+  | o  20:e02107f98737@default(draft) add gh
   | |
-  o |  19:10ffdd7e3cc9@default(draft) add gg
+  o |  19:24e63b319adf@default(draft) add gg
   |/
-  o  18:0bb66d4c1968@default(draft) a3
+  o  18:edc3c9de504e@default(draft) a3
   |
 
 Check that fold respects the allowunstable option
-  $ hg up 0bb66d4c1968
+  $ hg up edc3c9de504e
   0 files updated, 0 files merged, 2 files removed, 0 files unresolved
   $ mkcommit unstableifparentisfolded
   created new head
   $ glog -r "18::"
-  @  30:30ecefd67c0a@default(draft) add unstableifparentisfolded
+  @  30:68330ac625b8@default(draft) add unstableifparentisfolded
   |
-  | o  29:5a6c53544778@default(draft) add c5_
+  | o  29:2251801b6c91@default(draft) add c5_
   | |
-  +---o  20:db3d894869b0@default(draft) add gh
+  +---o  20:e02107f98737@default(draft) add gh
   | |
-  | o  19:10ffdd7e3cc9@default(draft) add gg
+  | o  19:24e63b319adf@default(draft) add gg
   |/
-  o  18:0bb66d4c1968@default(draft) a3
+  o  18:edc3c9de504e@default(draft) a3
   |
 
   $ hg fold --exact "19 + 18"
@@ -1350,13 +1348,13 @@
   > EOF
 
   $ glog -r "18::"
-  o  31:5cc6eda0f00d@default(draft) add gg
+  o  31:580886d07058@default(draft) add gg
   |
-  | @  30:30ecefd67c0a@default(draft) add unstableifparentisfolded
+  | @  30:68330ac625b8@default(draft) add unstableifparentisfolded
   |/
-  | o  20:db3d894869b0@default(draft) add gh
+  | o  20:e02107f98737@default(draft) add gh
   |/
-  o  18:0bb66d4c1968@default(draft) a3
+  o  18:edc3c9de504e@default(draft) a3
   |
 
 Create a split commit
@@ -1374,27 +1372,29 @@
   $ printf "pp" > pp;
   $ hg add pp
   $ hg commit -m "_pp"
-  $ hg prune --succ "desc(_oo) + desc(_pp)" -r "desc('oo+pp')"
+  $ hg prune --succ "desc(_oo) + desc(_pp)" -r "desc('oo+pp')" --split
   1 changesets pruned
   1 new unstable changesets
   $ glog -r "18::"
-  @  35:072908d77206@default(draft) _pp
+  @  35:7a555adf2b4a@default(draft) _pp
   |
-  o  34:68e429987343@default(draft) _oo
+  o  34:2be4d2d5bf34@default(draft) _oo
   |
-  | o  33:030868870864@default(draft) add uu
+  | o  33:53f0c003e03e@default(draft) add uu
   | |
-  | x  32:7e9688cf0a1b@default(draft) oo+pp
+  | x  32:1bf2152f4f82@default(draft) oo+pp
   |/
-  | o  31:5cc6eda0f00d@default(draft) add gg
+  | o  31:580886d07058@default(draft) add gg
   | |
-  o |  30:30ecefd67c0a@default(draft) add unstableifparentisfolded
+  o |  30:68330ac625b8@default(draft) add unstableifparentisfolded
   |/
-  | o  20:db3d894869b0@default(draft) add gh
+  | o  20:e02107f98737@default(draft) add gh
   |/
-  o  18:0bb66d4c1968@default(draft) a3
+  o  18:edc3c9de504e@default(draft) a3
   |
   $ hg evolve --rev "18::"
-  does not handle split parents yet
+  move:[33] add uu
+  atop:[35] _pp
+  working directory is now at 43c3f5ef149f
 
 
--- a/tests/test-inhibit.t	Mon Oct 12 01:22:41 2015 -0700
+++ b/tests/test-inhibit.t	Mon Oct 12 01:23:59 2015 -0700
@@ -133,6 +133,7 @@
   branch: default
   commit: (clean)
   update: 1 new changesets, 2 branch heads (merge)
+  phases: 6 draft
 
 check public revision got cleared
 (when adding the second inhibitor, the first one is removed because it is public)
@@ -352,10 +353,18 @@
   +cD
 
   $ hg export 1 3
-  abort: filtered revision '1' (not in 'visible-directaccess-nowarn' subset)!
+  abort: hidden revision '1'!
+  (use --hidden to access hidden revisions)
   [255]
 
 
+Test directaccess in a larger revset
+
+  $ hg log -r '. + .^ + 2db36d8066ff' -T '{node|short}\n'
+  55c73a90e4b4
+  cf5c4f4554ce
+  2db36d8066ff
+
 With severals hidden sha, rebase of one hidden stack onto another one:
   $ hg update -C 0
   0 files updated, 0 files merged, 4 files removed, 0 files unresolved
@@ -397,12 +406,12 @@
   o  0:54ccbc537fc2 add cA
   
   $ hg rebase -s 10 -d 3 
-  abort: filtered revision '3' (not in 'visible-directaccess-warn' subset)!
+  abort: hidden revision '3'!
+  (use --hidden to access hidden revisions)
   [255]
   $ hg rebase -r ad78ff7d621f -r 53a94305e133 -d  2db36d8066ff
   Warning: accessing hidden changesets 2db36d8066ff for write operation
-  Warning: accessing hidden changesets ad78ff7d621f for write operation
-  Warning: accessing hidden changesets 53a94305e133 for write operation
+  Warning: accessing hidden changesets ad78ff7d621f,53a94305e133 for write operation
   rebasing 10:ad78ff7d621f "add cK"
   rebasing 11:53a94305e133 "add cL"
   $ hg log -G
@@ -722,9 +731,10 @@
   > directaccess=!
   > testextension=!
   > EOF
-  $ hg up 15
-  abort: Cannot use inhibit without the direct access extension
-  [255]
+  $ hg up .
+  cannot use inhibit without the direct access extension
+  (please enable it or inhibit won't work)
+  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
   $ echo "directaccess=$(echo $(dirname $TESTDIR))/hgext/directaccess.py" >> $HGRCPATH
   $ cd ..
 
@@ -758,8 +768,7 @@
   adding manifests
   adding file changes
   added 1 changesets with 1 changes to 1 files
-  pushing 33 obsolescence markers (*) (glob)
-  2 obsolescence markers added
+  2 new obsolescence markers
 
 Pulling from a inhibit repo to a non-inhibit repo should work
 
--- a/tests/test-obsolete.t	Mon Oct 12 01:22:41 2015 -0700
+++ b/tests/test-obsolete.t	Mon Oct 12 01:23:59 2015 -0700
@@ -184,8 +184,7 @@
   adding manifests
   adding file changes
   added 5 changesets with 5 changes to 5 files (+1 heads)
-  pushing 2 obsolescence markers (*) (glob)
-  2 obsolescence markers added
+  2 new obsolescence markers
   $ hg -R ../other-new verify
   checking changesets
   checking manifests
@@ -239,8 +238,7 @@
   adding manifests
   adding file changes
   added 1 changesets with 1 changes to 1 files (+1 heads)
-  pushing 3 obsolescence markers (*) (glob)
-  1 obsolescence markers added
+  1 new obsolescence markers
   $ qlog -R ../other-new
   5
   - 95de7fc6918d
@@ -262,8 +260,6 @@
   pushing to ../other-new
   searching for changes
   no changes found
-  pushing 3 obsolescence markers (*) (glob)
-  0 obsolescence markers added
   [1]
 
   $ hg up --hidden -q .^ # 3
@@ -279,9 +275,8 @@
   adding manifests
   adding file changes
   added 1 changesets with 1 changes to [12] files \(\+1 heads\) (re)
-  pull obsolescence markers
-  1 obsolescence markers added
-  (run 'hg heads' to see heads, 'hg merge' to merge)
+  1 new obsolescence markers
+  (run 'hg heads .' to see heads, 'hg merge' to merge)
   $ qlog -R ../other-new
   6
   - 909a0fb57e5d
@@ -370,9 +365,8 @@
   adding manifests
   adding file changes
   added 1 changesets with 1 changes to [12] files \(\+1 heads\) (re)
-  pull obsolescence markers
-  1 obsolescence markers added
-  (run 'hg heads' to see heads, 'hg merge' to merge)
+  1 new obsolescence markers
+  (run 'hg heads .' to see heads, 'hg merge' to merge)
 
   $ hg up -q 7 # to check rollback update behavior
   $ qlog
@@ -395,6 +389,7 @@
   branch: default
   commit: 1 deleted, 2 unknown (clean)
   update: 2 new changesets, 2 branch heads (merge)
+  phases: 4 draft
   unstable: 1 changesets
   $ qlog
   6
@@ -544,8 +539,7 @@
   adding manifests
   adding file changes
   added 2 changesets with 1 changes to [12] files (re)
-  pushing 7 obsolescence markers (*) (glob)
-  3 obsolescence markers added
+  3 new obsolescence markers
   $ hg up -q 10
   $ mkcommit "obsol_d'''"
   created new head
@@ -557,8 +551,7 @@
   adding manifests
   adding file changes
   added 1 changesets with 1 changes to 1 files (+1 heads)
-  pushing 8 obsolescence markers (*) (glob)
-  1 obsolescence markers added
+  1 new obsolescence markers
   $ cd ..
 
 check bumped detection
@@ -659,7 +652,7 @@
 #no produced by 2.3
 33d458d86621f3186c40bfccd77652f4a122743e 3734a65252e69ddcced85901647a4f335d40de1e 0 {'date': '* *', 'user': 'test'} (glob)
 
-Check divergence detection
+Check divergence detection (note: multiple successors is sorted by changeset hash)
 
   $ hg up 9468a5f5d8b2 #  add obsol_d''
   1 files updated, 0 files merged, 1 files removed, 0 files unresolved
@@ -670,6 +663,7 @@
   branch: default
   commit: (clean)
   update: (2|9|11) new changesets, (3|9|10) branch heads \(merge\) (re)
+  phases: 3 draft
   bumped: 1 changesets
   $ hg debugobsolete `getid a7a6f2b5d8a5` `getid 50f11e5e3a63`
   $ hg log -r 'divergent()'
--- a/tests/test-prev-next.t	Mon Oct 12 01:22:41 2015 -0700
+++ b/tests/test-prev-next.t	Mon Oct 12 01:23:59 2015 -0700
@@ -22,6 +22,10 @@
    * mark                      0:a154386e50d1
 
 hg next -B should move active bookmark
+  $ hg next -B --dry-run
+  hg update 1;
+  hg bookmark mark -r 1;
+  [1] added b
   $ hg next -B
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
   [1] added b
@@ -29,6 +33,9 @@
    * mark                      1:6e742c9127b3
 
 hg prev should unset active bookmark
+  $ hg prev --dry-run
+  hg update 0;
+  [0] added a
   $ hg prev
   0 files updated, 0 files merged, 1 files removed, 0 files unresolved
   [0] added a
@@ -152,6 +159,11 @@
   no children
   (1 unstable changesets to be evolved here, do you want --evolve?)
   [1]
+  $ hg next --evolve --dry-run
+  move:[2] added c
+  atop:[3] added b (2)
+  hg rebase -r 4e26ef31f919 -d 9ad178109a19
+  working directory now at 9ad178109a19
   $ hg next --evolve
   move:[2] added c
   atop:[3] added b (2)
--- a/tests/test-prune.t	Mon Oct 12 01:22:41 2015 -0700
+++ b/tests/test-prune.t	Mon Oct 12 01:23:59 2015 -0700
@@ -32,6 +32,19 @@
   o  0:1f0dee641bb7[] (stable/public) add a
   
 
+Check arguments exclusive to each other
+---------------------------------------
+
+  $ hg prune --fold --biject
+  abort: can only specify one of biject, fold
+  [255]
+  $ hg prune --split --fold
+  abort: can only specify one of fold, split
+  [255]
+  $ hg prune --split --fold --biject
+  abort: can only specify one of biject, fold, split
+  [255]
+
 Check simple case
 ----------------------------
 
@@ -150,6 +163,9 @@
 one old, two new
 
   $ hg prune 'desc("add dd")' -s 'desc("add nD")' -s 'desc("add nC")'
+  abort: please add --split if you want to do a split
+  [255]
+  $ hg prune 'desc("add dd")' -s 'desc("add nD")' -s 'desc("add nC")' --split
   1 changesets pruned
   $ hg debugobsolete
   9d206ffc875e1bc304590549be293be36821e66c 0 {47d2a3944de8b013de3be9578e8e344ea2e6c097} (Sat Dec 15 00:00:00 1979 +0000) {'user': 'blah'}
@@ -190,6 +206,9 @@
 two old, one new:
 
   $ hg prune 'desc("add cc")' 'desc("add bb")' -s 'desc("add nB")'
+  abort: please add --fold if you want to do a fold
+  [255]
+  $ hg prune 'desc("add cc")' 'desc("add bb")' -s 'desc("add nB")' --fold
   2 changesets pruned
   $ hg debugobsolete
   9d206ffc875e1bc304590549be293be36821e66c 0 {47d2a3944de8b013de3be9578e8e344ea2e6c097} (Sat Dec 15 00:00:00 1979 +0000) {'user': 'blah'}
--- a/tests/test-sharing.t	Mon Oct 12 01:22:41 2015 -0700
+++ b/tests/test-sharing.t	Mon Oct 12 01:23:59 2015 -0700
@@ -46,7 +46,6 @@
   adding manifests
   adding file changes
   added 1 changesets with 1 changes to 1 files
-  pull obsolescence markers
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
 
 Let's commit a preliminary change and push it to ``test-repo`` for
@@ -88,8 +87,7 @@
   adding manifests
   adding file changes
   added 1 changesets with 1 changes to 1 files (+1 heads)
-  pull obsolescence markers
-  2 obsolescence markers added
+  2 new obsolescence markers
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
 
 Figure SG03
@@ -140,8 +138,7 @@
   adding manifests
   adding file changes
   added 1 changesets with 1 changes to 1 files
-  pushing 4 obsolescence markers (*) (glob)
-  4 obsolescence markers added
+  4 new obsolescence markers
 
 Now that the fix is public, we cannot amend it any more.
   $ hg amend -m 'fix bug 37'
@@ -161,8 +158,6 @@
   pushing to ../dev-repo
   searching for changes
   no changes found
-  pushing 4 obsolescence markers (*) (glob)
-  0 obsolescence markers added
   [1]
   $ hg -R ../dev-repo shortlog -r 'draft()'
 
@@ -196,8 +191,6 @@
   adding manifests
   adding file changes
   added 1 changesets with 1 changes to 1 files
-  pushing 4 obsolescence markers (*) (glob)
-  0 obsolescence markers added
   exporting bookmark bug15
   $ hg -R ../review bookmarks
      bug15                     2:f91e97234c2b
@@ -213,8 +206,7 @@
   adding manifests
   adding file changes
   added 1 changesets with 1 changes to 1 files (+1 heads)
-  pushing 6 obsolescence markers (*) (glob)
-  2 obsolescence markers added
+  2 new obsolescence markers
   updating bookmark bug15
   $ hg -R ../review bookmarks
      bug15                     3:cbdfbd5a5db2
@@ -241,8 +233,6 @@
   adding manifests
   adding file changes
   added 1 changesets with 1 changes to 1 files (+1 heads)
-  pushing 4 obsolescence markers (*) (glob)
-  0 obsolescence markers added
   exporting bookmark featureX
   $ hg -R ../review bookmarks
      bug15                     3:cbdfbd5a5db2
@@ -259,8 +249,7 @@
   adding manifests
   adding file changes
   added 1 changesets with 1 changes to 1 files (+1 heads)
-  pushing 6 obsolescence markers (*) (glob)
-  2 obsolescence markers added
+  2 new obsolescence markers
   updating bookmark featureX
 
 Bob receives second review, amends, and pushes to public:
@@ -274,8 +263,7 @@
   adding manifests
   adding file changes
   added 1 changesets with 1 changes to 1 files
-  pushing 8 obsolescence markers (*) (glob)
-  4 obsolescence markers added
+  4 new obsolescence markers
   $ hg -R ../public bookmarks
   no bookmarks set
   $ hg push ../review
@@ -286,8 +274,7 @@
   adding manifests
   adding file changes
   added 1 changesets with 1 changes to 1 files (+1 heads)
-  pushing 8 obsolescence markers (*) (glob)
-  2 obsolescence markers added
+  2 new obsolescence markers
   updating bookmark featureX
   $ hg -R ../review bookmarks
      bug15                     3:cbdfbd5a5db2
@@ -357,8 +344,7 @@
   adding manifests
   adding file changes
   added 1 changesets with 1 changes to 1 files (+1 heads)
-  pull obsolescence markers
-  4 obsolescence markers added
+  4 new obsolescence markers
   (run 'hg heads' to see heads, 'hg merge' to merge)
   $ hg log -G -q -r 'head()'
   o  5:540ba8f317e6
@@ -388,8 +374,7 @@
   adding manifests
   adding file changes
   added 1 changesets with 1 changes to 1 files
-  pushing 11 obsolescence markers (*) (glob)
-  3 obsolescence markers added
+  3 new obsolescence markers
   $ hg push ../review
   pushing to ../review
   searching for changes
@@ -397,8 +382,7 @@
   adding manifests
   adding file changes
   added 1 changesets with 0 changes to 1 files
-  pushing 11 obsolescence markers (*) (glob)
-  1 obsolescence markers added
+  1 new obsolescence markers
   updating bookmark bug15
 
 Figure SG08: review and public changesets after Alice pushes.
@@ -460,8 +444,6 @@
   adding manifests
   adding file changes
   added 1 changesets with 1 changes to 1 files
-  pull obsolescence markers
-  0 obsolescence markers added
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
   $ echo 'better fix (alice)' >> file1
   $ hg amend -u alice -m 'fix bug 24 (v2 by alice)'
@@ -489,8 +471,7 @@
   adding manifests
   adding file changes
   added 1 changesets with 1 changes to 1 files (+1 heads)
-  pull obsolescence markers
-  2 obsolescence markers added
+  2 new obsolescence markers
   (run 'hg heads' to see heads, 'hg merge' to merge)
   2 new divergent changesets
 
--- a/tests/test-simple4server.t	Mon Oct 12 01:22:41 2015 -0700
+++ b/tests/test-simple4server.t	Mon Oct 12 01:23:59 2015 -0700
@@ -96,7 +96,7 @@
   remote: adding manifests
   remote: adding file changes
   remote: added 1 changesets with 1 changes to 1 files (+1 heads)
-  pushing 2 obsolescence markers (*) (glob)
+  pushing 2 obsolescence markers (* bytes) (glob)
   $ cat ../errors.log
   $ hg push
   pushing to http://localhost:$HGPORT/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-split.t	Mon Oct 12 01:23:59 2015 -0700
@@ -0,0 +1,338 @@
+test of the split command
+-----------------------
+
+  $ cat >> $HGRCPATH <<EOF
+  > [defaults]
+  > amend=-d "0 0"
+  > fold=-d "0 0"
+  > split=-d "0 0"
+  > amend=-d "0 0"
+  > [web]
+  > push_ssl = false
+  > allow_push = *
+  > [phases]
+  > publish = False
+  > [diff]
+  > git = 1
+  > unified = 0
+  > [ui]
+  > interactive = true
+  > [extensions]
+  > hgext.graphlog=
+  > EOF
+  $ echo "evolve=$(echo $(dirname $TESTDIR))/hgext/evolve.py" >> $HGRCPATH
+  $ mkcommit() {
+  >    echo "$1" > "$1"
+  >    hg add "$1"
+  >    hg ci -m "add $1"
+  > }
+
+
+Basic case, split a head
+  $ hg init testsplit
+  $ cd testsplit
+  $ mkcommit _a
+  $ mkcommit _b
+  $ mkcommit _c
+  $ mkcommit _d
+  $ echo "change to a" >> _a
+  $ hg amend
+  $ hg debugobsolete
+  9e84a109b8eb081ad754681ee4b1380d17a3741f aa8f656bb307022172d2648be6fb65322f801225 0 (*) {'user': 'test'} (glob)
+  f002b57772d7f09b180c407213ae16d92996a988 0 {9e84a109b8eb081ad754681ee4b1380d17a3741f} (*) {'user': 'test'} (glob)
+
+To create commits with the number of split
+  $ echo 0 > num
+  $ cat > editor.sh << '__EOF__'
+  > NUM=$(cat num)
+  > NUM=`expr "$NUM" + 1`
+  > echo "$NUM" > num
+  > echo "split$NUM" > "$1"
+  > __EOF__
+  $ export HGEDITOR="\"sh\" \"editor.sh\""
+  $ hg split << EOF
+  > y
+  > y
+  > y
+  > n
+  > N
+  > y
+  > y
+  > EOF
+  1 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  reverting _a
+  adding _d
+  diff --git a/_a b/_a
+  1 hunks, 1 lines changed
+  examine changes to '_a'? [Ynesfdaq?] y
+  
+  @@ -1,0 +2,1 @@
+  +change to a
+  record change 1/2 to '_a'? [Ynesfdaq?] y
+  
+  diff --git a/_d b/_d
+  new file mode 100644
+  examine changes to '_d'? [Ynesfdaq?] y
+  
+  @@ -0,0 +1,1 @@
+  +_d
+  record change 2/2 to '_d'? [Ynesfdaq?] n
+  
+  created new head
+  Done splitting? [yN] N
+  diff --git a/_d b/_d
+  new file mode 100644
+  examine changes to '_d'? [Ynesfdaq?] y
+  
+  @@ -0,0 +1,1 @@
+  +_d
+  record this change to '_d'? [Ynesfdaq?] y
+  
+  no more change to split
+
+  $ hg debugobsolete
+  9e84a109b8eb081ad754681ee4b1380d17a3741f aa8f656bb307022172d2648be6fb65322f801225 0 (*) {'user': 'test'} (glob)
+  f002b57772d7f09b180c407213ae16d92996a988 0 {9e84a109b8eb081ad754681ee4b1380d17a3741f} (*) {'user': 'test'} (glob)
+  aa8f656bb307022172d2648be6fb65322f801225 a98b35e86cae589b61892127c5ec1c868e41d910 5410a2352fa3114883327beee89e3085eefac25c 0 (*) {'user': 'test'} (glob)
+  $ hg glog
+  @  changeset:   7:5410a2352fa3
+  |  tag:         tip
+  |  user:        test
+  |  date:        Thu Jan 01 00:00:00 1970 +0000
+  |  summary:     split2
+  |
+  o  changeset:   6:a98b35e86cae
+  |  parent:      2:102002290587
+  |  user:        test
+  |  date:        Thu Jan 01 00:00:00 1970 +0000
+  |  summary:     split1
+  |
+  o  changeset:   2:102002290587
+  |  user:        test
+  |  date:        Thu Jan 01 00:00:00 1970 +0000
+  |  summary:     add _c
+  |
+  o  changeset:   1:37445b16603b
+  |  user:        test
+  |  date:        Thu Jan 01 00:00:00 1970 +0000
+  |  summary:     add _b
+  |
+  o  changeset:   0:135f39f4bd78
+     user:        test
+     date:        Thu Jan 01 00:00:00 1970 +0000
+     summary:     add _a
+  
+
+Cannot split a commit with uncommited changes
+  $ hg up "desc(_c)"
+  1 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ echo "_cd" > _c
+  $ hg split 
+  abort: uncommitted changes
+  [255]
+
+Split a revision specified with -r
+  $ hg up "desc(_c)" -C
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ echo "change to b" >> _b
+  $ hg amend -m "_cprim"
+  2 new unstable changesets
+  $ hg evolve --all
+  move:[6] split1
+  atop:[9] _cprim
+  move:[7] split2
+  atop:[10] split1
+  working directory is now at * (glob)
+  $ hg log -r "desc(_cprim)" -v -p
+  changeset:   9:719157b217ac
+  parent:      1:37445b16603b
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  files:       _b _c
+  description:
+  _cprim
+  
+  
+  diff --git a/_b b/_b
+  --- a/_b
+  +++ b/_b
+  @@ -1,0 +2,1 @@
+  +change to b
+  diff --git a/_c b/_c
+  new file mode 100644
+  --- /dev/null
+  +++ b/_c
+  @@ -0,0 +1,1 @@
+  +_c
+  
+  $ hg split -r "desc(_cprim)" <<EOF
+  > y
+  > y
+  > y
+  > n
+  > y
+  > EOF
+  2 files updated, 0 files merged, 2 files removed, 0 files unresolved
+  reverting _b
+  adding _c
+  diff --git a/_b b/_b
+  1 hunks, 1 lines changed
+  examine changes to '_b'? [Ynesfdaq?] y
+  
+  @@ -1,0 +2,1 @@
+  +change to b
+  record change 1/2 to '_b'? [Ynesfdaq?] y
+  
+  diff --git a/_c b/_c
+  new file mode 100644
+  examine changes to '_c'? [Ynesfdaq?] y
+  
+  @@ -0,0 +1,1 @@
+  +_c
+  record change 2/2 to '_c'? [Ynesfdaq?] n
+  
+  created new head
+  Done splitting? [yN] y
+
+Stop before splitting the commit completely creates a commit with all the
+remaining changes
+
+  $ hg debugobsolete
+  9e84a109b8eb081ad754681ee4b1380d17a3741f aa8f656bb307022172d2648be6fb65322f801225 0 (*) {'user': 'test'} (glob)
+  f002b57772d7f09b180c407213ae16d92996a988 0 {9e84a109b8eb081ad754681ee4b1380d17a3741f} (*) {'user': 'test'} (glob)
+  aa8f656bb307022172d2648be6fb65322f801225 a98b35e86cae589b61892127c5ec1c868e41d910 5410a2352fa3114883327beee89e3085eefac25c 0 (*) {'user': 'test'} (glob)
+  10200229058723ce8d67f6612c1f6b4f73b1fe73 719157b217acc43d397369a448824ed4c7a302f2 0 (*) {'user': 'test'} (glob)
+  5d0c8b0f2d3e5e1ff95f93d7da2ba06650605ab5 0 {10200229058723ce8d67f6612c1f6b4f73b1fe73} (*) {'user': 'test'} (glob)
+  a98b35e86cae589b61892127c5ec1c868e41d910 286887947725085e03455d79649197feaef1eb9d 0 (*) {'user': 'test'} (glob)
+  5410a2352fa3114883327beee89e3085eefac25c 0b67cee46a7f2ad664f994027e7af95b36ae25fe 0 (*) {'user': 'test'} (glob)
+  719157b217acc43d397369a448824ed4c7a302f2 ced8fbcce3a7cd33f0e454d2cd63882ce1b6006b 73309fb98db840ba4ec5ad528346dc6ee0b39dcb 0 (*) {'user': 'test'} (glob)
+  $ hg evolve --all
+  move:[10] split1
+  atop:[13] split4
+  move:[11] split2
+  atop:[14] split1
+  working directory is now at f200e612ac86
+  $ hg glog
+  @  changeset:   15:f200e612ac86
+  |  tag:         tip
+  |  user:        test
+  |  date:        Thu Jan 01 00:00:00 1970 +0000
+  |  summary:     split2
+  |
+  o  changeset:   14:aec57822a8ff
+  |  user:        test
+  |  date:        Thu Jan 01 00:00:00 1970 +0000
+  |  summary:     split1
+  |
+  o  changeset:   13:73309fb98db8
+  |  user:        test
+  |  date:        Thu Jan 01 00:00:00 1970 +0000
+  |  summary:     split4
+  |
+  o  changeset:   12:ced8fbcce3a7
+  |  parent:      1:37445b16603b
+  |  user:        test
+  |  date:        Thu Jan 01 00:00:00 1970 +0000
+  |  summary:     split3
+  |
+  o  changeset:   1:37445b16603b
+  |  user:        test
+  |  date:        Thu Jan 01 00:00:00 1970 +0000
+  |  summary:     add _b
+  |
+  o  changeset:   0:135f39f4bd78
+     user:        test
+     date:        Thu Jan 01 00:00:00 1970 +0000
+     summary:     add _a
+  
+
+Split should move bookmarks on the last split successor and preserve the
+active bookmark as active
+  $ hg book bookA
+  $ hg book bookB
+  $ echo "changetofilea" > _a
+  $ hg amend
+  $ hg book
+     bookA                     17:39d16b69c75d
+   * bookB                     17:39d16b69c75d
+  $ hg glog -r "14::"
+  @  changeset:   17:39d16b69c75d
+  |  bookmark:    bookA
+  |  bookmark:    bookB
+  |  tag:         tip
+  |  parent:      14:aec57822a8ff
+  |  user:        test
+  |  date:        Thu Jan 01 00:00:00 1970 +0000
+  |  summary:     split2
+  |
+  o  changeset:   14:aec57822a8ff
+  |  user:        test
+  |  date:        Thu Jan 01 00:00:00 1970 +0000
+  |  summary:     split1
+  |
+  $ hg split <<EOF
+  > y
+  > y
+  > n
+  > y
+  > EOF
+  (leaving bookmark bookB)
+  1 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  reverting _a
+  adding _d
+  diff --git a/_a b/_a
+  1 hunks, 2 lines changed
+  examine changes to '_a'? [Ynesfdaq?] y
+  
+  @@ -1,2 +1,1 @@
+  -_a
+  -change to a
+  +changetofilea
+  record change 1/2 to '_a'? [Ynesfdaq?] y
+  
+  diff --git a/_d b/_d
+  new file mode 100644
+  examine changes to '_d'? [Ynesfdaq?] n
+  
+  created new head
+  Done splitting? [yN] y
+  $ hg glog -r "14::"
+  @  changeset:   19:a2b5c9d9b362
+  |  bookmark:    bookA
+  |  bookmark:    bookB
+  |  tag:         tip
+  |  user:        test
+  |  date:        Thu Jan 01 00:00:00 1970 +0000
+  |  summary:     split6
+  |
+  o  changeset:   18:bf3402785e72
+  |  parent:      14:aec57822a8ff
+  |  user:        test
+  |  date:        Thu Jan 01 00:00:00 1970 +0000
+  |  summary:     split5
+  |
+  o  changeset:   14:aec57822a8ff
+  |  user:        test
+  |  date:        Thu Jan 01 00:00:00 1970 +0000
+  |  summary:     split1
+  |
+  $ hg book
+     bookA                     19:a2b5c9d9b362
+   * bookB                     19:a2b5c9d9b362
+ 
+Cannot specify multiple revisions with -r
+  $ hg split -r "desc(_a)::"
+  abort: you can only specify one revision to split
+  [255]
+
+Cannot split a commit that is not a head if instability is not allowed
+  $ cat >> $HGRCPATH <<EOF
+  > [experimental]
+  > evolution=createmarkers
+  > evolutioncommands=split
+  > EOF
+  $ hg split -r "desc(split3)"
+  abort: cannot split commit: ced8fbcce3a7 not a head
+  [255]
+
+
--- a/tests/test-stabilize-order.t	Mon Oct 12 01:22:41 2015 -0700
+++ b/tests/test-stabilize-order.t	Mon Oct 12 01:23:59 2015 -0700
@@ -73,9 +73,9 @@
   b
   committing manifest
   committing changelog
-  working directory is now at bede829dd2d3
+  working directory is now at 81b8bbcd5892
   $ glog
-  @  8:bede829dd2d3@default(draft) addb
+  @  8:81b8bbcd5892@default(draft) addb
   |
   o  7:005fe5914f78@default(draft) adda
   |
@@ -96,7 +96,7 @@
   $ hg evolve -v
   move:[3] addc
   atop:[8] addb
-  hg rebase -r 7a7552255fb5 -d bede829dd2d3
+  hg rebase -r 7a7552255fb5 -d 81b8bbcd5892
   resolving manifests
   getting b
   resolving manifests
@@ -105,7 +105,7 @@
   c
   committing manifest
   committing changelog
-  working directory is now at 65095d7d0dd5
+  working directory is now at 0f691739f917
   $ hg debugobsolete > successors.new
   $ diff -u successors.old successors.new
   --- successors.old* (glob)
@@ -113,16 +113,16 @@
   @@ -3,3 +3,4 @@
    93418d2c0979643ad446f621195e78720edb05b4 005fe5914f78e8bc64c7eba28117b0b1fa210d0d 0 (*) {'user': 'test'} (glob)
    7a7d76dc97c57751de9e80f61ed2a639bd03cd24 0 {93418d2c0979643ad446f621195e78720edb05b4} (*) {'user': 'test'} (glob)
-   22619daeed78036f80fbd326b6852519c4f0c25e bede829dd2d3b2ae9bf198c23432b250dc964458 0 (*) {'user': 'test'} (glob)
-  +7a7552255fb5f8bd745e46fba6f0ca633a4dd716 65095d7d0dd5e4f15503bb7b1f433a5fe9bac052 0 (*) {'user': 'test'} (glob)
+   22619daeed78036f80fbd326b6852519c4f0c25e 81b8bbcd5892841efed41433d7a5e9df922396cb 0 (*) {'user': 'test'} (glob)
+  +7a7552255fb5f8bd745e46fba6f0ca633a4dd716 0f691739f91762462bf8ba21f35fdf71fe64310e 0 (*) {'user': 'test'} (glob)
   [1]
 
 
 
   $ glog
-  @  9:65095d7d0dd5@default(draft) addc
+  @  9:0f691739f917@default(draft) addc
   |
-  o  8:bede829dd2d3@default(draft) addb
+  o  8:81b8bbcd5892@default(draft) addb
   |
   o  7:005fe5914f78@default(draft) adda
   |
@@ -140,11 +140,11 @@
   $ hg amend
   1 new unstable changesets
   $ glog
-  @  11:036cf654e942@default(draft) addb
+  @  11:7a68bc4596ea@default(draft) addb
   |
-  | o  9:65095d7d0dd5@default(draft) addc
+  | o  9:0f691739f917@default(draft) addc
   | |
-  | x  8:bede829dd2d3@default(draft) addb
+  | x  8:81b8bbcd5892@default(draft) addb
   |/
   o  7:005fe5914f78@default(draft) adda
   |
@@ -159,7 +159,7 @@
   $ hg evolve --any -v
   move:[9] addc
   atop:[11] addb
-  hg rebase -r 65095d7d0dd5 -d 036cf654e942
+  hg rebase -r 0f691739f917 -d 7a68bc4596ea
   resolving manifests
   removing c
   getting b
@@ -169,11 +169,11 @@
   c
   committing manifest
   committing changelog
-  working directory is now at e99ecf51c867
+  working directory is now at 2256dae6521f
   $ glog
-  @  12:e99ecf51c867@default(draft) addc
+  @  12:2256dae6521f@default(draft) addc
   |
-  o  11:036cf654e942@default(draft) addb
+  o  11:7a68bc4596ea@default(draft) addb
   |
   o  7:005fe5914f78@default(draft) adda
   |
@@ -198,30 +198,30 @@
   $ hg commit --amend -m "newmessage"
   2 new unstable changesets
   $ hg log -G
-  @  changeset:   15:49773ccde390
+  @  changeset:   15:f83a0bce03e4
   |  tag:         tip
-  |  parent:      11:036cf654e942
+  |  parent:      11:7a68bc4596ea
   |  user:        test
   |  date:        Thu Jan 01 00:00:00 1970 +0000
   |  summary:     newmessage
   |
-  | o  changeset:   14:a9892777b519
-  | |  parent:      12:e99ecf51c867
+  | o  changeset:   14:fa68011f392e
+  | |  parent:      12:2256dae6521f
   | |  user:        test
   | |  date:        Thu Jan 01 00:00:00 1970 +0000
   | |  summary:     secondambiguous
   | |
-  | | o  changeset:   13:0b6e26b2472d
+  | | o  changeset:   13:bdc003b6eec2
   | |/   user:        test
   | |    date:        Thu Jan 01 00:00:00 1970 +0000
   | |    summary:     firstambiguous
   | |
-  | x  changeset:   12:e99ecf51c867
+  | x  changeset:   12:2256dae6521f
   |/   user:        test
   |    date:        Thu Jan 01 00:00:00 1970 +0000
   |    summary:     addc
   |
-  o  changeset:   11:036cf654e942
+  o  changeset:   11:7a68bc4596ea
   |  parent:      7:005fe5914f78
   |  user:        test
   |  date:        Thu Jan 01 00:00:00 1970 +0000
--- a/tests/test-stabilize-result.t	Mon Oct 12 01:22:41 2015 -0700
+++ b/tests/test-stabilize-result.t	Mon Oct 12 01:23:59 2015 -0700
@@ -307,6 +307,7 @@
   branch: default
   commit: (clean)
   update: 2 new changesets, 2 branch heads (merge)
+  phases: 3 draft
   $ hg export .
   # HG changeset patch
   # User test
--- a/tests/test-tutorial.t	Mon Oct 12 01:22:41 2015 -0700
+++ b/tests/test-tutorial.t	Mon Oct 12 01:23:59 2015 -0700
@@ -224,7 +224,6 @@
   adding manifests
   adding file changes
   added 1 changesets with 1 changes to 1 files (+1 heads)
-  pull obsolescence markers
   (run 'hg heads' to see heads, 'hg merge' to merge)
 
 I now have a new heads. Note that this remote head is immutable
@@ -406,8 +405,7 @@
   adding manifests
   adding file changes
   added 3 changesets with 3 changes to 1 files
-  pushing 6 obsolescence markers (*) (glob)
-  6 obsolescence markers added
+  6 new obsolescence markers
 
 for simplicity sake we get the bathroom change in line again
 
@@ -527,8 +525,7 @@
   adding manifests
   adding file changes
   added 1 changesets with 1 changes to 1 files
-  pull obsolescence markers
-  1 obsolescence markers added
+  1 new obsolescence markers
   (run 'hg update' to get a working copy)
   $ hg log -G
   o  75954b8cd933 (public): bathroom stuff
@@ -585,8 +582,7 @@
   adding manifests
   adding file changes
   added 1 changesets with 1 changes to 1 files
-  pull obsolescence markers
-  1 obsolescence markers added
+  1 new obsolescence markers
   (run 'hg update' to get a working copy)
   $ hg log -G
   o  75954b8cd933 (draft): bathroom stuff
@@ -646,8 +642,6 @@
   adding manifests
   adding file changes
   added 1 changesets with 1 changes to 1 files (+1 heads)
-  pull obsolescence markers
-  0 obsolescence markers added
   (run 'hg heads' to see heads, 'hg merge' to merge)
   1 new unstable changesets
 
@@ -737,8 +731,7 @@
   adding manifests
   adding file changes
   added 2 changesets with 2 changes to 1 files (+1 heads)
-  pushing 10 obsolescence markers (*) (glob)
-  3 obsolescence markers added
+  3 new obsolescence markers
 
 remote get a warning that current working directory is based on an obsolete changeset
 
@@ -747,8 +740,6 @@
   pulling from $TESTTMP/local (glob)
   searching for changes
   no changes found
-  pull obsolescence markers
-  0 obsolescence markers added
   working directory parent is obsolete!
   (use "hg evolve" to update to its successor)
 
@@ -781,8 +772,6 @@
   adding manifests
   adding file changes
   added 1 changesets with 1 changes to 1 files
-  pull obsolescence markers
-  0 obsolescence markers added
   (run 'hg update' to get a working copy)
   $ hg log -G
   o  99f039c5ec9e (draft): SPAM SPAM SPAM
--- a/tests/test-uncommit.t	Mon Oct 12 01:22:41 2015 -0700
+++ b/tests/test-uncommit.t	Mon Oct 12 01:23:59 2015 -0700
@@ -138,7 +138,6 @@
 
   $ hg branch foo
   marked working directory as branch foo
-  (branches are permanent and global, did you want a bookmark?)
   $ hg mv ff f
   $ hg mv h i
   $ hg rm j
--- a/tests/test-unstable.t	Mon Oct 12 01:22:41 2015 -0700
+++ b/tests/test-unstable.t	Mon Oct 12 01:23:59 2015 -0700
@@ -182,7 +182,6 @@
 ===============================================================================
 Test instability resolution for a changeset unstable because its parent
 is obsolete with multiple successors all in one chain (simple split)
-Not supported yet
 ==============================================================================
 
   $ hg init test4
@@ -208,16 +207,16 @@
   
 
   $ hg evo --all --any --unstable
-  does not handle split parents yet
+  move:[2] add _c
+  atop:[4] add bprimesplit2
+  working directory is now at 387cc1e837d7
   $ hg log -G
-  @  4:2a4ccc0bb20c@default(draft) add bprimesplit2
+  @  5:387cc1e837d7@default(draft) add _c
+  |
+  o  4:2a4ccc0bb20c@default(draft) add bprimesplit2
   |
   o  3:8b87864bd0f4@default(draft) add bprimesplit1
   |
-  | o  2:102002290587@default(draft) add _c
-  | |
-  | x  1:37445b16603b@default(draft) add _b
-  |/
   o  0:135f39f4bd78@default(draft) add _a
   
 
@@ -228,7 +227,6 @@
 Test instability resolution for a changeset unstable because its parent
 is obsolete with multiple successors on one branches but in reverse
 order (cross-split).
-Not supported yet
 ==============================================================================
 
   $ hg init test5
@@ -263,16 +261,16 @@
   
 
   $ hg evo --all --any --unstable
-  does not handle split parents yet
+  move:[2] add _c
+  atop:[6] add bsecondsplit2
+  working directory is now at 98e3f21461ff
   $ hg log -G
-  @  6:59b942dbda14@default(draft) add bsecondsplit2
+  @  7:98e3f21461ff@default(draft) add _c
+  |
+  o  6:59b942dbda14@default(draft) add bsecondsplit2
   |
   o  5:8ffdae67d696@default(draft) add bsecondsplit1
   |
-  | o  2:102002290587@default(draft) add _c
-  | |
-  | x  1:37445b16603b@default(draft) add _b
-  |/
   o  0:135f39f4bd78@default(draft) add _a
   
 
@@ -312,7 +310,7 @@
   
 
   $ hg evo --all --any --unstable
-  does not handle split parents yet
+  cannot solve split accross two branches
   $ hg log -G
   @  4:3c69ea6aa93e@default(draft) add bprimesplit2
   |
--- a/tests/test-wireproto-bundle1.t	Mon Oct 12 01:22:41 2015 -0700
+++ b/tests/test-wireproto-bundle1.t	Mon Oct 12 01:23:59 2015 -0700
@@ -50,7 +50,6 @@
   adding manifests
   adding file changes
   added 2 changesets with 2 changes to 2 files
-  pull obsolescence markers
   (run 'hg update' to get a working copy)
   $ hg push -R ../other
   pushing to ssh://user@dummy/server
@@ -70,8 +69,7 @@
   remote: adding manifests
   remote: adding file changes
   remote: added 1 changesets with 1 changes to 1 files (+1 heads)
-  pushing 2 obsolescence markers (*) (glob)
-  remote: 2 obsolescence markers added
+  remote: 2 new obsolescence markers
   $ hg push
   pushing to ssh://user@dummy/server
   searching for changes
@@ -88,9 +86,8 @@
   adding manifests
   adding file changes
   added 1 changesets with 1 changes to [12] files \(\+1 heads\) (re)
-  pull obsolescence markers
-  2 obsolescence markers added
-  (run 'hg heads' to see heads)
+  2 new obsolescence markers
+  (run 'hg heads' to see heads, 'hg merge' to merge)
   $ hg -R ../other pull
   pulling from ssh://user@dummy/server
   searching for changes