merge with filtering change (DO NOT USE WITHOUT FILTERING)
authorPierre-Yves David <pierre-yves.david@logilab.fr>
Fri, 04 Jan 2013 12:43:22 +0100
changeset 652 5a929510de9d
parent 651 609faf10d307 (diff)
parent 625 e291e5271694 (current diff)
child 653 116c6f76d24b
merge with filtering change (DO NOT USE WITHOUT FILTERING)
hgext/evolve.py
tests/test-amend.t
tests/test-evolve.t
tests/test-obsolete.t
tests/test-tutorial.t
--- a/.hgtags	Mon Dec 03 00:10:58 2012 +0100
+++ b/.hgtags	Fri Jan 04 12:43:22 2013 +0100
@@ -15,3 +15,4 @@
 c062edbcaf13135d0312fd2039deca74573ff4f0 1.1.0
 22cacfce2a65ab965c6179ae862b148f4abc7d8a 1.1.0
 d43e80504e55db9ad4826e860e50530103a27b0f 2.0.0
+f9d305deeff3dba782e65faf4ef3fd1569995859 2.1.0
--- a/README	Mon Dec 03 00:10:58 2012 +0100
+++ b/README	Fri Jan 04 12:43:22 2013 +0100
@@ -46,7 +46,16 @@
 Changelog
 ==================
 
-2.4.0 -- 2012-10-26
+2.2.0 --
+
+- make evolve smarter at picking next troubled to solved without --any
+
+2.1.0 -- 2012-12-03
+
+- qsync fixes
+- have qfold ask for commit message
+
+2.0.0 -- 2012-10-26
 
 - compat with mercurial 2.4
 
--- a/debian/changelog	Mon Dec 03 00:10:58 2012 +0100
+++ b/debian/changelog	Fri Jan 04 12:43:22 2013 +0100
@@ -1,3 +1,9 @@
+mercurial-evolve (2.1.0-1) UNRELEASED; urgency=low
+
+  * New upstream release
+
+ -- Pierre-Yves David <pierre-yves.david@logilab.fr>  Mon, 03 Dec 2012 15:19:19 +0100
+
 mercurial-evolve (1.1.0-1) UNRELEASED; urgency=low
 
   * New upstream release.
--- a/docs/evolve-faq.rst	Mon Dec 03 00:10:58 2012 +0100
+++ b/docs/evolve-faq.rst	Fri Jan 04 12:43:22 2013 +0100
@@ -132,14 +132,18 @@
   # current changeset (.) and previous one (.^) replace A (42)
   $ hg prune --new . --new .^ 42
 
+For more complexe scenario we recommand the use of the histedit_ extension.
 
-Update my current work in progess after a pull
+.. _histedit:: http://mercurial.selenic.com/wiki/HisteditExtension
+
+
+Update my current work in progress after a pull
 ----------------------------------------------
 
-Whenever you are working on some changesets, it is more likely that a pull 
+Whenever you are working on some changesets, it is more likely that a pull
 will, eventually, import new changesets in your tree.
 
-And it is likely that you will want your work in progress changsets to be 
+And it is likely that you will want your work in progress changiesets to be
 rebased on the top of this newly imported subtree.
 
 Doing so is only a matter of rebasing.
--- a/docs/from-mq.rst	Mon Dec 03 00:10:58 2012 +0100
+++ b/docs/from-mq.rst	Fri Jan 04 12:43:22 2013 +0100
@@ -14,12 +14,13 @@
 qseries                         ``log``
 qnew                            ``commit``
 qrefresh                        ``amend``
+qrefresh --exclude              ``uncommit``
 qpop                            ``update`` or ``gdown``
 qpush                           ``update`` or ``gup`` sometimes ``evolve``
 qrm                             ``prune``
 qfold                           ``fold``
 qdiff                           ``odiff``
-qrecord                         ``/qrecord``
+qrecord                         ``record``
 
 qfinish                         --
 qimport                         --
@@ -86,10 +87,10 @@
 ..   $ hg record babar.py
 ..   $ hg amend -c .^ # .^ refer to "working directoy parent, here 'feature A'
 
-note: refresh is an alias for amend
+.. note: refresh is an alias for amend
 
