merge with stable
authorPierre-Yves David <pierre-yves.david@logilab.fr>
Wed, 02 Jan 2013 14:38:40 +0100
changeset 645 ca5459892427
parent 633 3d5bed04ee4c (diff)
parent 644 8e41d5b78dff (current diff)
child 646 04d8e5f7fcbc
merge with stable
hgext/evolve.py
setup.py
tests/test-obsolete-divergent.t
tests/test-obsolete.t
--- a/debian/control	Mon Dec 03 14:41:14 2012 +0100
+++ b/debian/control	Wed Jan 02 14:38:40 2013 +0100
@@ -7,10 +7,8 @@
  Pierre-Yves David <pierre-yves.david@logilab.fr>,
 Standards-Version: 3.9.3
 Build-Depends:
- mercurial (>=2.4~),
- mercurial (<<2.5),
- mercurial-common (>=2.4~),
- mercurial-common (<<2.5),
+ mercurial (>=2.5~),
+ mercurial-common (>=2.5~),
  python,
  debhelper (>= 8),
  python-sphinx (>= 1.0.8),
@@ -24,8 +22,7 @@
 Depends:
  ${python:Depends},
  ${misc:Depends},
- mercurial (>= 2.4),
- mercurial (<<2.5),
+ mercurial (>= 2.5),
 Description: evolve extension for Mercurial
  This package provides the experimental "evolve" extension for the Mercurial
  DVCS.
--- a/hgext/evolve.py	Mon Dec 03 14:41:14 2012 +0100
+++ b/hgext/evolve.py	Wed Jan 02 14:38:40 2013 +0100
@@ -19,7 +19,7 @@
     - improves some aspect of the early implementation in 2.3
 '''
 
-testedwith = '2.4'
+testedwith = ''
 buglink = 'https://bitbucket.org/marmoute/mutable-history/issues'
 
 
@@ -29,17 +29,13 @@
 
 try:
     from mercurial import obsolete
-    getattr(obsolete, 'getrevs') # 2.4 specific
     if not obsolete._enabled:
         obsolete._enabled = True
-except (ImportError, AttributeError):
-    raise util.Abort('Evolve extension requires Mercurial 2.4.x')
-try:
     from mercurial import bookmarks
     bookmarks.bmstore
-    raise util.Abort('This version of Evolve is too old for you mercurial version')
-except AttributeError:
-    pass
+except (ImportError, AttributeError):
+    raise util.Abort('This version of Evolve is too old for you mercurial version',
+                     hint='requires version >> 2.4.x')
 
 
 
@@ -348,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
 
@@ -399,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              ###
@@ -584,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]
-
 
 
 
@@ -1038,7 +882,7 @@
         for book in destbookmarks: # restore bookmark that rebase move
             repo._bookmarks[book] = dest.node()
         if oldbookmarks or destbookmarks:
-            bookmarks.write(repo)
+            repo._bookmarks.write()
         return nodenew
     except util.Abort:
         # Invalidate the previous setparents
@@ -1061,7 +905,7 @@
                 repo._bookmarks[b] = newid
             dirty = True
         if dirty:
-            bookmarks.write(repo)
+            repo._bookmarks.write()
     return updatebookmarks
 
 ### new command
@@ -1123,6 +967,8 @@
     elif 'bumped' in troubles:
         return _solvebumped(ui, repo, tr, opts['dry_run'])
     elif 'divergent' in troubles:
+        repo = repo.unfiltered()
+        tr = repo[tr.rev()]
         return _solvedivergent(ui, repo, tr, opts['dry_run'])
     else:
         assert False  # WHAT? unknown troubles
@@ -1175,13 +1021,13 @@
         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
@@ -1404,7 +1250,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:
@@ -1772,7 +1618,7 @@
             for book in oldbookmarks:
                 repo._bookmarks[book] = new.node()
             if oldbookmarks:
-                bookmarks.write(repo)
+                repo._bookmarks.write()
         return result
     finally:
         if lock is not None:
@@ -1867,64 +1713,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 14:41:14 2012 +0100
+++ b/hgext/qsync.py	Wed Jan 02 14:38:40 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 14:41:14 2012 +0100
+++ b/setup.py	Wed Jan 02 14:38:40 2013 +0100
@@ -5,7 +5,7 @@
 
 setup(
     name='hg-evolve',
-    version='2.1.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 14:41:14 2012 +0100
+++ b/tests/test-amend.t	Wed Jan 02 14:38:40 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-obsolete-divergent.t	Mon Dec 03 14:41:14 2012 +0100
+++ b/tests/test-obsolete-divergent.t	Wed Jan 02 14:38:40 2013 +0100
@@ -95,10 +95,13 @@
 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!
+  abort: push includes divergent changeset: (82623d38b9ba|392fd25390da)! (re)
   (use 'hg evolve' to get a stable history or --force to ignore warnings)
   [255]
 
--- a/tests/test-obsolete.t	Mon Dec 03 14:41:14 2012 +0100
+++ b/tests/test-obsolete.t	Wed Jan 02 14:38:40 2013 +0100
@@ -262,8 +262,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
@@ -351,8 +351,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