branching: merge with stable
authorPierre-Yves David <pierre-yves.david@octobus.net>
Thu, 07 Mar 2019 10:51:48 +0100
changeset 4428 fe37721aa0d9
parent 4422 62a6f8f4e694 (diff)
parent 4427 9e2ee7dc5e34 (current diff)
child 4429 e10ebc58926e
branching: merge with stable
hgext3rd/evolve/cmdrewrite.py
hgext3rd/evolve/evolvecmd.py
tests/test-evolve-content-divergence.t
tests/test-evolve-continue.t
--- a/CHANGELOG	Thu Mar 07 01:57:43 2019 +0530
+++ b/CHANGELOG	Thu Mar 07 10:51:48 2019 +0100
@@ -1,6 +1,13 @@
 Changelog
 =========
 
+8.5.0 - in progress
+-------------------
+
+  * evolve: improved support for content-divergence with public changesets
+  * stack: support ranges in revsets indexing
+  * pick: add the standard `--tool` option
+
 8.4.1 - in progress
 -------------------
 
--- a/hgext3rd/evolve/__init__.py	Thu Mar 07 01:57:43 2019 +0530
+++ b/hgext3rd/evolve/__init__.py	Thu Mar 07 10:51:48 2019 +0100
@@ -257,14 +257,6 @@
 import struct
 
 try:
-    import StringIO as io
-    StringIO = io.StringIO
-except ImportError:
-    import io
-    StringIO = io.StringIO
-
-
-try:
     from mercurial import registrar
     registrar.templatekeyword # new in hg-3.8
 except ImportError:
--- a/hgext3rd/evolve/cmdrewrite.py	Thu Mar 07 01:57:43 2019 +0530
+++ b/hgext3rd/evolve/cmdrewrite.py	Thu Mar 07 10:51:48 2019 +0100
@@ -159,7 +159,6 @@
         old = repo['.']
         p1 = old.p1()
         rewriteutil.precheck(repo, [old.rev()], 'amend')
-        bookmarkupdater = rewriteutil.bookmarksupdater(repo, old.node(), tr)
         diffopts = patch.difffeatureopts(repo.ui, whitespace=True)
         diffopts.nodates = True
         diffopts.git = True
@@ -169,18 +168,18 @@
         for chunk, label in patch.diffui(repo, p1.node(), old.node(),
                                          match=matcher,
                                          opts=diffopts):
-                fp.write(chunk)
+            fp.write(chunk)
         newnode = _editandapply(ui, repo, pats, old, p1, fp, diffopts)
         if newnode == old.node():
             raise error.Abort(_("nothing changed"))
         metadata = {}
         if opts.get('note'):
             metadata['note'] = opts['note']
-        obsolete.createmarkers(repo, [(old, (repo[newnode],))],
-                               metadata=metadata, operation='amend')
+        replacements = {old.node(): [newnode]}
+        scmutil.cleanupnodes(repo, replacements, operation='amend',
+                             metadata=metadata)
         phases.retractboundary(repo, tr, old.phase(), [newnode])
         hg.updaterepo(repo, newnode, True)
-        bookmarkupdater(newnode)
         tr.close()
     finally:
         if tr is not None:
@@ -205,7 +204,7 @@
             for chunk, label in patch.diffui(repo, p1.node(), old.node(),
                                              match=restmatcher,
                                              opts=diffopts):
-                    afp.write(chunk)
+                afp.write(chunk)
 
         user_patch = afp.getvalue()
         if not user_patch:
@@ -523,7 +522,6 @@
 
         # Recommit the filtered changeset
         tr = repo.transaction('uncommit')
-        updatebookmarks = rewriteutil.bookmarksupdater(repo, old.node(), tr)
         if interactive:
             opts['all'] = True
             match = scmutil.match(old, pats, opts)
@@ -548,8 +546,9 @@
         if opts.get('note'):
             metadata['note'] = opts['note']
 
-        obsolete.createmarkers(repo, [(old, (repo[newid],))], metadata=metadata,
-                               operation="uncommit")
+        replacements = {old.node(): [newid]}
+        scmutil.cleanupnodes(repo, replacements, operation="uncommit",
+                             metadata=metadata)
         phases.retractboundary(repo, tr, oldphase, [newid])
         if opts.get('revert'):
             hg.updaterepo(repo, newid, True)
@@ -557,7 +556,6 @@
             with repo.dirstate.parentchange():
                 repo.dirstate.setparents(newid, node.nullid)
                 _uncommitdirstate(repo, old, match, interactive)
-        updatebookmarks(newid)
         if not repo[newid].files():
             ui.warn(_("new changeset is empty\n"))
             ui.status(_("(use 'hg prune .' to remove it)\n"))
@@ -582,7 +580,7 @@
     fp = stringio()
     for chunk, label in patch.diffui(repo, tempnode, old.node(), None,
                                      opts=diffopts):
-            fp.write(chunk)
+        fp.write(chunk)
 
     fp.seek(0)
     newnode = _patchtocommit(ui, repo, old, fp)
@@ -613,7 +611,7 @@
         raise error.Abort(_("nothing selected to uncommit"))
     fp = stringio()
     for c in chunks:
-            c.write(fp)
+        c.write(fp)
 
     fp.seek(0)
     oldnode = node.hex(old.node())[:12]
@@ -776,14 +774,9 @@
                                                          root.p2().node()],
                                                         commitopts=commitopts)
             phases.retractboundary(repo, tr, targetphase, [newid])
-            obsolete.createmarkers(repo, [(ctx, (repo[newid],))
-                                   for ctx in allctx], metadata=metadata,
-                                   operation="fold")
-            # move bookmarks from old nodes to the new one
-            # XXX: we should make rewriteutil.rewrite() handle such cases
-            for ctx in allctx:
-                bmupdater = rewriteutil.bookmarksupdater(repo, ctx.node(), tr)
-                bmupdater(newid)
+            replacements = {ctx.node(): [newid] for ctx in allctx}
+            scmutil.cleanupnodes(repo, replacements, operation="fold",
+                                 metadata=metadata)
             tr.close()
         finally:
             tr.release()
@@ -1044,9 +1037,9 @@
             msg = "please add --fold if you want to do a fold"
             raise error.Abort(msg)
         elif biject:
-            relations = [(p, (s,)) for p, s in zip(precs, sucs)]
+            replacements = {p.node(): [s.node()] for p, s in zip(precs, sucs)}
         else:
-            relations = [(p, sucs) for p in precs]
+            replacements = {p.node(): [s.node() for s in sucs] for p in precs}
 
         wdp = repo['.']
 
@@ -1106,14 +1099,8 @@
         if opts.get('note'):
             metadata['note'] = opts['note']
 
-        # create markers
-        obsolete.createmarkers(repo, relations, metadata=metadata,
-                               operation="prune")
-
-        # informs that changeset have been pruned
-        ui.status(_('%i changesets pruned\n') % len(precs))
-
         precrevs = (precursor.rev() for precursor in precs)
+        moves = {}
         for ctx in repo.unfiltered().set('bookmark() and %ld', precrevs):
             # used to be:
             #
@@ -1124,11 +1111,14 @@
             # but then revset took a lazy arrow in the knee and became much
             # slower. The new forms makes as much sense and a much faster.
             for dest in ctx.ancestors():
-                if not dest.obsolete():
-                    bookmarksupdater = rewriteutil.bookmarksupdater
-                    updatebookmarks = bookmarksupdater(repo, ctx.node(), tr)
-                    updatebookmarks(dest.node())
+                if not dest.obsolete() and dest.node() not in replacements:
+                    moves[ctx.node()] = dest.node()
                     break
+        scmutil.cleanupnodes(repo, replacements, operation="prune", moves=moves,
+                             metadata=metadata)
+
+        # informs that changeset have been pruned
+        ui.status(_('%i changesets pruned\n') % len(precs))
 
         tr.close()
     finally:
@@ -1404,7 +1394,7 @@
     [('r', 'rev', '', _('revision to pick'), _('REV')),
      ('c', 'continue', False, 'continue interrupted pick'),
      ('a', 'abort', False, 'abort interrupted pick'),
-    ],
+    ] + mergetoolopts,
     _('[-r] rev'))
 def cmdpick(ui, repo, *revs, **opts):
     """move a commit on the top of working directory parent and updates to it."""
@@ -1419,7 +1409,8 @@
     if opts.get('rev'):
         revs.append(opts['rev'])
 
-    with repo.wlock(), repo.lock(), repo.transaction('pick'):
+    overrides = {('ui', 'forcemerge'): opts.get('tool', '')}
+    with repo.wlock(), repo.lock(), repo.transaction('pick'), ui.configoverride(overrides, 'pick'):
         pickstate = state.cmdstate(repo, path='pickstate')
         pctx = repo['.']
 
@@ -1480,7 +1471,8 @@
         if pickstate:
             pickstate.delete()
         newctx = repo[newnode] if newnode else pctx