-hg qref -X
-````````````
+hg qref --exclude
+`````````````````````
 
 To remove changes from you current commit use::
 
@@ -114,10 +115,10 @@
 ````````
 
 When you rewrite changesets, descendants of rewritten changesets are marked as
-"out of sync". You need to rewrite them on top of the new version of their
+"unstable". You need to rewrite them on top of the new version of their
 ancestor.
 
-The evolution extension adds a command to rewrite the "out of sync"
+The evolution extension adds a command to rewrite "unstable"
 changesets:::
 
   $ hg evolve
@@ -141,13 +142,6 @@
 
   $ hg prune <revset>
 
-hg qrm
-```````
-
-::
-
-  $ hg fold <first>::<last>
-
 hg qfold
 `````````
 
--- a/docs/index.rst	Mon Dec 03 00:10:58 2012 +0100
+++ b/docs/index.rst	Fri Jan 04 12:43:22 2013 +0100
@@ -20,7 +20,7 @@
 The effort is split in two parts:
 
  * The **obsolescence marker** concept aims to provide an alternative to ``strip``
-   to get rid of changesets. This concept have been partially implemented in
+   to get rid of changesets. This concept have been partially implemented since
    Mercurial 2.3.
 
  * The **evolve** mercurial extension rewrites history using obsolete
@@ -78,20 +78,18 @@
 
              Production ready version should hide such details to normal user.
 
-The evolve extension require mercurial 2.3
+The evolve extension requires mercurial 2.4 (older version supports 2.3 and 2.2)
 
 To enable the evolve extension use::
 
     $ hg clone https://bitbucket.org/marmoute/mutable-history -u stable
     $ echo '[extensions]\nevolve=$PWD/mutable-history/hgext/evolve.py' >> ~/.hgrc
 
-You will probably want to use hgview_ to visualize obsolescence. Version 1.6.2
+You will probably want to use hgview_ to visualize obsolescence. Version 1.7.0
 or later is required.
 
 .. _hgview: http://www.logilab.org/project/hgview/
 
-(The old version 0.7 of evolve works with mercurial 2.2 but have far less feature)
-
 
  ---
 
--- a/hgext/evolve.py	Mon Dec 03 00:10:58 2012 +0100
+++ b/hgext/evolve.py	Fri Jan 04 12:43:22 2013 +0100
@@ -34,7 +34,7 @@
     from mercurial import bookmarks
     bookmarks.bmstore
 except (ImportError, AttributeError):
-    raise util.Abort('This version of Evolve is too old for you mercurial version',
+    raise util.Abort('Your Mercurial is too old for this version of Evolve',
                      hint='requires version >> 2.4.x')
 
 
@@ -344,25 +344,6 @@
 latediff = 1  # flag to prevent taking late comer fix into account
 
 
-@cachefor('divergent')
-def _computedivergentset(repo):
-    """the set of rev trying to obsolete public revision"""
-    divergent = set()
-    obsstore = repo.obsstore
-    newermap = {}
-    for ctx in repo.set('(not public()) - obsolete()'):
-        mark = obsstore.precursors.get(ctx.node(), ())
-        toprocess = set(mark)
-        while toprocess:
-            prec = toprocess.pop()[0]
-            if prec not in newermap:
-                successorssets(repo, prec, newermap)
-            newer = [n for n in newermap[prec] if n]
-            if len(newer) > 1:
-                divergent.add(ctx.rev())
-                break
-            toprocess.update(obsstore.precursors.get(prec, ()))
-    return divergent
 
 ### changectx method
 
@@ -395,23 +376,6 @@
 
 
 
-### Discovery wrapping
-
-@eh.wrapfunction(discovery, 'checkheads')
-def wrapcheckheads(orig, repo, remote, outgoing, *args, **kwargs):
-    """wrap mercurial.discovery.checkheads
-
-    * prevent divergent to be pushed
-    """
-    # do not push instability
-    for h in outgoing.missingheads:
-        # Checking heads is enough, obsolete descendants are either
-        # obsolete or unstable.
-        ctx = repo[h]
-        if ctx.divergent():
-            raise util.Abort(_("push includes a divergent changeset: %s!")
-                             % ctx)
-    return orig(repo, remote, outgoing, *args, **kwargs)
 
 #####################################################################
 ### Filter extinct changesets from common operations              ###
@@ -580,122 +544,6 @@
             cs.add(sr)
     return cs
 
-nodemod = node
-def successorssets(repo, initialnode, cache=None):
-    """Return the newer version of an obsolete changeset"""
-
-    # prec -> markers mapping
-    markersfor = repo.obsstore.successors
-
-    # Stack of node need to know the last successors set
-    toproceed = [initialnode]
-    # set version of toproceed for fast loop detection
-    stackedset = set(toproceed)
-    if cache is None:
-        cache = {}
-    while toproceed:
-        # work on the last node of the stack
-        node = toproceed[-1]
-        if node in cache:
-            # We already have a value for it.
-            # Keep working on something else.
-            stackedset.remove(toproceed.pop())
-        elif node not in markersfor:
-            # The node is not obsolete.
-            # This mean it is its own last successors.
-            if node in repo:
-                # We have a valid last successors.
-                cache[node] = [(node,)]
-            else:
-                # final obsolete version is unknown locally.
-                # Do not count that as a valid successors
-                cache[node] = []
-        else:
-            # <lss> stand for Last Successors Sets
-            # it contains the list of all last successors for the current node.
-            lss = []
-            for mark in markersfor[node]:
-                # <mlss> stand for Marker Last Successors Sets
-                # it contains the list of last successors set introduced by
-                # this marker.
-                mlss = [[]]
-                # iterate over possible multiple successors
-                for suc in mark[1]:
-                    if suc not in cache:
-                        # We do not know the last successors of that yet.
-                        if suc in stackedset:
-                            # Loop detected!
-                            #
-                            # we won't be able to ever compute a proper last
-                            # successors the naive and simple approve is to
-                            # consider it killed
-                            cache[suc] = []
-                        else:
-                            # Add the successor to the stack and break the next
-                            # iteration will work on this successors and the
-                            # algorithm will eventually process the current
-                            # node again.
-                            toproceed.append(suc)
-                            stackedset.add(suc)
-                            break
-                    # if we did not break, we can extend the possible set of
-                    # last successors.
-                    #
-                    # I say "extends" because if the marker have multiple
-                    # successors we have to generate
-                    #
-                    # if successors have multiple successors set (when ther are
-                    # divergent themself), we do a cartesian product of
-                    # possible successors set of already processed successors
-                    # and newly obtains successors set.
-                    newmlss = []
-                    for prefix in mlss:
-                        for suffix in cache[suc]:
-                            newss = list(prefix)
-                            for part in suffix:
-                                # do not duplicated entry in successors set.
-                                # first entry win.
-                                if part not in newss:
-                                    newss.append(part)
-                            newmlss.append(newss)
-                    mlss = newmlss
-                else:
-                    # note: mlss is still empty if the marker was a bare killing
-                    # of this changeset
-                    #
-                    # We extends the list of all possible successors sets with
-                    # successors set continuted by this marker
-                    lss.extend(mlss)
-                    # we use continue here to skip the break right bellow
-                    continue
-                # propagate "nested for" break.
-                # if the nested for exited on break, it did not ran the else
-                # clause and didn't "continue
-                break
-            else:
-                # computation was succesful for *all* marker.
-                # Add computed successors set to the cache
-                # (will be poped from to proceeed) on the new iteration
-                #
-                # We remove successors set that are subset of another one
-                # this fil
-                candsucset = sorted(((len(ss), set(ss), ss) for ss in lss),
-                                    reverse=True)
-                finalsucset = []
-                for cl, cs, css in candsucset:
-                    if not css:
-                        # remove empty successors set
-                        continue
-                    for fs, fss in finalsucset:
-                        if cs.issubset(fs):
-                            break
-                    else:
-                        finalsucset.append((cs, css))
-                finalsucset = [s[1] for s in finalsucset]
-                finalsucset.reverse()
-                cache[node] = finalsucset
-    return cache[initialnode]
-
 
 
 
@@ -804,7 +652,7 @@
     priordivergents = len(repo.revs('divergent()'))
     ret = orig(ui, repo, *args, **kwargs)
     # workaround phase stupidity
-    phases._filterunknown(ui, repo.changelog, repo._phasecache.phaseroots)
+    #phases._filterunknown(ui, repo.changelog, repo._phasecache.phaseroots)
     newunstables = len(repo.revs('unstable()')) - priorunstables
     newbumpeds = len(repo.revs('bumped()')) - priorbumpeds
     newdivergents = len(repo.revs('divergent()')) - priordivergents
@@ -853,7 +701,7 @@
     ret = orig(ui, repo, *args, **kwargs)
     nbunstable = len(getrevs(repo, 'unstable'))
     nbbumped = len(getrevs(repo, 'bumped'))
-    nbdivergent = len(getrevs(repo, 'unstable'))
+    nbdivergent = len(getrevs(repo, 'divergent'))
     write('unstable: %i changesets\n', nbunstable)
     write('bumped: %i changesets\n', nbbumped)
     write('divergent: %i changesets\n', nbdivergent)
@@ -1112,6 +960,8 @@
         else:
             ui.write_err(_('no troubled changeset\n'))
             return 1
+    repo = repo.unfiltered()
+    tr = repo[tr.rev()]
     cmdutil.bailifchanged(repo)
     troubles = tr.troubles()
     if 'unstable' in troubles:
@@ -1150,31 +1000,36 @@
     """
     def selfanddescendants(repo, pctx):
         yield pctx
+        for prec in repo.set('allprecursors(%d)', pctx):
+            yield prec
         for ctx in pctx.descendants():
             yield ctx
+            for prec in repo.set('allprecursors(%d)', ctx):
+                yield prec
 
     # Look for an unstable which can be stabilized as a child of
     # node. The unstable must be a child of one of node predecessors.
     for ctx in selfanddescendants(repo, pctx):
-        unstables = list(repo.set('unstable() and children(allprecursors(%d))',
-                                  ctx.rev()))
-        if unstables:
-            return unstables[0]
+        for child in ctx.children():
+            if child.unstable():
+                return child
     return None
 
 def _solveunstable(ui, repo, orig, dryrun=False):
     """Stabilize a unstable changeset"""
     obs = orig.parents()[0]
     if not obs.obsolete():
+        print obs.rev(), orig.parents()
+        print orig.rev()
         obs = orig.parents()[1]
     assert obs.obsolete()
-    newer = successorssets(repo, obs.node())
+    newer = obsolete.successorssets(repo, obs.node())
     # search of a parent which is not killed
     while not newer or newer == [()]:
         ui.debug("stabilize target %s is plain dead,"
                  " trying to stabilize on its parent")
         obs = obs.parents()[0]
-        newer = successorssets(repo, obs.node())
+        newer = obsolete.successorssets(repo, obs.node())
     if len(newer) > 1:
         ui.write_err(_("conflict rewriting. can't choose destination\n"))
         return 2
@@ -1397,7 +1252,7 @@
     XXX this woobly function won't survive XXX
     """
     for base in ctx._repo.set('reverse(precursors(%d))', ctx):
-        newer = successorssets(ctx._repo, base.node())
+        newer = obsolete.successorssets(ctx._repo, base.node())
         # drop filter and solution including the original ctx
         newer = [n for n in newer if n and ctx.node() not in n]
         if newer:
@@ -1458,8 +1313,9 @@
         return 1
 
 @command('^prune|obsolete|kill',
-    [('n', 'new', [], _("successor changeset"))],
-    _('[OPTION] REV...'))
+    [('n', 'new', [], _("successor changeset")),
+     ('r', 'rev', [], _("revisions to fold"))],
+    _('[OPTION] [-r] REV...'))
 def kill(ui, repo, *revs, **opts):
     """mark a changeset as obsolete
 
@@ -1470,6 +1326,8 @@
     XXX handle merge
     XXX check immutable first
     """
+    revs = list(revs)
+    revs.extend(opts['rev'])
     wlock = repo.wlock()
     try:
         lock = repo.lock()
@@ -1811,7 +1669,7 @@
         lockmod.release(lock, wlock)
 
 @command('^fold',
-    [('r', 'rev', [], 'revisions to fold'),
+    [('r', 'rev', [], _("revisions to fold")),
     ],
     # allow to choose the seed ?
     _('[-r] revs'))
@@ -1857,64 +1715,11 @@
         finally:
             tr.release()
         ui.status('%i changesets folded\n' % len(revs))
-        if repo.revs('. and %ld', revs):
+        if repo['.'].rev() in revs:
             hg.update(repo, newid)
     finally:
         lockmod.release(lock, wlock)
 
-if 'debugsuccessorssets' not in commands.table:
-
-    @command('debugsuccessorssets',
-        [],
-        _('[REV]'))
-    def debugsuccessorssets(ui, repo, *revs):
-        """show set of successors for revision
-
-        Successors set of changeset A are a consistent group of revision that
-        succeed to A. Successors set contains non-obsolete changeset only.
-
-        In most case a changeset A have zero (changeset pruned) or a single
-        successors set that contains a single successors (changeset A replacement
-        by A')
-
-        But splitted changeset will result with successors set containing more than
-        a single element. Divergent rewritting will result in multiple successor
-        set.
-
-        result is displayed as follows::
-
-            <rev1>
-                <successors-1A>
-            <rev2>
-                <successors-2A>
-                <successors-2B1> <successors-2B1> <successors-2B1>
-
-        here rev2 have two possible successors sets. One hold three elements.
-
-        add --debug if you want full size node id.
-        """
-        cache = {}
-        s = str
-        if ui.debug:
-            def s(ctx):
-                return ctx.hex()
-        for rev in scmutil.revrange(repo, revs):
-            ctx = repo[rev]
-            if ui.debug():
-                ui.write('%s\n'% ctx.hex())
-                s = node.hex
-            else:
-                ui.write('%s\n'% ctx)
-                s = node.short
-            for ss in successorssets(repo, ctx.node(), cache):
-                if ss:
-                    ui.write('    ')
-                    ui.write(s(ss[0]))
-                    for n in ss[1:]:
-                        ui.write(' ')
-                        ui.write(s(n))
-                ui.write('\n')
-        pass
 
 
 @eh.wrapcommand('graft')
--- a/hgext/qsync.py	Mon Dec 03 00:10:58 2012 +0100
+++ b/hgext/qsync.py	Fri Jan 04 12:43:22 2013 +0100
@@ -16,6 +16,7 @@
 from mercurial import error
 from mercurial import extensions
 from mercurial import phases
+from mercurial import obsolete
 
 ### old compat code
 #############################
@@ -85,8 +86,7 @@
                     review_list.append(patch_name)
                 except IOError:
                     oldnode = oldfiles[patch_name]
-                    evolve = extensions.find('evolve')
-                    newnodes = evolve.successorssets(repo, oldnode)
+                    newnodes = obsolete.successorssets(repo, oldnode)
                     if newnodes:
                         newnodes = [n for n in newnodes if n and n[0] in repo] # remove killing
                     if not newnodes:
@@ -177,7 +177,7 @@
         usedold.add(oldhex)
         oldname = str(oldname)
         oldnode = bin(oldhex)
-        newnodes = evolve.successorssets(repo, oldnode)
+        newnodes = obsolete.successorssets(repo, oldnode)
         if newnodes:
             newnodes = [n for n in newnodes if n and n[0] in repo] # remove killing
             if len(newnodes) > 1:
--- a/setup.py	Mon Dec 03 00:10:58 2012 +0100
+++ b/setup.py	Fri Jan 04 12:43:22 2013 +0100
@@ -5,7 +5,7 @@
 
 setup(
     name='hg-evolve',
-    version='2.0.0',
+    version='2.99.0',
     author='Pierre-Yves David',
     maintainer='Pierre-Yves David',
     maintainer_email='pierre-yves.david@logilab.fr',
--- a/tests/test-amend.t	Mon Dec 03 00:10:58 2012 +0100
+++ b/tests/test-amend.t	Fri Jan 04 12:43:22 2013 +0100
@@ -11,7 +11,7 @@
   >   hg glog --template '{rev}@{branch}({phase}) {desc|firstline}\n' "$@"
   > }
 
-  $ hg init repo
+  $ hg init repo --traceback
   $ cd repo
   $ echo a > a
   $ hg ci -Am adda
--- a/tests/test-evolve.t	Mon Dec 03 00:10:58 2012 +0100
+++ b/tests/test-evolve.t	Fri Jan 04 12:43:22 2013 +0100
@@ -79,7 +79,7 @@
 
 test multiple kill
 
-  $ hg kill 4 3
+  $ hg kill 4 -r 3
   0 files updated, 0 files merged, 1 files removed, 0 files unresolved
   working directory now at 7c3bad9141dc
   $ hg qlog
--- a/tests/test-obsolete-divergent.t	Mon Dec 03 00:10:58 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,442 +0,0 @@
-Test file decicated to testing the divergent troubles from obsolete changeset.
-
-This is the most complexe troubles from far so we isolate it in a dedicated
-file.
-
-Enable obsolete
-
-  $ cat >> $HGRCPATH << EOF
-  > [ui]
-  > logtemplate = {rev}:{node|short} {desc}\n
-  > [alias]
-  > debugobsolete = debugobsolete -d '0 0'
-  > [phases]
-  > publish=False
-  > [extensions]
-  > rebase=
-  > EOF
-  $ echo "evolve=$(echo $(dirname $TESTDIR))/hgext/evolve.py" >> $HGRCPATH
-
-
-  $ mkcommit() {
-  >    echo "$1" > "$1"
-  >    hg add "$1"
-  >    hg ci -m "$1"
-  > }
-  $ getid() {
-  >    hg id --hidden --debug -ir "desc('$1')"
-  > }
-
-setup repo
-
-  $ hg init reference
-  $ cd reference
-  $ mkcommit base
-  $ mkcommit A_0
-  $ hg up 0
-  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
-  $ mkcommit A_1
-  created new head
-  $ hg up 0
-  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
-  $ mkcommit A_2
-  created new head
-  $ hg up 0
-  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
-  $ cd ..
-
-
-  $ newcase() {
-  >    hg clone -u 0 -q reference $1
-  >    cd $1
-  > }
-
-direct divergence
------------------
-
-A_1 have two direct and divergent successors A_1 and A_1
-
-  $ newcase direct
-  $ hg debugobsolete `getid A_0` `getid A_1`
-  $ hg debugobsolete `getid A_0` `getid A_2`
-  $ hg log -G --hidden
-  o  3:392fd25390da A_2
-  |
-  | o  2:82623d38b9ba A_1
-  |/
-  | x  1:007dc284c1f8 A_0
-  |/
-  @  0:d20a80d4def3 base
-  
-  $ hg debugsuccessorssets --hidden 'all()'
-  d20a80d4def3
-      d20a80d4def3
-  007dc284c1f8
-      392fd25390da
-      82623d38b9ba
-  82623d38b9ba
-      82623d38b9ba
-  392fd25390da
-      392fd25390da
-  $ hg log -r 'divergent()'
-  2:82623d38b9ba A_1
-  3:392fd25390da A_2
-
-check that mercurial refuse to push
-
-  $ hg init ../other
-  $ hg log -r 'outgoing("../other") and divergent()'
-  2:82623d38b9ba A_1
-  3:392fd25390da A_2
-  $ hg push ../other
-  pushing to ../other
-  searching for changes
-  abort: push includes a divergent changeset: (82623d38b9ba|392fd25390da)! (re)
-  (use 'hg evolve' to get a stable history or --force to ignore warnings)
-  [255]
-
-  $ cd ..
-
-
-indirect divergence with known changeset
--------------------------------------------
-
-  $ newcase indirect_known
-  $ hg debugobsolete `getid A_0` `getid A_1`
-  $ hg debugobsolete `getid A_0` `getid A_2`
-  $ mkcommit A_3
-  created new head
-  $ hg debugobsolete `getid A_2` `getid A_3`
-  $ hg log -G --hidden
-  @  4:01f36c5a8fda A_3
-  |
-  | x  3:392fd25390da A_2
-  |/
-  | o  2:82623d38b9ba A_1
-  |/
-  | x  1:007dc284c1f8 A_0
-  |/
-  o  0:d20a80d4def3 base
-  
-  $ hg debugsuccessorssets --hidden 'all()'
-  d20a80d4def3
-      d20a80d4def3
-  007dc284c1f8
-      01f36c5a8fda
-      82623d38b9ba
-  82623d38b9ba
-      82623d38b9ba
-  392fd25390da
-      01f36c5a8fda
-  01f36c5a8fda
-      01f36c5a8fda
-  $ hg log -r 'divergent()'
-  2:82623d38b9ba A_1
-  4:01f36c5a8fda A_3
-  $ cd ..
-
-
-indirect divergence with known changeset
--------------------------------------------
-
-  $ newcase indirect_unknown
-  $ hg debugobsolete `getid A_0` aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-  $ hg debugobsolete aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa `getid A_1`
-  $ hg debugobsolete `getid A_0` `getid A_2`
-  $ hg log -G --hidden
-  o  3:392fd25390da A_2
-  |
-  | o  2:82623d38b9ba A_1
-  |/
-  | x  1:007dc284c1f8 A_0
-  |/
-  @  0:d20a80d4def3 base
-  
-  $ hg debugsuccessorssets --hidden 'all()'
-  d20a80d4def3
-      d20a80d4def3
-  007dc284c1f8
-      392fd25390da
-      82623d38b9ba
-  82623d38b9ba
-      82623d38b9ba
-  392fd25390da
-      392fd25390da
-  $ hg log -r 'divergent()'
-  2:82623d38b9ba A_1
-  3:392fd25390da A_2
-  $ cd ..
-
-do not take unknown node in account if they are final
------------------------------------------------------
-
-  $ newcase final-unknown
-  $ hg debugobsolete `getid A_0` `getid A_1`
-  $ hg debugobsolete `getid A_1` `getid A_2`
-  $ hg debugobsolete `getid A_0` bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
-  $ hg debugobsolete bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb cccccccccccccccccccccccccccccccccccccccc
-  $ hg debugobsolete `getid A_1` dddddddddddddddddddddddddddddddddddddddd
-
-  $ hg debugsuccessorssets --hidden 'desc('A_0')'
-  007dc284c1f8
-      392fd25390da
-
-  $ cd ..
-
-divergence that converge again is not divergence anymore
------------------------------------------------------
-
-  $ newcase converged_divergence
-  $ hg debugobsolete `getid A_0` `getid A_1`
-  $ hg debugobsolete `getid A_0` `getid A_2`
-  $ mkcommit A_3
-  created new head
-  $ hg debugobsolete `getid A_1` `getid A_3`
-  $ hg debugobsolete `getid A_2` `getid A_3`
-  $ hg log -G --hidden
-  @  4:01f36c5a8fda A_3
-  |
-  | x  3:392fd25390da A_2
-  |/
-  | x  2:82623d38b9ba A_1
-  |/
-  | x  1:007dc284c1f8 A_0
-  |/
-  o  0:d20a80d4def3 base
-  
-  $ hg debugsuccessorssets --hidden 'all()'
-  d20a80d4def3
-      d20a80d4def3
-  007dc284c1f8
-      01f36c5a8fda
-  82623d38b9ba
-      01f36c5a8fda
-  392fd25390da
-      01f36c5a8fda
-  01f36c5a8fda
-      01f36c5a8fda
-  $ hg log -r 'divergent()'
-  $ cd ..
-
-split is not divergences
------------------------------
-
-  $ newcase split
-  $ hg debugobsolete `getid A_0` `getid A_1` `getid A_2`
-  $ hg log -G --hidden
-  o  3:392fd25390da A_2
-  |
-  | o  2:82623d38b9ba A_1
-  |/
-  | x  1:007dc284c1f8 A_0
-  |/
-  @  0:d20a80d4def3 base
-  
-  $ hg debugsuccessorssets --hidden 'all()'
-  d20a80d4def3
-      d20a80d4def3
-  007dc284c1f8
-      82623d38b9ba 392fd25390da
-  82623d38b9ba
-      82623d38b9ba
-  392fd25390da
-      392fd25390da
-  $ hg log -r 'divergent()'
-
-Even when subsequente rewriting happen
-
-  $ mkcommit A_3
-  created new head
-  $ hg debugobsolete `getid A_1` `getid A_3`
-  $ hg up 0
-  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
-  $ mkcommit A_4
-  created new head
-  $ hg debugobsolete `getid A_2` `getid A_4`
-  $ hg up 0
-  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
-  $ mkcommit A_5
-  created new head
-  $ hg debugobsolete `getid A_4` `getid A_5`
-  $ hg log -G --hidden
-  @  6:e442cfc57690 A_5
-  |
-  | x  5:6a411f0d7a0a A_4
-  |/
-  | o  4:01f36c5a8fda A_3
-  |/
-  | x  3:392fd25390da A_2
-  |/
-  | x  2:82623d38b9ba A_1
-  |/
-  | x  1:007dc284c1f8 A_0
-  |/
-  o  0:d20a80d4def3 base
-  
-  $ hg debugsuccessorssets --hidden 'all()'
-  d20a80d4def3
-      d20a80d4def3
-  007dc284c1f8
-      01f36c5a8fda e442cfc57690
-  82623d38b9ba
-      01f36c5a8fda
-  392fd25390da
-      e442cfc57690
-  01f36c5a8fda
-      01f36c5a8fda
-  6a411f0d7a0a
-      e442cfc57690
-  e442cfc57690
-      e442cfc57690
-  $ hg log -r 'divergent()'
-
-Check more complexe obsolescence graft (with divergence)
-
-  $ mkcommit B_0; hg up 0
-  0 files updated, 0 files merged, 2 files removed, 0 files unresolved
-  $ hg debugobsolete `getid B_0` `getid A_2`
-  $ mkcommit A_7; hg up 0
-  created new head
-  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
-  $ mkcommit A_8; hg up 0
-  created new head
-  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
-  $ hg debugobsolete `getid A_5` `getid A_7` `getid A_8`
-  $ mkcommit A_9; hg up 0
-  created new head
-  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
-  $ hg debugobsolete `getid A_5` `getid A_9`
-  $ hg log -G --hidden
-  o  10:bed64f5d2f5a A_9
-  |
-  | o  9:14608b260df8 A_8
-  |/
-  | o  8:7ae126973a96 A_7
-  |/
-  | x  7:3750ebee865d B_0
-  | |
-  | x  6:e442cfc57690 A_5
-  |/
-  | x  5:6a411f0d7a0a A_4
-  |/
-  | o  4:01f36c5a8fda A_3
-  |/
-  | x  3:392fd25390da A_2
-  |/
-  | x  2:82623d38b9ba A_1
-  |/
-  | x  1:007dc284c1f8 A_0
-  |/
-  @  0:d20a80d4def3 base
-  
-  $ hg debugsuccessorssets --hidden 'all()'
-  d20a80d4def3
-      d20a80d4def3
-  007dc284c1f8
-      01f36c5a8fda bed64f5d2f5a
-      01f36c5a8fda 7ae126973a96 14608b260df8
-  82623d38b9ba
-      01f36c5a8fda
-  392fd25390da
-      bed64f5d2f5a
-      7ae126973a96 14608b260df8
-  01f36c5a8fda
-      01f36c5a8fda
-  6a411f0d7a0a
-      bed64f5d2f5a
-      7ae126973a96 14608b260df8
-  e442cfc57690
-      bed64f5d2f5a
-      7ae126973a96 14608b260df8
-  3750ebee865d
-      bed64f5d2f5a
-      7ae126973a96 14608b260df8
-  7ae126973a96
-      7ae126973a96
-  14608b260df8
-      14608b260df8
-  bed64f5d2f5a
-      bed64f5d2f5a
-  $ hg log -r 'divergent()'
-  4:01f36c5a8fda A_3
-  8:7ae126973a96 A_7
-  9:14608b260df8 A_8
-  10:bed64f5d2f5a A_9
-
-fix the divergence
-
-  $ mkcommit A_A; hg up 0
-  created new head
-  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
-  $ hg debugobsolete `getid A_9` `getid A_A`
-  $ hg debugobsolete `getid A_7` `getid A_A`
-  $ hg debugobsolete `getid A_8` `getid A_A`
-  $ hg log -G --hidden
-  o  11:a139f71be9da A_A
-  |
-  | x  10:bed64f5d2f5a A_9
-  |/
-  | x  9:14608b260df8 A_8
-  |/
-  | x  8:7ae126973a96 A_7
-  |/
-  | x  7:3750ebee865d B_0
-  | |
-  | x  6:e442cfc57690 A_5
-  |/
-  | x  5:6a411f0d7a0a A_4
-  |/
-  | o  4:01f36c5a8fda A_3
-  |/
-  | x  3:392fd25390da A_2
-  |/
-  | x  2:82623d38b9ba A_1
-  |/
-  | x  1:007dc284c1f8 A_0
-  |/
-  @  0:d20a80d4def3 base
-  
-  $ hg debugsuccessorssets --hidden 'all()'
-  d20a80d4def3
-      d20a80d4def3
-  007dc284c1f8
-      01f36c5a8fda a139f71be9da
-  82623d38b9ba
-      01f36c5a8fda
-  392fd25390da
-      a139f71be9da
-  01f36c5a8fda
-      01f36c5a8fda
-  6a411f0d7a0a
-      a139f71be9da
-  e442cfc57690
-      a139f71be9da
-  3750ebee865d
-      a139f71be9da
-  7ae126973a96
-      a139f71be9da
-  14608b260df8
-      a139f71be9da
-  bed64f5d2f5a
-      a139f71be9da
-  a139f71be9da
-      a139f71be9da
-  $ hg log -r 'divergent()'
-
-  $ cd ..
-
-
-Subset does not diverge
-------------------------------
-
-Do not report divergent successors-set if it is a subset of another
-successors-set. (report [A,B] not [A] + [A,B])
-
-  $ newcase subset
-  $ hg debugobsolete `getid A_0` `getid A_2`
-  $ hg debugobsolete `getid A_0` `getid A_1` `getid A_2`
-  $ hg debugsuccessorssets --hidden 'desc('A_0')'
-  007dc284c1f8
-      82623d38b9ba 392fd25390da
-
-  $ cd ..
--- a/tests/test-obsolete.t	Mon Dec 03 00:10:58 2012 +0100
+++ b/tests/test-obsolete.t	Fri Jan 04 12:43:22 2013 +0100
@@ -260,8 +260,8 @@
   adding changesets
   adding manifests
   adding file changes
-  added 1 changesets with 1 changes to 1 files (+1 heads)
-  (run 'hg heads .' to see heads, 'hg merge' to merge)
+  added 1 changesets with 1 changes to [12] files \(\+1 heads\) (re)
+  \(run 'hg heads( \.)?' to see heads, 'hg merge' to merge\) (re)
   $ qlog -R ../other-new
   6
   - 909a0fb57e5d
@@ -349,8 +349,8 @@
   adding changesets
   adding manifests
   adding file changes
-  added 1 changesets with 1 changes to 1 files (+1 heads)
-  (run 'hg heads .' to see heads, 'hg merge' to merge)
+  added 1 changesets with 1 changes to [12] files \(\+1 heads\) (re)
+  \(run 'hg heads( \.)?' to see heads, 'hg merge' to merge\) (re)
 
   $ hg up -q 7 # to check rollback update behavior
   $ qlog
@@ -374,7 +374,6 @@
   commit: 1 deleted, 2 unknown (clean)
   update: 2 new changesets, 2 branch heads (merge)
   unstable: 1 changesets
-  divergent: 1 changesets
   $ qlog
   6
   - 909a0fb57e5d
--- a/tests/test-tutorial.t	Mon Dec 03 00:10:58 2012 +0100
+++ b/tests/test-tutorial.t	Fri Jan 04 12:43:22 2013 +0100
@@ -14,8 +14,6 @@
   > # "-d '0 0'" means that the new commit will be at January 1st 1970.
   > # This is used for stable hash during test
   > amend = amend -d '0 0'
-  > [extensions]
-  > hgext.graphlog=
   > EOF
 
   $ hg init local
@@ -55,10 +53,6 @@
   $ hg showconfig diff
   diff.git=1
 
-And the graphlog extension
-  $ hg showconfig extensions
-  extensions.hgext.graphlog=
-
 And of course, we enable the experimental extensions for mutable history:
 
   $ cat >> $HGRCPATH <<EOF
@@ -120,7 +114,7 @@
 
 This history is very linear
 
-  $ hg glog
+  $ hg log -G
   @  d85de4546133 (draft): adding fruit
   |
   o  4d5dc8187023 (draft): adding condiment
@@ -153,7 +147,7 @@
 the outside. The first one have been exchanged and is an immutable public
 changeset.
 
-  $ hg glog
+  $ hg log -G
   @  d85de4546133 (draft): adding fruit
   |
   o  4d5dc8187023 (draft): adding condiment
@@ -161,7 +155,7 @@
   o  7e82d3f3c2cb (public): Monthy Python Shopping list
   
 
-hopefully. I can use hg amend to rewrite my faulty changeset!
+hopefully. I can use `hg commit --amend` to rewrite my faulty changeset!
 
   $ sed -i'' -e s/Bananos/Banana/ shopping
   $ hg diff
@@ -176,12 +170,12 @@
   +Banana
    Pear
    Apple
-  $ hg amend
+  $ hg commit --amend
 
 A new changeset with the right diff replace the wrong one.
 
-  $ hg glog
-  @  0cacb48f4482 (draft): adding fruit
+  $ hg log -G
+  @  9d0363b81950 (draft): adding fruit
   |
   o  4d5dc8187023 (draft): adding condiment
   |
@@ -191,7 +185,7 @@
   # HG changeset patch
   # User test
   # Date 0 0
-  # Node ID 0cacb48f44828d2fd31c4e45e18fde32a5b2f07b
+  # Node ID 9d0363b81950646bc6ad1ec5de8b8197ea586541
   # Parent  4d5dc81870237d492284826e21840b2ca00e26d1
   adding fruit
   
@@ -233,7 +227,7 @@
   $ hg log -G
   o  9ca060c80d74 (public): SPAM
   |
-  | @  0cacb48f4482 (draft): adding fruit
+  | @  9d0363b81950 (draft): adding fruit
   | |
   | o  4d5dc8187023 (draft): adding condiment
   |/
@@ -251,7 +245,7 @@
 My local work is now rebased on the remote one.
 
   $ hg log -G
-  @  387187ad9bd9 (draft): adding fruit
+  @  41aff6a42b75 (draft): adding fruit
   |
   o  dfd3a2d7691e (draft): adding condiment
   |
@@ -273,9 +267,9 @@
   > EOF
   $ hg ci -m 'transport'
   $ hg log -G
-  @  d58c77aa15d7 (draft): transport
+  @  1125e39fbf21 (draft): transport
   |
-  o  387187ad9bd9 (draft): adding fruit
+  o  41aff6a42b75 (draft): adding fruit
   |
   o  dfd3a2d7691e (draft): adding condiment
   |
@@ -289,12 +283,12 @@
 
   $ hg prune . # . is for working directory parent
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
-  working directory now at 387187ad9bd9
+  working directory now at 41aff6a42b75
 
 The silly changeset is gone.
 
   $ hg log -G
-  @  387187ad9bd9 (draft): adding fruit
+  @  41aff6a42b75 (draft): adding fruit
   |
   o  dfd3a2d7691e (draft): adding condiment
   |
@@ -322,11 +316,11 @@
   $ sed -i'' -e 's/Spam/Spam Spam Spam/g' shopping
   $ hg ci -m 'SPAM SPAM'
   $ hg log -G
-  @  c48f32fb1787 (draft): SPAM SPAM
+  @  fac207dec9f5 (draft): SPAM SPAM
   |
-  o  8d39a843582d (draft): bathroom stuff
+  o  10b8aeaa8cc8 (draft): bathroom stuff
   |
-  o  387187ad9bd9 (draft): adding fruit
+  o  41aff6a42b75 (draft): adding fruit
   |
   o  dfd3a2d7691e (draft): adding condiment
   |
@@ -335,7 +329,7 @@
   o  7e82d3f3c2cb (public): Monthy Python Shopping list
   
 
-.. note: don't amend changeset 7e82d3f3c2cb or 9ca060c80d74 as they are immutable.
+.. note: We can't amend changeset 7e82d3f3c2cb or 9ca060c80d74 as they are immutable.
 
 I now want to push to remote all my change but the bathroom one that i'm not
 totally happy with yet. To be able to push "SPAM SPAM" I need a version of "SPAM SPAM" not children of
@@ -343,17 +337,16 @@
 
 You can use 'rebase -r' or 'graft -O' for that:
 
-  $ hg up 'p1(8d39a843582d)' # going on "bathroom stuff" parent
+  $ hg up 'p1(10b8aeaa8cc8)' # going on "bathroom stuff" parent
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
-  $ hg graft -O c48f32fb1787 # moving "SPAM SPAM" to the working directory parent
-  grafting revision 10
+  $ hg rebase --rev fac207dec9f5 --dest . # moving "SPAM SPAM" to the working directory parent
   merging shopping
   $ hg log -G
-  @  a2fccc2e7b08 (draft): SPAM SPAM
+  @  a224f2a4fb9f (draft): SPAM SPAM
   |
-  | o  8d39a843582d (draft): bathroom stuff
+  | o  10b8aeaa8cc8 (draft): bathroom stuff
   |/
-  o  387187ad9bd9 (draft): adding fruit
+  o  41aff6a42b75 (draft): adding fruit
   |
   o  dfd3a2d7691e (draft): adding condiment
   |
@@ -364,7 +357,7 @@
 
 We have a new SPAM SPAM version without the bathroom stuff
 
-  $ grep Spam shopping  # enouth spam
+  $ grep Spam shopping  # enough spam
   Spam Spam Spam Spam Spam Spam Spam Spam Spam
   $ grep Toothbrush shopping # no Toothbrush
   [1]
@@ -372,8 +365,8 @@
   # HG changeset patch
   # User test
   # Date 0 0
-  # Node ID a2fccc2e7b08bbce6af7255b989453f7089e4cf0
-  # Parent  387187ad9bd9d8f9a00a9fa804a26231db547429
+  # Node ID a224f2a4fb9f9f828f608959912229d7b38b26de
+  # Parent  41aff6a42b7578ec7ec3cb2041633f1ca43cca96
   SPAM SPAM
   
   diff --git a/shopping b/shopping
@@ -389,7 +382,7 @@
 To make sure I do not push unready changeset by mistake I set the "bathroom
 stuff" changeset in the secret phase.
 
-  $ hg phase --force --secret 8d39a843582d
+  $ hg phase --force --secret 10b8aeaa8cc8
 
 we can now push our change:
 
@@ -403,15 +396,15 @@
 
 for simplicity shake we get the bathroom change in line again
 
-  $ hg rebase -r 8d39a843582d -d a2fccc2e7b08
+  $ hg rebase -r 10b8aeaa8cc8 -d a224f2a4fb9f
   merging shopping
   $ hg phase --draft .
   $ hg log -G
-  @  8a79ae8b029e (draft): bathroom stuff
+  @  75954b8cd933 (draft): bathroom stuff
   |
-  o  a2fccc2e7b08 (public): SPAM SPAM
+  o  a224f2a4fb9f (public): SPAM SPAM
   |
-  o  387187ad9bd9 (public): adding fruit
+  o  41aff6a42b75 (public): adding fruit
   |
   o  dfd3a2d7691e (public): adding condiment
   |
@@ -425,13 +418,12 @@
 Splitting change
 ------------------
 
-To be done (currently achieve with "two commit + debugobsolete")
+histedit or uncommit
 
 Collapsing change
 ------------------
 
-To be done (currently achieve with "revert + debugobsolete" or "rebase --collapse")
-
+This can be done with hg fold but the tutorial part is not written yet.
 
 
 
@@ -464,11 +456,11 @@
   added 1 changesets with 1 changes to 1 files
   (run 'hg update' to get a working copy)
   $ hg log -G
-  o  8a79ae8b029e (public): bathroom stuff
+  o  75954b8cd933 (public): bathroom stuff
   |
-  o  a2fccc2e7b08 (public): SPAM SPAM
+  o  a224f2a4fb9f (public): SPAM SPAM
   |
-  o  387187ad9bd9 (public): adding fruit
+  o  41aff6a42b75 (public): adding fruit
   |
   o  dfd3a2d7691e (public): adding condiment
   |
@@ -484,9 +476,9 @@
   $ hg rollback
   repository tip rolled back to revision 4 (undo pull)
   $ hg log -G
-  o  a2fccc2e7b08 (public): SPAM SPAM
+  o  a224f2a4fb9f (public): SPAM SPAM
   |
-  o  387187ad9bd9 (public): adding fruit
+  o  41aff6a42b75 (public): adding fruit
   |
   o  dfd3a2d7691e (public): adding condiment
   |
@@ -518,11 +510,11 @@
   added 1 changesets with 1 changes to 1 files
   (run 'hg update' to get a working copy)
   $ hg log -G
-  o  8a79ae8b029e (draft): bathroom stuff
+  o  75954b8cd933 (draft): bathroom stuff
   |
-  o  a2fccc2e7b08 (public): SPAM SPAM
+  o  a224f2a4fb9f (public): SPAM SPAM
   |
-  o  387187ad9bd9 (public): adding fruit
+  o  41aff6a42b75 (public): adding fruit
   |
   o  dfd3a2d7691e (public): adding condiment
   |
@@ -536,7 +528,7 @@
 
 Remotely someone add a new changeset on top of the mutable "bathroom" on.
 
-  $ hg up 8a79ae8b029e -q
+  $ hg up 75954b8cd933 -q
   $ cat >> shopping << EOF
   > Giraffe
   > Rhino
@@ -548,15 +540,15 @@
 But at the same time, locally, this same "bathroom changeset" was updated.
 
   $ cd ../local
-  $ hg up 8a79ae8b029e -q
+  $ hg up 75954b8cd933 -q
   $ sed -i'' -e 's/... More bathroom stuff to come/Bath Robe/' shopping
-  $ hg amend
+  $ hg commit --amend
   $ hg log -G
-  @  ffa278c50818 (draft): bathroom stuff
+  @  a44c85f957d3 (draft): bathroom stuff
   |
-  o  a2fccc2e7b08 (public): SPAM SPAM
+  o  a224f2a4fb9f (public): SPAM SPAM
   |
-  o  387187ad9bd9 (public): adding fruit
+  o  41aff6a42b75 (public): adding fruit
   |
   o  dfd3a2d7691e (public): adding condiment
   |
@@ -584,15 +576,15 @@
 see both version showing up in the log.
 
   $ hg log -G
-  o  9ac5d0e790a2 (draft): animals
+  o  bf1b0d202029 (draft): animals
   |
-  | @  ffa278c50818 (draft): bathroom stuff
+  | @  a44c85f957d3 (draft): bathroom stuff
   | |
-  x |  8a79ae8b029e (draft): bathroom stuff
+  x |  75954b8cd933 (draft): bathroom stuff
   |/
-  o  a2fccc2e7b08 (public): SPAM SPAM
+  o  a224f2a4fb9f (public): SPAM SPAM
   |
-  o  387187ad9bd9 (public): adding fruit
+  o  41aff6a42b75 (public): adding fruit
   |
   o  dfd3a2d7691e (public): adding condiment
   |
@@ -601,10 +593,10 @@
   o  7e82d3f3c2cb (public): Monthy Python Shopping list
   
 
-The older version 8a79ae8b029e never ceased to exist in the local repo. It was
+The older version 75954b8cd933 never ceased to exist in the local repo. It was
 jsut hidden and excluded from pull and push.
 
-.. note:: In hgview there is a nice doted relation highlighting ffa278c50818 as a new version of 8a79ae8b029e. this is not yet ported to graphlog.
+.. note:: In hgview there is a nice doted relation highlighting a44c85f957d3 as a new version of 75954b8cd933. this is not yet ported to graphlog.
 
 Their is **unstable** changeset in this history now. Mercurial will refuse to
 share it with the outside:
@@ -612,38 +604,40 @@
   $ hg push other
   pushing to $TESTTMP/other
   searching for changes
-  abort: push includes unstable changeset: 9ac5d0e790a2!
+  abort: push includes unstable changeset: bf1b0d202029!
   (use 'hg evolve' to get a stable history or --force to ignore warnings)
   [255]
  
 
 
 
-To resolve this unstable state, you need to rebase 9ac5d0e790a2 onto
-ffa278c50818 the "hg evolve" command will make this for you.
+To resolve this unstable state, you need to rebase bf1b0d202029 onto
+a44c85f957d3 the "hg evolve" command will make this for you.
 
 It has a --dry-run option to only suggest the next move.
 
   $ hg evolve --dry-run
   move:[15] animals
   atop:[14] bathroom stuff
-  hg rebase -r 9ac5d0e790a2 -d ffa278c50818
+  hg rebase -r bf1b0d202029 -d a44c85f957d3
 
 Let's do it
 
-  $ hg rebase -r 9ac5d0e790a2 -d ffa278c50818
+  $ hg evolve
+  move:[15] animals
+  atop:[14] bathroom stuff
   merging shopping
 
 The old version of bathroom is hidden again.
 
   $ hg log -G
-  @  437efbcaf700 (draft): animals
+  @  ee942144f952 (draft): animals
   |
-  o  ffa278c50818 (draft): bathroom stuff
+  o  a44c85f957d3 (draft): bathroom stuff
   |
-  o  a2fccc2e7b08 (public): SPAM SPAM
+  o  a224f2a4fb9f (public): SPAM SPAM
   |
-  o  387187ad9bd9 (public): adding fruit
+  o  41aff6a42b75 (public): adding fruit
   |
   o  dfd3a2d7691e (public): adding condiment
   |
@@ -672,7 +666,7 @@
   no changes found
   Working directory parent is obsolete
 
-  $ hg up 437efbcaf700
+  $ hg up ee942144f952
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
 
 Relocating unstable change after prune
@@ -695,15 +689,15 @@
   added 1 changesets with 1 changes to 1 files
   (run 'hg update' to get a working copy)
   $ hg log -G
-  o  ae45c0c3092a (draft): SPAM SPAM SPAM
+  o  99f039c5ec9e (draft): SPAM SPAM SPAM
   |
-  @  437efbcaf700 (draft): animals
+  @  ee942144f952 (draft): animals
   |
-  o  ffa278c50818 (draft): bathroom stuff
+  o  a44c85f957d3 (draft): bathroom stuff
   |
-  o  a2fccc2e7b08 (public): SPAM SPAM
+  o  a224f2a4fb9f (public): SPAM SPAM
   |
-  o  387187ad9bd9 (public): adding fruit
+  o  41aff6a42b75 (public): adding fruit
   |
   o  dfd3a2d7691e (public): adding condiment
   |
@@ -714,9 +708,9 @@
 
 In the mean time I noticed you can't buy animals in a super market and I prune the animal changeset:
 
-  $ hg prune 437efbcaf700
+  $ hg prune ee942144f952
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
-  working directory now at ffa278c50818
+  working directory now at a44c85f957d3
   1 new unstable changesets
 
 
@@ -724,15 +718,15 @@
 is neither dead or obsolete.  My repository is in an unstable state again.
 
   $ hg log -G
-  o  ae45c0c3092a (draft): SPAM SPAM SPAM
+  o  99f039c5ec9e (draft): SPAM SPAM SPAM
   |
-  x  437efbcaf700 (draft): animals
+  x  ee942144f952 (draft): animals
   |
-  @  ffa278c50818 (draft): bathroom stuff
+  @  a44c85f957d3 (draft): bathroom stuff
   |
-  o  a2fccc2e7b08 (public): SPAM SPAM
+  o  a224f2a4fb9f (public): SPAM SPAM
   |
-  o  387187ad9bd9 (public): adding fruit
+  o  41aff6a42b75 (public): adding fruit
   |
   o  dfd3a2d7691e (public): adding condiment
   |
@@ -742,21 +736,21 @@
   
 
   $ hg log -r 'unstable()'
-  ae45c0c3092a (draft): SPAM SPAM SPAM
+  99f039c5ec9e (draft): SPAM SPAM SPAM
 
-  $ hg evolve --any
+  $ hg evolve
   move:[17] SPAM SPAM SPAM
   atop:[14] bathroom stuff
   merging shopping
 
   $ hg log -G
-  @  d6717f710962 (draft): SPAM SPAM SPAM
+  @  40aa40daeefb (draft): SPAM SPAM SPAM
   |
-  o  ffa278c50818 (draft): bathroom stuff
+  o  a44c85f957d3 (draft): bathroom stuff
   |
-  o  a2fccc2e7b08 (public): SPAM SPAM
+  o  a224f2a4fb9f (public): SPAM SPAM
   |
-  o  387187ad9bd9 (public): adding fruit
+  o  41aff6a42b75 (public): adding fruit
   |
   o  dfd3a2d7691e (public): adding condiment
   |
@@ -769,7 +763,7 @@
 Handling Conflicting amend
 ----------------------------------------------
 
-We can detect that multiple diverging//conflicting amend have been made. There
-will be a "evol-merge" command to merge conflicting amend
+We can detect that multiple diverging//conflicting amend have been made.
+hg evolve is able to solve several of them
 
-This command is not ready yet.
+This section need to be written