--- 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