-        obsolete.createmarkers(repo, [(origctx, (newctx,))], operation="pick")
+        replacements = {origctx.node(): [newctx.node()]}
+        scmutil.cleanupnodes(repo, replacements, operation="pick")
 
         if newnode is None:
             ui.warn(_("note: picking %d:%s created no changes to commit\n") %
--- a/hgext3rd/evolve/evolvecmd.py	Thu Mar 07 01:57:43 2019 +0530
+++ b/hgext3rd/evolve/evolvecmd.py	Thu Mar 07 10:51:48 2019 +0100
@@ -18,8 +18,8 @@
     context,
     copies,
     error,
+    encoding,
     hg,
-    lock as lockmod,
     merge,
     mergeutil,
     node as nodemod,
@@ -71,11 +71,7 @@
     else:
         displayer = compat.changesetdisplayer(ui, repo,
                                               {'template': shorttemplate})
-    wlock = lock = tr = None
-    try:
-        wlock = repo.wlock()
-        lock = repo.lock()
-        tr = repo.transaction("evolve")
+    with repo.wlock(), repo.lock(), repo.transaction("evolve"):
         if 'orphan' == category:
             result = _solveunstable(ui, repo, ctx, evolvestate, displayer,
                                     dryrun, confirm, progresscb,
@@ -89,10 +85,7 @@
                                      dryrun, confirm, progresscb)
         else:
             assert False, "unknown trouble category: %s" % (category)
-        tr.close()
         return result
-    finally:
-        lockmod.release(tr, lock, wlock)
 
 def _solveunstable(ui, repo, orig, evolvestate, displayer, dryrun=False,
                    confirm=False, progresscb=None, lastsolved=None):
@@ -172,7 +165,7 @@
             repo.ui.write(_('atop:'))
             displayer.show(target)
     if confirm and ui.prompt('perform evolve? [Ny]', 'n') != 'y':
-            raise error.Abort(_('evolve aborted by user'))
+        raise error.Abort(_('evolve aborted by user'))
     if progresscb:
         progresscb()
     todo = 'hg rebase -r %s -d %s\n' % (orig, target)
@@ -349,6 +342,7 @@
     repo = repo.unfiltered()
     divergent = repo[divergent.rev()]
     evolvestate['divergent'] = divergent.node()
+    evolvestate['orig-divergent'] = divergent.node()
     # sometimes we will relocate a node in case of different parents and we can
     # encounter conflicts after relocation is done while solving
     # content-divergence and if the user calls `hg evolve --stop`, we need to
@@ -382,6 +376,17 @@
     evolvestate['other-divergent'] = other.node()
     evolvestate['base'] = base.node()
 
+    # haspubdiv: to keep track if we are solving public content-divergence
+    haspubdiv = False
+    if not other.mutable():
+        haspubdiv = True
+        publicdiv = other
+        evolvestate['public-divergent'] = other.node()
+        # for simplicity, lets keep public one to local side while merging the
+        # two csets.(local side is divergent one)
+        divergent, other = other, divergent
+        evolvestate['divergent'] = divergent.node()
+        evolvestate['other-divergent'] = other.node()
     # we don't handle merge content-divergent changesets yet
     if len(other.parents()) > 1:
         msg = _("skipping %s: %s changeset can't be "
@@ -437,6 +442,8 @@
     elif divp1 in gca and otherp1 not in gca:
         relocatereq = True
         divergent, other = other, divergent
+        evolvestate['divergent'] = divergent.node()
+        evolvestate['other-divergent'] = other.node()
         resolutionparent = divergent.p1().node()
     else:
         msg = _("skipping %s: have a different parent than %s "
@@ -499,8 +506,25 @@
 
     _mergecontentdivergents(repo, progresscb, divergent, other, base,
                             evolvestate)
-    return _completecontentdivergent(ui, repo, progresscb, divergent, other,
-                                     base, evolvestate)
+    res, newnode = _completecontentdivergent(ui, repo, progresscb, divergent,
+                                             other, base, evolvestate)
+    if not haspubdiv:
+        return (res, newnode)
+    else:
+        # when we have content-divergence with a public cset: after completing
+        # content divergence resolution the resulting node will be phase
+        # divergent with that same public cset.
+        # here newnode is phase divergent, lets resolve this divergence.
+        if not res:
+            # resolution was not successful, return
+            return (res, newnode)
+        if newnode == publicdiv.node():
+            # no changes were found that are different from public cset
+            return (res, newnode)
+        prec = publicdiv
+        bumped = repo[newnode]
+        return _resolvephasedivergent(ui, repo, prec=prec, bumped=bumped,
+                                      tmpctx=bumped)
 
 def _mergecontentdivergents(repo, progresscb, divergent, other, base,
                             evolvestate):
@@ -542,6 +566,26 @@
     # whether to store the obsmarker in the evolvestate
     storemarker = False
     resparent = evolvestate['resolutionparent']
+
+    # whether we are solving public divergence
+    haspubdiv = False
+    if evolvestate.get('public-divergent'):
+        haspubdiv = True
+        publicnode = evolvestate['public-divergent']
+        publicdiv = repo[publicnode]
+        othernode = evolvestate['other-divergent']
+        otherdiv = repo[othernode]
+
+        with repo.dirstate.parentchange():
+            repo.dirstate.setparents(publicnode, nodemod.nullid)
+            dirstatedance(repo, divergent, publicnode, None)
+        # check if node to be committed has changes same as public one
+        s = publicdiv.status()
+        if not (s.added or s.removed or s.deleted or s.modified):
+            # no changes, create markers to resolve divergence
+            obsolete.createmarkers(repo, [(otherdiv, (publicdiv,))],
+                                   operation='evolve')
+            return (True, publicnode)
     try:
         with repo.dirstate.parentchange():
             repo.dirstate.setparents(resparent, nodemod.nullid)
@@ -571,10 +615,17 @@
             new = repo[newnode]
             newnode = new.node()
             hg.updaterepo(repo, new.rev(), False)
-            obsolete.createmarkers(repo, [(divergent, (new,))], operation='evolve')
+            if haspubdiv and publicdiv == divergent:
+                bypassphase(repo, (divergent, new), operation='evolve')
+            else:
+                obsolete.createmarkers(repo, [(divergent, (new,))],
+                                       operation='evolve')
 
         # creating markers and moving phases post-resolution
-        obsolete.createmarkers(repo, [(other, (new,))], operation='evolve')
+        if haspubdiv and publicdiv == other:
+            bypassphase(repo, (other, new), operation='evolve')
+        else:
+            obsolete.createmarkers(repo, [(other, (new,))], operation='evolve')
         if storemarker:
             # storing the marker in the evolvestate
             # we just store the precursors and successor pair for now, we might
@@ -587,6 +638,46 @@
     finally:
         repo.ui.restoreconfig(emtpycommitallowed)
 
+def bypassphase(repo, relation, flag=0, metadata=None, operation='evolve'):
+    """function to create a single obsmarker relation even for public csets
+    where relation should be a single pair (prec, succ)"""
+
+    # prepare metadata
+    if metadata is None:
+        metadata = {}
+    if 'user' not in metadata:
+        luser = repo.ui.config('devel', 'user.obsmarker') or repo.ui.username()
+        metadata['user'] = encoding.fromlocal(luser)
+    # Operation metadata handling
+    useoperation = repo.ui.configbool('experimental',
+                                      'evolution.track-operation')
+    if useoperation and operation:
+        metadata['operation'] = operation
+
+    # Effect flag metadata handling
+    saveeffectflag = repo.ui.configbool('experimental',
+                                        'evolution.effect-flags')
+    with repo.transaction('add-obsolescence-marker') as tr:
+        prec, succ = relation
+        nprec = prec.node()
+        npare = None
+        nsucs = [succ.node()]
+        if not nsucs:
+            npare = tuple(p.node() for p in prec.parents())
+        if nprec in nsucs:
+            raise error.Abort(_("changeset %s cannot obsolete itself") % prec)
+
+        if saveeffectflag:
+            # The effect flag is saved in a versioned field name for
+            # future evolution
+            effectflag = obsutil.geteffectflag(prec, (succ,))
+            metadata[obsutil.EFFECTFLAGFIELD] = "%d" % effectflag
+
+        # create markers
+        repo.obsstore.create(tr, nprec, nsucs, flag, parents=npare,
+                             metadata=metadata, ui=repo.ui)
+        repo.filteredrevcache.clear()
+
 def dirstatedance(repo, oldparent, newparent, match):
     """utility function to fix the dirstate when we change parents from
     oldparent to newparent with a dirty working directory using
@@ -897,7 +988,7 @@
         # uurrgs
         # there no other topic setter yet
         if not orig.topic() and repo.vfs.exists('topic'):
-                repo.vfs.unlink('topic')
+            repo.vfs.unlink('topic')
         else:
             with repo.vfs.open('topic', 'w') as f:
                 f.write(orig.topic())
@@ -1298,10 +1389,12 @@
         compat.progress(ui, _('evolve'), None)
 
     if not shouldupdate:
+        # Move back to startnode, or to its successor if the start node is
+        # obsolete (perhaps made obsolete by the current `hg evolve`)
         unfi = repo.unfiltered()
         succ = utility._singlesuccessor(repo, unfi[startnode])
         hg.updaterepo(repo, repo[succ].node(), False)
-    if repo['.'] != startnode:
+    if repo['.'].node() != startnode:
         ui.status(_('working directory is now at %s\n') % repo['.'])
 
 def divergentsets(repo, ctx):
@@ -1456,7 +1549,7 @@
     contopt = opts['continue']
     anyopt = opts['any']
     allopt = opts['all']
-    startnode = repo['.']
+    startnode = repo['.'].node()
     dryrunopt = opts['dry_run']
     confirmopt = opts['confirm']
     revopt = opts['rev']
@@ -1554,7 +1647,7 @@
         # cbor does not know how to serialize sets, using list for skippedrevs
         stateopts = {'category': targetcat, 'replacements': {},
                      'revs': list(revs), 'confirm': confirmopt,
-                     'startnode': startnode.node(), 'skippedrevs': [],
+                     'startnode': startnode, 'skippedrevs': [],
                      'command': 'evolve', 'orphanmerge': False,
                      'bookmarkchanges': [], 'temprevs': [], 'obsmarkers': []}
         evolvestate.addopts(stateopts)
@@ -1601,8 +1694,9 @@
     _cleanup(ui, repo, startnode, showprogress, shouldupdate)
 
 def solveobswdp(ui, repo, opts):
+    """this function updates to the successor of obsolete wdir parent"""
     oldid = repo['.'].node()
-    startnode = repo['.']
+    startctx = repo['.']
     dryrunopt = opts.get('dry_run', False)
     displayer = compat.changesetdisplayer(ui, repo,
                                           {'template': shorttemplate})
@@ -1625,7 +1719,7 @@
     res = hg.update(repo, ctx.rev())
     newid = ctx.node()
 
-    if ctx != startnode:
+    if ctx != startctx:
         with repo.wlock(), repo.lock(), repo.transaction('evolve') as tr:
             bmupdater = rewriteutil.bookmarksupdater(repo, oldid, tr)
             bmupdater(newid)
@@ -1820,8 +1914,26 @@
                                         repo[other],
                                         repo[base],
                                         evolvestate)
-        evolvestate['replacements'][divergent] = ret[1]
+        origdivergent = evolvestate['orig-divergent']
+        evolvestate['replacements'][origdivergent] = ret[1]
+        # logic to continue the public content-divergent
+        publicnode = evolvestate.get('public-divergent')
+        if publicnode:
+            res, newnode = ret
+            if not res:
+                # no need to proceed for phase divergence resolution step
+                pass
+            elif newnode == publicnode:
+                # merging had the same changes as public changeset and
+                # divergence has been resolved by creating markers
+                pass
+            else:
+                prec = repo[publicnode]
+                bumped = repo[newnode]
+                ret = _resolvephasedivergent(ui, repo, prec=prec,
+                                             bumped=bumped, tmpctx=bumped)
         tr.close()
+        return ret
     finally:
         tr.release()
 
--- a/hgext3rd/evolve/metadata.py	Thu Mar 07 01:57:43 2019 +0530
+++ b/hgext3rd/evolve/metadata.py	Thu Mar 07 10:51:48 2019 +0100
@@ -5,7 +5,7 @@
 # This software may be used and distributed according to the terms of the
 # GNU General Public License version 2 or any later version.
 
-__version__ = '8.4.1.dev'
+__version__ = '8.5.0.dev'
 testedwith = '4.4.2 4.5.2 4.6.2 4.7 4.8 4.9'
 minimumhgversion = '4.4'
 buglink = 'https://bz.mercurial-scm.org/'
--- a/hgext3rd/evolve/obsdiscovery.py	Thu Mar 07 01:57:43 2019 +0530
+++ b/hgext3rd/evolve/obsdiscovery.py	Thu Mar 07 10:51:48 2019 +0100
@@ -15,13 +15,6 @@
 
 from __future__ import absolute_import
 
-try:
-    import StringIO as io
-    StringIO = io.StringIO
-except ImportError:
-    import io
-    StringIO = io.StringIO
-
 import hashlib
 import heapq
 import inspect
--- a/hgext3rd/evolve/obsexchange.py	Thu Mar 07 01:57:43 2019 +0530
+++ b/hgext3rd/evolve/obsexchange.py	Thu Mar 07 10:51:48 2019 +0100
@@ -8,11 +8,9 @@
 from __future__ import absolute_import
 
 try:
-    import StringIO as io
-    StringIO = io.StringIO
+    from StringIO import StringIO
 except ImportError:
-    import io
-    StringIO = io.StringIO
+    from io import StringIO
 
 from mercurial import (
     bundle2,
--- a/hgext3rd/evolve/utility.py	Thu Mar 07 01:57:43 2019 +0530
+++ b/hgext3rd/evolve/utility.py	Thu Mar 07 10:51:48 2019 +0100
@@ -164,7 +164,7 @@
     promptmsg = customheader + "\n"
     for idx, rev in enumerate(revs):
         curctx = repo[rev]
-        revmsg = "%d: [%s] %s\n" % (idx, curctx,
+        revmsg = "%d: [%s] %s\n" % (idx + 1, curctx,
                                     curctx.description().split("\n")[0])
         promptmsg += revmsg
 
@@ -181,9 +181,9 @@
         ui.write_err(_("invalid value '%s' entered for index\n") % idxselected)
         return None
 
-    if intidx >= len(revs) or intidx < 0:
+    if intidx > len(revs) or intidx <= 0:
         # we can make this error message better
         ui.write_err(_("invalid value '%d' entered for index\n") % intidx)
         return None
 
-    return revs[intidx]
+    return revs[intidx - 1]
--- a/hgext3rd/serverminitopic.py	Thu Mar 07 01:57:43 2019 +0530
+++ b/hgext3rd/serverminitopic.py	Thu Mar 07 10:51:48 2019 +0100
@@ -146,6 +146,10 @@
     return hasminitopic(repo) and repo.filtername not in _publiconly
 
 class _topiccache(branchmap.branchcache): # combine me with branchmap.branchcache
+    @classmethod
+    def fromfile(cls, repo):
+        orig = super(_topiccache, cls).fromfile
+        return wrapread(orig, repo)
 
     def __init__(self, *args, **kwargs):
         # super() call may fail otherwise
@@ -226,6 +230,12 @@
 
 def uisetup(ui):
     wrapclass(branchmap, 'branchcache', _topiccache)
-    extensions.wrapfunction(branchmap, 'read', wrapread)
+    try:
+        # Mercurial 4.8 and older
+        extensions.wrapfunction(branchmap, 'read', wrapread)
+    except AttributeError:
+        # Mercurial 4.9; branchcache.fromfile now takes care of this
+        # which is alredy defined on _topiccache
+        pass
     extensions.wrapfunction(wireproto, '_capabilities', wireprotocaps)
     extensions.wrapfunction(context.changectx, 'branch', topicbranch)
--- a/hgext3rd/topic/__init__.py	Thu Mar 07 01:57:43 2019 +0530
+++ b/hgext3rd/topic/__init__.py	Thu Mar 07 10:51:48 2019 +0100
@@ -177,7 +177,7 @@
               'topic.active': 'green',
              }
 
-__version__ = '0.13.1.dev'
+__version__ = '0.14.0.dev'
 
 testedwith = '4.4.2 4.5.2 4.6.2 4.7 4.8 4.9'
 minimumhgversion = '4.4'
--- a/hgext3rd/topic/revset.py	Thu Mar 07 01:57:43 2019 +0530
+++ b/hgext3rd/topic/revset.py	Thu Mar 07 10:51:48 2019 +0100
@@ -108,7 +108,7 @@
     return revset.baseset(stack.stack(repo, branch=branch, topic=topic)[1:]) & subset
 
 if util.safehasattr(revset, 'subscriptrelations'):
-    def stackrel(repo, subset, x, rel, n, order):
+    def stackrel(repo, subset, x, rel, z, order):
         """This is a revset-flavored implementation of stack aliases.
 
         The syntax is: rev#stack[n] or rev#s[n]. Plenty of logic is borrowed
@@ -116,9 +116,25 @@
         (e.g. when stack index is too high), this returns empty set to be more
         revset-friendly.
         """
+        # hg 4.9 provides a number or None, hg 5.0 provides a tuple of tokens
+        if isinstance(z, tuple):
+            a, b = revset.getintrange(
+                z,
+                'relation subscript must be an integer or a range',
+                'relation subscript bounds must be integers',
+                None, None)
+        else:
+            a = b = z
+
         s = revset.getset(repo, revset.fullreposet(repo), x)
         if not s:
             return revset.baseset()
+
+        def getrange(st, a, b):
+            start = 1 if a is None else a
+            end = len(st.revs) if b is None else b + 1
+            return range(start, end)
+
         revs = []
         for r in s:
             topic = repo[r].topic()
@@ -126,32 +142,29 @@
                 st = stack.stack(repo, topic=topic)
             else:
                 st = stack.stack(repo, branch=repo[r].branch())
-            if n < 0:
-                st = list(st)[1:]
-            else:
-                st = list(st)
-            try:
-                rev = st[n]
-            except IndexError:
-                continue
-            if rev == -1 and n == 0:
-                continue
-            if rev not in revs:
-                revs.append(rev)
+            for n in getrange(st, a, b):
+                if abs(n) >= len(st.revs):
+                    # also means stack base is not accessible with n < 0, which
+                    # is by design
+                    continue
+                if n == 0 and b != 0 and a != 0:
+                    # quirk: we don't want stack base unless specifically asked
+                    # for it (at least one of the indices is 0)
+                    continue
+                rev = st.revs[n]
+                if rev == -1 and n == 0:
+                    continue
+                if rev not in revs:
+                    revs.append(rev)
+
         return subset & revset.baseset(revs)
 
     revset.subscriptrelations['stack'] = stackrel
     revset.subscriptrelations['s'] = stackrel
 
-    def topicrel(repo, subset, x, rel, n, order):
-        ancestors = revset._ancestors
-        descendants = revset._descendants
-        subset = topicset(repo, subset, x)
-        if n <= 0:
-            n = -n
-            return ancestors(repo, subset, x, startdepth=n, stopdepth=n + 1)
-        else:
-            return descendants(repo, subset, x, startdepth=n, stopdepth=n + 1)
+    def topicrel(repo, subset, x, *args):
+        subset &= topicset(repo, subset, x)
+        return revset.generationsrel(repo, subset, x, *args)
 
     revset.subscriptrelations['topic'] = topicrel
     revset.subscriptrelations['t'] = topicrel
--- a/hgext3rd/topic/topicmap.py	Thu Mar 07 01:57:43 2019 +0530
+++ b/hgext3rd/topic/topicmap.py	Thu Mar 07 10:51:48 2019 +0100
@@ -117,7 +117,21 @@
     class topiccache(_topiccache, branchmap.branchcache):
         pass
     branchmap.branchcache = topiccache
-    extensions.wrapfunction(branchmap, 'updatecache', _wrapupdatebmcache)
+
+    try:
+        # Mercurial 4.9
+        class remotetopiccache(_topiccache, branchmap.remotebranchcache):
+            pass
+        branchmap.remotebranchcache = remotetopiccache
+
+        def _wrapupdatebmcachemethod(orig, self, repo):
+            # pass in the bound method as the original
+            return _wrapupdatebmcache(orig.__get__(self), repo)
+        extensions.wrapfunction(branchmap.BranchMapCache, 'updatecache', _wrapupdatebmcachemethod)
+    except AttributeError:
+        # Mercurial 4.8 and before
+        extensions.wrapfunction(branchmap, 'updatecache', _wrapupdatebmcache)
+
 
 def _wrapupdatebmcache(orig, repo):
     previous = getattr(repo, '_autobranchmaptopic', False)
--- a/tests/test-evolve-content-divergence.t	Thu Mar 07 01:57:43 2019 +0530
+++ b/tests/test-evolve-content-divergence.t	Thu Mar 07 10:51:48 2019 +0100
@@ -595,7 +595,7 @@
   @@ -0,0 +1,1 @@
   +bar
 
-Testing when the relocation will result in conflicts and merging wont
+Testing when the relocation will result in conflicts and merging also:
 ----------------------------------------------------------------------
 
   $ hg glog
@@ -660,7 +660,7 @@
   o  0:8fa14d15e168 added hgignore
       () [default] draft
 
-  $ hg evolve --content-divergent
+  $ hg evolve --content-divergent --any
   merge:[25] added z
   with: [23] added z
   base: [22] added z
--- a/tests/test-evolve-continue.t	Thu Mar 07 01:57:43 2019 +0530
+++ b/tests/test-evolve-continue.t	Thu Mar 07 10:51:48 2019 +0100
@@ -127,6 +127,7 @@
   $ hg evolve --continue
   evolving 7:ad0a59d83efe "added e"
   evolution of 7:ad0a59d83efe created no changes to commit
+  working directory is now at 00a5c774cc37
 
   $ hg glog
   @  8:00a5c774cc37 added d
--- a/tests/test-evolve-issue5832.t	Thu Mar 07 01:57:43 2019 +0530
+++ b/tests/test-evolve-issue5832.t	Thu Mar 07 10:51:48 2019 +0100
@@ -112,17 +112,17 @@
 Resolving instability using `hg evolve`
 
   $ hg evolve --any --all --config ui.interactive=True <<EOF
-  > 0
+  > 1
   > EOF
   move:[2] added b
   atop:[5] added a
   move:[4] merge commit
   ancestor '7235ef625ea3' split over multiple topological branches.
   choose an evolve destination:
-  0: [62fb70414f99] added c
-  1: [5841d7cf9893] added d
+  1: [62fb70414f99] added c
+  2: [5841d7cf9893] added d
   q: quit the prompt
-  enter the index of the revision you want to select: 0
+  enter the index of the revision you want to select: 1
   move:[9] merge commit
   atop:[6] added c
   working directory is now at 28a0775ac832
@@ -253,17 +253,17 @@
   could not solve instability, ambiguous destination: parent split across two branches
 
   $ hg evolve --any --all --config ui.interactive=True <<EOF
-  > 1
+  > 2
   > EOF
   move:[2] added b
   atop:[6] added a
   move:[4] merge commit
   ancestor 'cdf2ea1b9312' split over multiple topological branches.
   choose an evolve destination:
-  0: [62fb70414f99] added c
-  1: [5841d7cf9893] added d
+  1: [62fb70414f99] added c
+  2: [5841d7cf9893] added d
   q: quit the prompt
-  enter the index of the revision you want to select: 1
+  enter the index of the revision you want to select: 2
   move:[10] merge commit
   atop:[8] added d
   working directory is now at 460e6e72b7f9
@@ -398,16 +398,16 @@
   could not solve instability, ambiguous destination: parent split across two branches
 
   $ hg evolve --any --all --config ui.interactive=True <<EOF
-  > 1
+  > 2
   > EOF
   move:[2] added b
   atop:[6] added a
   ancestor 'b9b387427a53' split over multiple topological branches.
   choose an evolve destination:
-  0: [62fb70414f99] added c
-  1: [5841d7cf9893] added d
+  1: [62fb70414f99] added c
+  2: [5841d7cf9893] added d
   q: quit the prompt
-  enter the index of the revision you want to select: 1
+  enter the index of the revision you want to select: 2
   move:[4] merge commit
   atop:[8] added d
   move:[10] merge commit
--- a/tests/test-evolve-orphan-split.t	Thu Mar 07 01:57:43 2019 +0530
+++ b/tests/test-evolve-orphan-split.t	Thu Mar 07 10:51:48 2019 +0100
@@ -182,27 +182,27 @@
       () draft
 
   $ hg evolve --dry-run <<EOF
-  > 0
+  > 1
   > EOF
   ancestor 'd48a30875f01' split over multiple topological branches.
   choose an evolve destination:
-  0: [f2632392aefe] added a b c
-  1: [7f87764e5b64] added a b c
+  1: [f2632392aefe] added a b c
+  2: [7f87764e5b64] added a b c
   q: quit the prompt
-  enter the index of the revision you want to select: 0
+  enter the index of the revision you want to select: 1
   move:[7] added d
   atop:[8] added a b c
   hg rebase -r d48a30875f01 -d f2632392aefe
 
   $ hg evolve --dry-run <<EOF
-  > 1
+  > 2
   > EOF
   ancestor 'd48a30875f01' split over multiple topological branches.
   choose an evolve destination:
-  0: [f2632392aefe] added a b c
-  1: [7f87764e5b64] added a b c
+  1: [f2632392aefe] added a b c
+  2: [7f87764e5b64] added a b c
   q: quit the prompt
-  enter the index of the revision you want to select: 1
+  enter the index of the revision you want to select: 2
   move:[7] added d
   atop:[10] added a b c
   hg rebase -r d48a30875f01 -d 7f87764e5b64
@@ -215,8 +215,8 @@
   > EOF
   ancestor 'd48a30875f01' split over multiple topological branches.
   choose an evolve destination:
-  0: [f2632392aefe] added a b c
-  1: [7f87764e5b64] added a b c
+  1: [f2632392aefe] added a b c
+  2: [7f87764e5b64] added a b c
   q: quit the prompt
   enter the index of the revision you want to select: foo
   invalid value 'foo' entered for index
@@ -227,8 +227,8 @@
   > EOF
   ancestor 'd48a30875f01' split over multiple topological branches.
   choose an evolve destination:
-  0: [f2632392aefe] added a b c
-  1: [7f87764e5b64] added a b c
+  1: [f2632392aefe] added a b c
+  2: [7f87764e5b64] added a b c
   q: quit the prompt
   enter the index of the revision you want to select: 4
   invalid value '4' entered for index
@@ -239,8 +239,8 @@
   > EOF
   ancestor 'd48a30875f01' split over multiple topological branches.
   choose an evolve destination:
-  0: [f2632392aefe] added a b c
-  1: [7f87764e5b64] added a b c
+  1: [f2632392aefe] added a b c
+  2: [7f87764e5b64] added a b c
   q: quit the prompt
   enter the index of the revision you want to select: -1
   invalid value '-1' entered for index
@@ -251,8 +251,8 @@
   > EOF
   ancestor 'd48a30875f01' split over multiple topological branches.
   choose an evolve destination:
-  0: [f2632392aefe] added a b c
-  1: [7f87764e5b64] added a b c
+  1: [f2632392aefe] added a b c
+  2: [7f87764e5b64] added a b c
   q: quit the prompt
   enter the index of the revision you want to select: q
   could not solve instability, ambiguous destination: parent split across two branches
@@ -264,10 +264,10 @@
   > EOF
   ancestor 'd48a30875f01' split over multiple topological branches.
   choose an evolve destination:
-  0: [f2632392aefe] added a b c
-  1: [7f87764e5b64] added a b c
+  1: [f2632392aefe] added a b c
+  2: [7f87764e5b64] added a b c
   q: quit the prompt
   enter the index of the revision you want to select: 1
   move:[7] added d
-  atop:[10] added a b c
-  working directory is now at 1c6caa7c902a
+  atop:[8] added a b c
+  working directory is now at 71e4d45a7aaa
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-evolve-public-content-divergent.t	Thu Mar 07 10:51:48 2019 +0100
@@ -0,0 +1,1414 @@
+Test for handling of content divergence with public cset using `hg evolve`
+==========================================================================
+
+Setup
+=====
+  $ cat >> $HGRCPATH <<EOF
+  > [alias]
+  > glog = log -GT "{rev}:{node|short} {desc|firstline}\n {phase} {troubles}\n\n"
+  > [phases]
+  > publish = False
+  > [extensions]
+  > rebase =
+  > EOF
+  $ echo "evolve=$(echo $(dirname $TESTDIR))/hgext3rd/evolve/" >> $HGRCPATH
+
+Testing the case when both divergent cset are on the same parent and no-conflict in merging:
+-------------------------------------------------------------------------------------
+
+Prepare the repository:
+
+  $ hg init pubdiv
+  $ cd pubdiv
+  $ for ch in a b; do
+  >   echo $ch > $ch;
+  >   hg ci -Aqm "added "$ch;
+  > done;
+  $ hg glog
+  @  1:5f6d8a4bf34a added b
+  |   draft
+  |
+  o  0:9092f1db7931 added a
+      draft
+  
+
+Make an amend and change phase to public:
+
+  $ sed -i "1 i I am first" b
+  $ hg amend
+  $ hg phase --public
+
+Amend again to create a cset divergent to public one:
+
+  $ hg up 1 --hidden -q
+  updated to hidden changeset 5f6d8a4bf34a
+  (hidden revision '5f6d8a4bf34a' was rewritten as: 44f360db368f)
+  working directory parent is obsolete! (5f6d8a4bf34a)
+
+  $ echo "I am second" >> b
+  $ hg ci --amend -m "updated b"
+  1 new content-divergent changesets
+
+  $ hg glog
+  @  3:dcdaf152280a updated b
+  |   draft content-divergent
+  |
+  | o  2:44f360db368f added b
+  |/    public
+  |
+  o  0:9092f1db7931 added a
+      public
+  
+
+Lets resolve the public content-divergence:
+
+  $ hg evolve --content-divergent
+  merge:[2] added b
+  with: [3] updated b
+  base: [1] added b
+  updating to "local" side of the conflict: 44f360db368f
+  merging "other" content-divergent changeset 'dcdaf152280a'
+  merging b
+  0 files updated, 1 files merged, 0 files removed, 0 files unresolved
+  computing new diff
+  committed as c1aa9cfb6cf8
+  working directory is now at c1aa9cfb6cf8
+
+Following graph log shows that it correctly merged the two divergent csets:
+
+  $ hg glog -p
+  @  5:c1aa9cfb6cf8 phase-divergent update to 44f360db368f:
+  |   draft
+  |
+  |  diff -r 44f360db368f -r c1aa9cfb6cf8 b
+  |  --- a/b	Thu Jan 01 00:00:00 1970 +0000
+  |  +++ b/b	Thu Jan 01 00:00:00 1970 +0000
+  |  @@ -1,2 +1,3 @@
+  |   I am first
+  |   b
+  |  +I am second
+  |
+  o  2:44f360db368f added b
+  |   public
+  |
+  |  diff -r 9092f1db7931 -r 44f360db368f b
+  |  --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+  |  +++ b/b	Thu Jan 01 00:00:00 1970 +0000
+  |  @@ -0,0 +1,2 @@
+  |  +I am first
+  |  +b
+  |
+  o  0:9092f1db7931 added a
+      public
+  
+     diff -r 000000000000 -r 9092f1db7931 a
+     --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+     +++ b/a	Thu Jan 01 00:00:00 1970 +0000
+     @@ -0,0 +1,1 @@
+     +a
+  
+  $ hg evolve -l
+
+  $ cd ..
+
+Testing the case when both divergent cset has same parent and has conflict in merging:
+------------------------------------------------------------------------------
+
+Prepare the repository:
+
+  $ hg init pubdiv1
+  $ cd pubdiv1
+  $ for ch in a b; do
+  >   echo $ch > $ch;
+  >   hg ci -Aqm "added "$ch;
+  > done;
+  $ hg glog
+  @  1:5f6d8a4bf34a added b
+  |   draft
+  |
+  o  0:9092f1db7931 added a
+      draft
+  
+
+Make an amend and change phase to public:
+
+  $ echo "I am foo" > b
+  $ hg amend
+  $ hg phase --public
+
+Amend again to create a cset divergent to public one:
+
+  $ hg up 1 --hidden -q
+  updated to hidden changeset 5f6d8a4bf34a
+  (hidden revision '5f6d8a4bf34a' was rewritten as: 580f2d01e52c)
+  working directory parent is obsolete! (5f6d8a4bf34a)
+
+  $ echo "I am bar" > b
+  $ hg ci --amend -m "updated b"
+  1 new content-divergent changesets
+
+  $ hg glog
+  @  3:0e805383168e updated b
+  |   draft content-divergent
+  |
+  | o  2:580f2d01e52c added b
+  |/    public
+  |
+  o  0:9092f1db7931 added a
+      public
+  
+
+Lets resolve the divergence:
+
+  $ hg evolve --content-divergent
+  merge:[2] added b
+  with: [3] updated b
+  base: [1] added b
+  updating to "local" side of the conflict: 580f2d01e52c
+  merging "other" content-divergent changeset '0e805383168e'
+  merging b
+  warning: conflicts while merging b! (edit, then use 'hg resolve --mark')
+  0 files updated, 0 files merged, 0 files removed, 1 files unresolved
+  fix conflicts and see `hg help evolve.interrupted`
+  [1]
+
+  $ echo "I am foobar" > b
+  $ hg resolve -m --tool union
+  (no more unresolved files)
+  continue: hg evolve --continue
+  $ hg evolve --continue
+  computing new diff
+  committed as 1a739394e9d4
+  working directory is now at 1a739394e9d4
+
+  $ hg glog
+  @  5:1a739394e9d4 phase-divergent update to 580f2d01e52c:
+  |   draft
+  |
+  o  2:580f2d01e52c added b
+  |   public
+  |
+  o  0:9092f1db7931 added a
+      public
+  
+Testing the case when divergence is not created by actual diff change, but because of rebasing:
+------------------------------------------------------------------------------------------------
+
+Prepare the repo:
+
+  $ cd ..
+  $ hg init rebasediv
+  $ cd rebasediv
+  $ for ch in a b c; do
+  >   echo $ch > $ch;
+  >   hg ci -Am "added "$ch;
+  > done;
+  adding a
+  adding b
+  adding c
+
+  $ hg glog
+  @  2:155349b645be added c
+  |   draft
+  |
+  o  1:5f6d8a4bf34a added b
+  |   draft
+  |
+  o  0:9092f1db7931 added a
+      draft
+  
+
+On server side: a new cset is added based on rev 1 and rev 2 is rebased on newly added cset:
+
+  $ hg up .^ -q
+  $ echo d > d
+  $ hg ci -Am "added d"
+  adding d
+  created new head
+
+  $ hg rebase -r 2 -d .
+  rebasing 2:155349b645be "added c"
+
+  $ hg glog
+  o  4:c0d7ee6604ea added c
+  |   draft
+  |
+  @  3:c9241b0f2d5b added d
+  |   draft
+  |
+  o  1:5f6d8a4bf34a added b
+  |   draft
+  |
+  o  0:9092f1db7931 added a
+      draft
+  
+
+On user side: user has not pulled yet and amended the rev 2 which created the divergence after pull:
+  $ hg up 2 --hidden -q
+  updated to hidden changeset 155349b645be
+  (hidden revision '155349b645be' was rewritten as: c0d7ee6604ea)
+  working directory parent is obsolete! (155349b645be)
+
+  $ echo cc >> c
+  $ hg ci --amend -m "updated c"
+  2 new content-divergent changesets
+
+Lets change the phase to --public of branch which is pulled from server:
+  $ hg phase --public -r 4
+  $ hg glog -p
+  @  5:f5f9b4fc8b77 updated c
+  |   draft content-divergent
+  |
+  |  diff -r 5f6d8a4bf34a -r f5f9b4fc8b77 c
+  |  --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+  |  +++ b/c	Thu Jan 01 00:00:00 1970 +0000
+  |  @@ -0,0 +1,2 @@
+  |  +c
+  |  +cc
+  |
+  | o  4:c0d7ee6604ea added c
+  | |   public
+  | |
+  | |  diff -r c9241b0f2d5b -r c0d7ee6604ea c
+  | |  --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+  | |  +++ b/c	Thu Jan 01 00:00:00 1970 +0000
+  | |  @@ -0,0 +1,1 @@
+  | |  +c
+  | |
+  | o  3:c9241b0f2d5b added d
+  |/    public
+  |
+  |    diff -r 5f6d8a4bf34a -r c9241b0f2d5b d
+  |    --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+  |    +++ b/d	Thu Jan 01 00:00:00 1970 +0000
+  |    @@ -0,0 +1,1 @@
+  |    +d
+  |
+  o  1:5f6d8a4bf34a added b
+  |   public
+  |
+  |  diff -r 9092f1db7931 -r 5f6d8a4bf34a b
+  |  --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+  |  +++ b/b	Thu Jan 01 00:00:00 1970 +0000
+  |  @@ -0,0 +1,1 @@
+  |  +b
+  |
+  o  0:9092f1db7931 added a
+      public
+  
+     diff -r 000000000000 -r 9092f1db7931 a
+     --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+     +++ b/a	Thu Jan 01 00:00:00 1970 +0000
+     @@ -0,0 +1,1 @@
+     +a
+  
+
+Evolve:
+  $ hg evolve --content-divergent
+  merge:[4] added c
+  with: [5] updated c
+  base: [2] added c
+  rebasing "other" content-divergent changeset f5f9b4fc8b77 on c9241b0f2d5b
+  updating to "local" side of the conflict: c0d7ee6604ea
+  merging "other" content-divergent changeset 'c3d442d80993'
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  computing new diff
+  committed as 3b336cbee992
+  working directory is now at 3b336cbee992
+
+  $ hg glog -p
+  @  8:3b336cbee992 phase-divergent update to c0d7ee6604ea:
+  |   draft
+  |
+  |  diff -r c0d7ee6604ea -r 3b336cbee992 c
+  |  --- a/c	Thu Jan 01 00:00:00 1970 +0000
+  |  +++ b/c	Thu Jan 01 00:00:00 1970 +0000
+  |  @@ -1,1 +1,2 @@
+  |   c
+  |  +cc
+  |
+  o  4:c0d7ee6604ea added c
+  |   public
+  |
+  |  diff -r c9241b0f2d5b -r c0d7ee6604ea c
+  |  --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+  |  +++ b/c	Thu Jan 01 00:00:00 1970 +0000
+  |  @@ -0,0 +1,1 @@
+  |  +c
+  |
+  o  3:c9241b0f2d5b added d
+  |   public
+  |
+  |  diff -r 5f6d8a4bf34a -r c9241b0f2d5b d
+  |  --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+  |  +++ b/d	Thu Jan 01 00:00:00 1970 +0000
+  |  @@ -0,0 +1,1 @@
+  |  +d
+  |
+  o  1:5f6d8a4bf34a added b
+  |   public
+  |
+  |  diff -r 9092f1db7931 -r 5f6d8a4bf34a b
+  |  --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+  |  +++ b/b	Thu Jan 01 00:00:00 1970 +0000
+  |  @@ -0,0 +1,1 @@
+  |  +b
+  |
+  o  0:9092f1db7931 added a
+      public
+  
+     diff -r 000000000000 -r 9092f1db7931 a
+     --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+     +++ b/a	Thu Jan 01 00:00:00 1970 +0000
+     @@ -0,0 +1,1 @@
+     +a
+  
+Check that we don't have any troubled cset now:
+  $ hg evolve -l
+  $ cd ..
+
+Testing the case when csets are on different parent and no conflict in relocation and merging:
+----------------------------------------------------------------------------------------------
+
+  $ hg init pubdiv2
+  $ cd pubdiv2
+  $ for ch in a b c d; do
+  >   echo $ch > $ch;
+  >   hg ci -Aqm "added "$ch;
+  > done;
+
+  $ hg up .^
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ echo dd > d
+  $ hg add d
+  $ hg ci -m "added d"
+  created new head
+
+  $ hg up 1
+  0 files updated, 0 files merged, 2 files removed, 0 files unresolved
+  $ echo dd > d
+  $ echo e > e
+  $ hg add d e
+  $ hg ci -m "added d e"
+  created new head
+
+  $ hg glog
+  @  5:4291d72ee19a added d e
+  |   draft
+  |
+  | o  4:93cd84bbdaca added d
+  | |   draft
+  | |
+  | | o  3:9150fe93bec6 added d
+  | |/    draft
+  | |
+  | o  2:155349b645be added c
+  |/    draft
+  |
+  o  1:5f6d8a4bf34a added b
+  |   draft
+  |
+  o  0:9092f1db7931 added a
+      draft
+  
+
+  $ hg prune 3 -s 5
+  1 changesets pruned
+  $ hg prune 3 -s 4 --hidden
+  1 changesets pruned
+  2 new content-divergent changesets
+
+Change phase to public for one head:
+  $ hg phase -r 4 --public
+
+  $ hg glog
+  @  5:4291d72ee19a added d e
+  |   draft content-divergent
+  |
+  | o  4:93cd84bbdaca added d
+  | |   public
+  | |
+  | o  2:155349b645be added c
+  |/    public
+  |
+  o  1:5f6d8a4bf34a added b
+  |   public
+  |
+  o  0:9092f1db7931 added a
+      public
+  
+
+  $ hg evolve --content-divergent --any
+  merge:[4] added d
+  with: [5] added d e
+  base: [3] added d
+  rebasing "other" content-divergent changeset 4291d72ee19a on 155349b645be
+  updating to "local" side of the conflict: 93cd84bbdaca
+  merging "other" content-divergent changeset 'f88581407163'
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  computing new diff
+  committed as 4cbe48a0c3d9
+  working directory is now at 4cbe48a0c3d9
+
+  $ hg glog -l 1
+  @  8:4cbe48a0c3d9 phase-divergent update to 93cd84bbdaca:
+  |   draft
+  ~
+
+  $ hg evolve -l
+  $ cd ..
+
+Testing the case when csets are on different parent and conflict in relocation but not in merging:
+--------------------------------------------------------------------------------------------------
+
+  $ hg init pubdiv3
+  $ cd pubdiv3
+  $ for ch in a b c d; do
+  >   echo $ch > $ch;
+  >   hg ci -Aqm "added "$ch;
+  > done;
+
+  $ hg up .^^
+  0 files updated, 0 files merged, 2 files removed, 0 files unresolved
+  $ echo cfoo > c
+  $ echo e > e
+  $ hg add c e
+  $ hg ci -m "added c e"
+  created new head
+
+  $ hg up 2
+  1 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ echo dd > d
+  $ hg add d
+  $ hg ci -m "added d"
+  created new head
+
+  $ hg glog
+  @  5:93cd84bbdaca added d
+  |   draft
+  |
+  | o  4:e568fd1029bb added c e
+  | |   draft
+  | |
+  +---o  3:9150fe93bec6 added d
+  | |     draft
+  | |
+  o |  2:155349b645be added c
+  |/    draft
+  |
+  o  1:5f6d8a4bf34a added b
+  |   draft
+  |
+  o  0:9092f1db7931 added a
+      draft
+  
+  $ hg prune 3 -s 5
+  1 changesets pruned
+  $ hg prune 3 -s 4 --hidden
+  1 changesets pruned
+  2 new content-divergent changesets
+
+Change phase to public for one head:
+  $ hg phase --public -r 5
+
+  $ hg glog
+  @  5:93cd84bbdaca added d
+  |   public
+  |
+  | *  4:e568fd1029bb added c e
+  | |   draft content-divergent
+  | |
+  o |  2:155349b645be added c
+  |/    public
+  |
+  o  1:5f6d8a4bf34a added b
+  |   public
+  |
+  o  0:9092f1db7931 added a
+      public
+  
+  $ hg evolve --content-divergent --any
+  merge:[5] added d
+  with: [4] added c e
+  base: [3] added d
+  rebasing "other" content-divergent changeset e568fd1029bb on 155349b645be
+  merging c
+  warning: conflicts while merging c! (edit, then use 'hg resolve --mark')
+  fix conflicts and see `hg help evolve.interrupted`
+  [1]
+
+  $ hg diff
+  diff -r 155349b645be c
+  --- a/c	Thu Jan 01 00:00:00 1970 +0000
+  +++ b/c	Thu Jan 01 00:00:00 1970 +0000
+  @@ -1,1 +1,5 @@
+  +<<<<<<< destination: 155349b645be - test: added c
+   c
+  +=======
+  +cfoo
+  +>>>>>>> evolving:    e568fd1029bb - test: added c e
+  diff -r 155349b645be e
+  --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+  +++ b/e	Thu Jan 01 00:00:00 1970 +0000
+  @@ -0,0 +1,1 @@
+  +e
+
+  $ echo c > c
+  $ hg res -m
+  (no more unresolved files)
+  continue: hg evolve --continue
+
+  $ hg evolve --continue
+  evolving 4:e568fd1029bb "added c e"
+  updating to "local" side of the conflict: 93cd84bbdaca
+  merging "other" content-divergent changeset '2af3359250d3'
+  1 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  computing new diff
+  committed as 06e4564a3897
+  working directory is now at 06e4564a3897
+
+  $ hg evolve -l
+  $ cd ..
+
+Testing the case when merging leads to conflicts but relocation won't:
+---------------------------------------------------------------------
+
+  $ hg init pubdiv3.5
+  $ cd pubdiv3.5
+  $ for ch in a b c d; do
+  >   echo $ch > $ch;
+  >   hg ci -Aqm "added "$ch;
+  > done;
+
+  $ hg up .^^
+  0 files updated, 0 files merged, 2 files removed, 0 files unresolved
+  $ echo dconflict > d
+  $ hg add d
+  $ hg ci -m "added d"
+  created new head
+
+  $ hg up 2
+  1 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ echo dd > d
+  $ hg add d
+  $ hg ci -m "added d"
+  created new head
+
+  $ hg glog
+  @  5:93cd84bbdaca added d
+  |   draft
+  |
+  | o  4:9411ad1fe615 added d
+  | |   draft
+  | |
+  +---o  3:9150fe93bec6 added d
+  | |     draft
+  | |
+  o |  2:155349b645be added c
+  |/    draft
+  |
+  o  1:5f6d8a4bf34a added b
+  |   draft
+  |
+  o  0:9092f1db7931 added a
+      draft
+  
+  $ hg prune 3 -s 5
+  1 changesets pruned
+  $ hg prune 3 -s 4 --hidden
+  1 changesets pruned
+  2 new content-divergent changesets
+
+Change phase to public for one head:
+  $ hg phase --public -r 5
+
+  $ hg glog
+  @  5:93cd84bbdaca added d
+  |   public
+  |
+  | *  4:9411ad1fe615 added d
+  | |   draft content-divergent
+  | |
+  o |  2:155349b645be added c
+  |/    public
+  |
+  o  1:5f6d8a4bf34a added b
+  |   public
+  |
+  o  0:9092f1db7931 added a
+      public
+  
+  $ hg evolve --content-divergent --any
+  merge:[5] added d
+  with: [4] added d
+  base: [3] added d
+  rebasing "other" content-divergent changeset 9411ad1fe615 on 155349b645be
+  updating to "local" side of the conflict: 93cd84bbdaca
+  merging "other" content-divergent changeset 'b5c690cdf1d5'
+  merging d
+  warning: conflicts while merging d! (edit, then use 'hg resolve --mark')
+  0 files updated, 0 files merged, 0 files removed, 1 files unresolved
+  fix conflicts and see `hg help evolve.interrupted`
+  [1]
+
+  $ echo d > d
+  $ hg res -m
+  (no more unresolved files)
+  continue: hg evolve --continue
+
+  $ hg evolve --continue
+  computing new diff
+  committed as 2a0f44767904
+  working directory is now at 2a0f44767904
+
+  $ hg evolve -l
+  $ cd ..
+
+Testing the case when relocation and merging both leads to conflicts:
+--------------------------------------------------------------------
+
+  $ hg init pubdiv4
+  $ cd pubdiv4
+  $ for ch in a b c d; do
+  >   echo $ch > $ch;
+  >   hg ci -Aqm "added "$ch;
+  > done;
+
+  $ hg up .^^
+  0 files updated, 0 files merged, 2 files removed, 0 files unresolved
+  $ echo cfoo > c
+  $ echo e > e
+  $ echo dconflict > d
+  $ hg add c e d
+  $ hg ci -m "added c e"
+  created new head
+
+  $ hg up 2
+  1 files updated, 0 files merged, 2 files removed, 0 files unresolved
+  $ echo dd > d
+  $ hg add d
+  $ hg ci -m "added d"
+  created new head
+
+  $ hg glog
+  @  5:93cd84bbdaca added d
+  |   draft
+  |
+  | o  4:3c17c7afaf6e added c e
+  | |   draft
+  | |
+  +---o  3:9150fe93bec6 added d
+  | |     draft
+  | |
+  o |  2:155349b645be added c
+  |/    draft
+  |
+  o  1:5f6d8a4bf34a added b
+  |   draft
+  |
+  o  0:9092f1db7931 added a
+      draft
+  
+  $ hg prune 3 -s 5
+  1 changesets pruned
+  $ hg prune 3 -s 4 --hidden
+  1 changesets pruned
+  2 new content-divergent changesets
+
+Change phase to public for one head:
+  $ hg phase --public -r 5
+
+  $ hg glog
+  @  5:93cd84bbdaca added d
+  |   public
+  |
+  | *  4:3c17c7afaf6e added c e
+  | |   draft content-divergent
+  | |
+  o |  2:155349b645be added c
+  |/    public
+  |
+  o  1:5f6d8a4bf34a added b
+  |   public
+  |
+  o  0:9092f1db7931 added a
+      public
+  
+  $ hg evolve --content-divergent --any
+  merge:[5] added d
+  with: [4] added c e
+  base: [3] added d
+  rebasing "other" content-divergent changeset 3c17c7afaf6e on 155349b645be
+  merging c
+  warning: conflicts while merging c! (edit, then use 'hg resolve --mark')
+  fix conflicts and see `hg help evolve.interrupted`
+  [1]
+
+  $ hg diff
+  diff -r 155349b645be c
+  --- a/c	Thu Jan 01 00:00:00 1970 +0000
+  +++ b/c	Thu Jan 01 00:00:00 1970 +0000
+  @@ -1,1 +1,5 @@
+  +<<<<<<< destination: 155349b645be - test: added c
+   c
+  +=======
+  +cfoo
+  +>>>>>>> evolving:    3c17c7afaf6e - test: added c e
+  diff -r 155349b645be d
+  --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+  +++ b/d	Thu Jan 01 00:00:00 1970 +0000
+  @@ -0,0 +1,1 @@
+  +dconflict
+  diff -r 155349b645be e
+  --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+  +++ b/e	Thu Jan 01 00:00:00 1970 +0000
+  @@ -0,0 +1,1 @@
+  +e
+
+  $ echo cfoo > c
+  $ hg res -m
+  (no more unresolved files)
+  continue: hg evolve --continue
+
+  $ hg evolve --continue
+  evolving 4:3c17c7afaf6e "added c e"
+  updating to "local" side of the conflict: 93cd84bbdaca
+  merging "other" content-divergent changeset 'c4ce3d34e784'
+  merging d
+  warning: conflicts while merging d! (edit, then use 'hg resolve --mark')
+  2 files updated, 0 files merged, 0 files removed, 1 files unresolved
+  fix conflicts and see `hg help evolve.interrupted`
+  [1]
+
+  $ echo d > d
+  $ hg res -m
+  (no more unresolved files)
+  continue: hg evolve --continue
+
+  $ hg evolve --continue
+  computing new diff
+  committed as b9082a9e66ce
+  working directory is now at b9082a9e66ce
+
+  $ hg evolve -l
+  $ cd ..
+
+
+Testing the case when "merging results in same as public cset" where:
+both the csets are on same parent and no conflict in merging.
+---------------------------------------------------------------------
+
+Prepare the repo:
+
+  $ hg init pubdiv5
+  $ cd pubdiv5
+  $ for ch in a b c; do
+  >   echo $ch > $ch;
+  >   hg ci -Am "added "$ch;
+  > done;
+  adding a
+  adding b
+  adding c
+
+  $ hg up .^
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ echo ch > ch
+  $ hg add ch
+  $ hg ci -m "added ch"
+  created new head
+
+  $ hg up .^
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ echo ch > ch
+  $ hg add ch
+  $ hg ci -m "added c"
+  created new head
+
+  $ hg glog
+  @  4:f7c1071f1e7c added c
+  |   draft
+  |
+  | o  3:90522bccf499 added ch
+  |/    draft
+  |
+  | o  2:155349b645be added c
+  |/    draft
+  |
+  o  1:5f6d8a4bf34a added b
+  |   draft
+  |
+  o  0:9092f1db7931 added a
+      draft
+  
+
+  $ hg prune 2 -s 3
+  1 changesets pruned
+  $ hg prune 2 -s 4 --hidden
+  1 changesets pruned
+  2 new content-divergent changesets
+  $ hg phase --public -r 4
+
+  $ hg glog
+  @  4:f7c1071f1e7c added c
+  |   public
+  |
+  | *  3:90522bccf499 added ch
+  |/    draft content-divergent
+  |
+  o  1:5f6d8a4bf34a added b
+  |   public
+  |
+  o  0:9092f1db7931 added a
+      public
+  
+  $ hg evolve --content-divergent --any
+  merge:[4] added c
+  with: [3] added ch
+  base: [2] added c
+  merging "other" content-divergent changeset '90522bccf499'
+  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+
+  $ hg evolve -l
+
+  $ hg par
+  changeset:   4:f7c1071f1e7c
+  tag:         tip
+  parent:      1:5f6d8a4bf34a
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     added c
+  
+
+Testing the case when "merging results in same as public cset" where:
+both the csets are on different parent and no conflict in merging and relocation.
+---------------------------------------------------------------------------------
+
+Prepare the repo:
+
+  $ cd ..
+  $ hg init pubdiv6
+  $ cd pubdiv6
+  $ for ch in a b c d; do
+  >   echo $ch > $ch;
+  >   hg ci -Am "added "$ch;
+  > done;
+  adding a
+  adding b
+  adding c
+  adding d
+
+  $ hg up 1
+  0 files updated, 0 files merged, 2 files removed, 0 files unresolved
+  $ echo dh > dh
+  $ hg add dh
+  $ hg ci -m "added dh"
+  created new head
+
+  $ hg up 2
+  1 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ echo dh > dh
+  $ hg add dh
+  $ hg ci -m "added d"
+  created new head
+
+  $ hg glog
+  @  5:e800202333a4 added d
+  |   draft
+  |
+  | o  4:5acd58ef5066 added dh
+  | |   draft
+  | |
+  +---o  3:9150fe93bec6 added d
+  | |     draft
+  | |
+  o |  2:155349b645be added c
+  |/    draft
+  |
+  o  1:5f6d8a4bf34a added b
+  |   draft
+  |
+  o  0:9092f1db7931 added a
+      draft
+  
+
+  $ hg prune 3 -s 4
+  1 changesets pruned
+  $ hg prune 3 -s 5 --hidden
+  1 changesets pruned
+  2 new content-divergent changesets
+  $ hg phase --public -r 5
+
+  $ hg glog
+  @  5:e800202333a4 added d
+  |   public
+  |
+  | *  4:5acd58ef5066 added dh
+  | |   draft content-divergent
+  | |
+  o |  2:155349b645be added c
+  |/    public
+  |
+  o  1:5f6d8a4bf34a added b
+  |   public
+  |
+  o  0:9092f1db7931 added a
+      public
+  
+  $ hg evolve --content-divergent --any
+  merge:[5] added d
+  with: [4] added dh
+  base: [3] added d
+  rebasing "other" content-divergent changeset 5acd58ef5066 on 155349b645be
+  updating to "local" side of the conflict: e800202333a4
+  merging "other" content-divergent changeset 'ae3429430ef1'
+  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+
+  $ hg evolve -l
+
+  $ hg par
+  changeset:   5:e800202333a4
+  tag:         tip
+  parent:      2:155349b645be
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     added d
+  
+Testing the case when "merging results in same as public cset" where:
+both the csets are on same parent and merging leads to conflict.
+---------------------------------------------------------------------
+
+Prepare the repo:
+
+  $ cd ..
+  $ hg init pubdiv7
+  $ cd pubdiv7
+  $ for ch in a b c; do
+  >   echo $ch > $ch;
+  >   hg ci -Am "added "$ch;
+  > done;
+  adding a
+  adding b
+  adding c
+
+  $ hg up .^
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ echo chconflict > ch
+  $ hg add ch
+  $ hg ci -m "added ch"
+  created new head
+
+  $ hg up .^
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ echo ch > ch
+  $ hg add ch
+  $ hg ci -m "added c"
+  created new head
+
+  $ hg glog
+  @  4:f7c1071f1e7c added c
+  |   draft
+  |
+  | o  3:229da2719b19 added ch
+  |/    draft
+  |
+  | o  2:155349b645be added c
+  |/    draft
+  |
+  o  1:5f6d8a4bf34a added b
+  |   draft
+  |
+  o  0:9092f1db7931 added a
+      draft
+  
+
+  $ hg prune 2 -s 3
+  1 changesets pruned
+  $ hg prune 2 -s 4 --hidden
+  1 changesets pruned
+  2 new content-divergent changesets
+  $ hg phase --public -r 4
+
+  $ hg glog
+  @  4:f7c1071f1e7c added c
+  |   public
+  |
+  | *  3:229da2719b19 added ch
+  |/    draft content-divergent
+  |
+  o  1:5f6d8a4bf34a added b
+  |   public
+  |
+  o  0:9092f1db7931 added a
+      public
+  
+  $ hg evolve --content-divergent --any
+  merge:[4] added c
+  with: [3] added ch
+  base: [2] added c
+  merging "other" content-divergent changeset '229da2719b19'
+  merging ch
+  warning: conflicts while merging ch! (edit, then use 'hg resolve --mark')
+  0 files updated, 0 files merged, 0 files removed, 1 files unresolved
+  fix conflicts and see `hg help evolve.interrupted`
+  [1]
+
+  $ hg diff
+  diff -r f7c1071f1e7c ch
+  --- a/ch	Thu Jan 01 00:00:00 1970 +0000
+  +++ b/ch	Thu Jan 01 00:00:00 1970 +0000
+  @@ -1,1 +1,5 @@
+  +<<<<<<< local: f7c1071f1e7c - test: added c
+   ch
+  +=======
+  +chconflict
+  +>>>>>>> other: 229da2719b19 - test: added ch
+
+  $ echo ch > ch
+  $ hg res -m
+  (no more unresolved files)
+  continue: hg evolve --continue
+
+  $ hg evolve --continue
+  working directory is now at f7c1071f1e7c
+
+  $ hg evolve -l
+
+  $ hg par
+  changeset:   4:f7c1071f1e7c
+  tag:         tip
+  parent:      1:5f6d8a4bf34a
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     added c
+  
+Testing the case when "merging results in same as public cset" where:
+both the csets are on different parent and relocation leads to conflict but merging won't.
+------------------------------------------------------------------------------------------
+Prepare the repo:
+
+  $ cd ..
+  $ hg init pubdiv8
+  $ cd pubdiv8
+  $ for ch in a b c d; do
+  >   echo $ch > $ch;
+  >   hg ci -Am "added "$ch;
+  > done;
+  adding a
+  adding b
+  adding c
+  adding d
+
+  $ hg up 1
+  0 files updated, 0 files merged, 2 files removed, 0 files unresolved
+  $ echo dh > dh
+  $ echo cc > c
+  $ hg add dh c
+  $ hg ci -m "added dh"
+  created new head
+
+  $ hg up 2
+  1 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ echo dh > dh
+  $ hg add dh
+  $ hg ci -m "added d"
+  created new head
+
+  $ hg glog
+  @  5:e800202333a4 added d
+  |   draft
+  |
+  | o  4:f89a8e2f86ac added dh
+  | |   draft
+  | |
+  +---o  3:9150fe93bec6 added d
+  | |     draft
+  | |
+  o |  2:155349b645be added c
+  |/    draft
+  |
+  o  1:5f6d8a4bf34a added b
+  |   draft
+  |
+  o  0:9092f1db7931 added a
+      draft
+  
+
+  $ hg prune 3 -s 4
+  1 changesets pruned
+  $ hg prune 3 -s 5 --hidden
+  1 changesets pruned
+  2 new content-divergent changesets
+  $ hg phase --public -r 5
+
+  $ hg glog
+  @  5:e800202333a4 added d
+  |   public
+  |
+  | *  4:f89a8e2f86ac added dh
+  | |   draft content-divergent
+  | |
+  o |  2:155349b645be added c
+  |/    public
+  |
+  o  1:5f6d8a4bf34a added b
+  |   public
+  |
+  o  0:9092f1db7931 added a
+      public
+  
+  $ hg evolve --content-divergent --any
+  merge:[5] added d
+  with: [4] added dh
+  base: [3] added d
+  rebasing "other" content-divergent changeset f89a8e2f86ac on 155349b645be
+  merging c
+  warning: conflicts while merging c! (edit, then use 'hg resolve --mark')
+  fix conflicts and see `hg help evolve.interrupted`
+  [1]
+
+  $ echo c > c
+  $ hg res -m
+  (no more unresolved files)
+  continue: hg evolve --continue
+
+  $ hg evolve --continue
+  evolving 4:f89a8e2f86ac "added dh"
+  updating to "local" side of the conflict: e800202333a4
+  merging "other" content-divergent changeset 'bc309da55b88'
+  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  working directory is now at e800202333a4
+
+  $ hg evolve -l
+
+  $ hg par
+  changeset:   5:e800202333a4
+  tag:         tip
+  parent:      2:155349b645be
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     added d
+  
+Testing the case when "merging results in same as public cset" where:
+both the csets are on different parent and merging leads to conflict but relocation won't.
+------------------------------------------------------------------------------------------
+Prepare the repo:
+
+  $ cd ..
+  $ hg init pubdiv9
+  $ cd pubdiv9
+  $ for ch in a b c d; do
+  >   echo $ch > $ch;
+  >   hg ci -Am "added "$ch;
+  > done;
+  adding a
+  adding b
+  adding c
+  adding d
+
+  $ hg up 1
+  0 files updated, 0 files merged, 2 files removed, 0 files unresolved
+  $ echo dhconflict > dh
+  $ hg add dh
+  $ hg ci -m "added dh"
+  created new head
+
+  $ hg up 2
+  1 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ echo dh > dh
+  $ hg add dh
+  $ hg ci -m "added d"
+  created new head
+
+  $ hg glog
+  @  5:e800202333a4 added d
+  |   draft
+  |
+  | o  4:db0b7bba0aae added dh
+  | |   draft
+  | |
+  +---o  3:9150fe93bec6 added d
+  | |     draft
+  | |
+  o |  2:155349b645be added c
+  |/    draft
+  |
+  o  1:5f6d8a4bf34a added b
+  |   draft
+  |
+  o  0:9092f1db7931 added a
+      draft
+  
+
+  $ hg prune 3 -s 4
+  1 changesets pruned
+  $ hg prune 3 -s 5 --hidden
+  1 changesets pruned
+  2 new content-divergent changesets
+  $ hg phase --public -r 5
+
+  $ hg glog
+  @  5:e800202333a4 added d
+  |   public
+  |
+  | *  4:db0b7bba0aae added dh
+  | |   draft content-divergent
+  | |
+  o |  2:155349b645be added c
+  |/    public
+  |
+  o  1:5f6d8a4bf34a added b
+  |   public
+  |
+  o  0:9092f1db7931 added a
+      public
+  
+  $ hg evolve --content-divergent --any
+  merge:[5] added d
+  with: [4] added dh
+  base: [3] added d
+  rebasing "other" content-divergent changeset db0b7bba0aae on 155349b645be
+  updating to "local" side of the conflict: e800202333a4
+  merging "other" content-divergent changeset 'a5bbf2042450'
+  merging dh
+  warning: conflicts while merging dh! (edit, then use 'hg resolve --mark')
+  0 files updated, 0 files merged, 0 files removed, 1 files unresolved
+  fix conflicts and see `hg help evolve.interrupted`
+  [1]
+
+  $ echo dh > dh
+  $ hg res -m
+  (no more unresolved files)
+  continue: hg evolve --continue
+
+  $ hg evolve --continue
+  working directory is now at e800202333a4
+
+  $ hg evolve -l
+
+  $ hg par
+  changeset:   5:e800202333a4
+  tag:         tip
+  parent:      2:155349b645be
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     added d
+  
+
+Testing the case when "merging results in same as public cset" where:
+both the csets are on different parent and relocation and merging both leads to conflict:
+-----------------------------------------------------------------------------------------
+Prepare the repo:
+
+  $ cd ..
+  $ hg init pubdiv10
+  $ cd pubdiv10
+  $ for ch in a b c d; do
+  >   echo $ch > $ch;
+  >   hg ci -Am "added "$ch;
+  > done;
+  adding a
+  adding b
+  adding c
+  adding d
+
+  $ hg up 1
+  0 files updated, 0 files merged, 2 files removed, 0 files unresolved
+  $ echo dhconflict > dh
+  $ echo cc > c
+  $ hg add dh c
+  $ hg ci -m "added dh"
+  created new head
+
+  $ hg up 2
+  1 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ echo dh > dh
+  $ hg add dh
+  $ hg ci -m "added d"
+  created new head
+
+  $ hg glog
+  @  5:e800202333a4 added d
+  |   draft
+  |
+  | o  4:67b19bbd770f added dh
+  | |   draft
+  | |
+  +---o  3:9150fe93bec6 added d
+  | |     draft
+  | |
+  o |  2:155349b645be added c
+  |/    draft
+  |
+  o  1:5f6d8a4bf34a added b
+  |   draft
+  |
+  o  0:9092f1db7931 added a
+      draft
+  
+
+  $ hg prune 3 -s 4
+  1 changesets pruned
+  $ hg prune 3 -s 5 --hidden
+  1 changesets pruned
+  2 new content-divergent changesets
+  $ hg phase --public -r 5
+
+  $ hg glog
+  @  5:e800202333a4 added d
+  |   public
+  |
+  | *  4:67b19bbd770f added dh
+  | |   draft content-divergent
+  | |
+  o |  2:155349b645be added c
+  |/    public
+  |
+  o  1:5f6d8a4bf34a added b
+  |   public
+  |
+  o  0:9092f1db7931 added a
+      public
+  
+  $ hg evolve --content-divergent --any
+  merge:[5] added d
+  with: [4] added dh
+  base: [3] added d
+  rebasing "other" content-divergent changeset 67b19bbd770f on 155349b645be
+  merging c
+  warning: conflicts while merging c! (edit, then use 'hg resolve --mark')
+  fix conflicts and see `hg help evolve.interrupted`
+  [1]
+
+  $ echo c > c
+  $ hg res -m
+  (no more unresolved files)
+  continue: hg evolve --continue
+
+  $ hg evolve --continue
+  evolving 4:67b19bbd770f "added dh"
+  updating to "local" side of the conflict: e800202333a4
+  merging "other" content-divergent changeset '09054d1f3c97'
+  merging dh
+  warning: conflicts while merging dh! (edit, then use 'hg resolve --mark')
+  0 files updated, 0 files merged, 0 files removed, 1 files unresolved
+  fix conflicts and see `hg help evolve.interrupted`
+  [1]
+
+  $ echo dh > dh
+  $ hg res -m
+  (no more unresolved files)
+  continue: hg evolve --continue
+
+  $ hg evolve --continue
+  working directory is now at e800202333a4
+
+  $ hg evolve -l
+
+  $ hg par
+  changeset:   5:e800202333a4
+  tag:         tip
+  parent:      2:155349b645be
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     added d
+  
--- a/tests/test-grab.t	Thu Mar 07 01:57:43 2019 +0530
+++ b/tests/test-grab.t	Thu Mar 07 10:51:48 2019 +0100
@@ -24,9 +24,10 @@
   
   options:
   
-   -r --rev REV  revision to pick
-   -c --continue continue interrupted pick
-   -a --abort    abort interrupted pick
+   -r --rev REV   revision to pick
+   -c --continue  continue interrupted pick
+   -a --abort     abort interrupted pick
+   -t --tool TOOL specify merge tool
   
   (some details hidden, use --verbose to show complete help)
 
--- a/tests/test-prev-next.t	Thu Mar 07 01:57:43 2019 +0530
+++ b/tests/test-prev-next.t	Thu Mar 07 10:51:48 2019 +0100
@@ -213,13 +213,13 @@
   0 files updated, 0 files merged, 1 files removed, 0 files unresolved
   [3] added b (2)
   $ hg next <<EOF
-  > 1
+  > 2
   > EOF
   ambiguous next changeset, choose one to update:
-  0: [e3b6d5df389b] added c
-  1: [9df671ccd2c7] added d
+  1: [e3b6d5df389b] added c
+  2: [9df671ccd2c7] added d
   q: quit the prompt
-  enter the index of the revision you want to select: 1
+  enter the index of the revision you want to select: 2
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
   [5] added d
 
@@ -236,13 +236,13 @@
   (2 unstable changesets to be evolved here, do you want --evolve?)
   [1]
   $ hg next --evolve <<EOF
-  > 0
+  > 1
   > EOF
   ambiguous next (unstable) changeset, choose one to evolve and update:
-  0: [e3b6d5df389b] added c
-  1: [9df671ccd2c7] added d
+  1: [e3b6d5df389b] added c
+  2: [9df671ccd2c7] added d
   q: quit the prompt
-  enter the index of the revision you want to select: 0
+  enter the index of the revision you want to select: 1
   move:[4] added c
   atop:[6] added b (3)
   working directory now at 5ce67c2407b0
@@ -284,8 +284,8 @@
   > q
   > EOF
   multiple parents, choose one to update:
-  0: [47ea25be8aea] added d
-  1: [5ce67c2407b0] added c
+  1: [47ea25be8aea] added d
+  2: [5ce67c2407b0] added c
   q: quit the prompt
   enter the index of the revision you want to select: q
   [8] added d
@@ -300,13 +300,13 @@
   [1]
 
   $ hg prev <<EOF
-  > 1
+  > 2
   > EOF
   multiple parents, choose one to update:
-  0: [47ea25be8aea] added d
-  1: [5ce67c2407b0] added c
+  1: [47ea25be8aea] added d
+  2: [5ce67c2407b0] added c
   q: quit the prompt
-  enter the index of the revision you want to select: 1
+  enter the index of the revision you want to select: 2
   0 files updated, 0 files merged, 1 files removed, 0 files unresolved
   [7] added c
 
--- a/tests/test-split.t	Thu Mar 07 01:57:43 2019 +0530
+++ b/tests/test-split.t	Thu Mar 07 10:51:48 2019 +0100
@@ -19,6 +19,8 @@
   > [diff]
   > git = 1
   > unified = 0
+  > [commands]
+  > commit.interactive.unified = 0
   > [ui]
   > interactive = true
   > [extensions]
--- a/tests/test-topic.t	Thu Mar 07 01:57:43 2019 +0530
+++ b/tests/test-topic.t	Thu Mar 07 10:51:48 2019 +0100
@@ -860,6 +860,10 @@
   3: featureA
   $ tlog 'featureA#topic[0]'
   3: featureA
+  $ tlog 'featureA#topic[:]'
+  1: featureA
+  2: featureA
+  3: featureA
 
   $ tlog '2#t[-2]'
   $ tlog '2#t[-1]'
@@ -869,6 +873,10 @@
   $ tlog '2#t[1]'
   3: featureA
   $ tlog '2#t[2]'
+  $ tlog '2#t[-1:1]'
+  1: featureA
+  2: featureA
+  3: featureA
 
 stack subscript relation
 
@@ -898,6 +906,28 @@
 
   $ tlog 'featureA#s[0]'
   0: 
+  $ tlog 'featureA#s[0:0]'
+  0: 
+  $ tlog 'featureA#s[:]'
+  1: featureA
+  2: featureA
+  3: featureA
+  $ tlog 'featureA#s[2:]'
+  2: featureA
+  3: featureA
+  $ tlog 'featureA#s[:2]'
+  1: featureA
+  2: featureA
+  $ tlog 'featureA#s[0:1]'
+  0: 
+  1: featureA
+  $ tlog 'featureA#s[-1:0]'
+  0: 
+  3: featureA
+  $ tlog 'featureA#s[-3:3]'
+  1: featureA
+  2: featureA
+  3: featureA
   $ tlog 'featureA#s[1] and featureA#s[-3]'
   1: featureA
   $ tlog 'featureA#s[2] and featureA#s[-2]'