--- a/hgext/evolve.py Fri Jun 19 13:57:16 2015 -0700
+++ b/hgext/evolve.py Tue Jun 16 15:14:37 2015 -0700
@@ -1183,15 +1183,22 @@
mean = sum(len(x[1]) for x in allpclusters) // nbcluster
ui.write(' mean length: %9i\n' % mean)
-def _solveone(ui, repo, ctx, dryrun, confirm, progresscb):
+def _solveone(ui, repo, ctx, dryrun, confirm, progresscb, category):
"""Resolve the troubles affecting one revision"""
wlock = lock = tr = None
try:
wlock = repo.wlock()
lock = repo.lock()
tr = repo.transaction("evolve")
- result = _evolveany(ui, repo, ctx, dryrun, confirm,
- progresscb=progresscb)
+ if 'unstable' == category:
+ result = _solveunstable(ui, repo, ctx, dryrun, confirm, progresscb)
+ elif 'bumped' == category:
+ result = _solvebumped(ui, repo, ctx, dryrun, confirm, progresscb)
+ elif 'divergent' == category:
+ result = _solvedivergent(ui, repo, ctx, dryrun, confirm,
+ progresscb)
+ else:
+ assert False, "unknown trouble category: %s" % (category)
tr.close()
return result
finally:
@@ -1335,6 +1342,9 @@
'ask for confirmation before performing the action'),
('A', 'any', False, 'also consider troubled changesets unrelated to current working directory'),
('r', 'rev', '', 'solves troubles of these revisions'),
+ ('', 'bumped', False, 'solves only bumped changesets'),
+ ('', 'divergent', False, 'solves only divergent changesets'),
+ ('', 'unstable', False, 'solves only unstable changesets (default)'),
('a', 'all', False, 'evolve all troubled changesets in the repo '
'(implies any)'),
('c', 'continue', False, 'continue an interrupted evolution'),
@@ -1358,15 +1368,16 @@
working copy will be updated on the result (this last behavior will most
likely to change in the future).
- See --all and --any options to change this behavior.
-
- - For unstable, this means taking the first which could be rebased as a
- child of the working directory parent revision or one of its descendants
- and rebasing it.
-
- - For divergent, this means taking "." if applicable.
-
- With --any, evolve picks any troubled changeset to repair.
+ You can decide to evolve other categories of trouble using the --divergent
+ and --bumped flags. If no other option are specified, this will try to
+ solve the specified troubles for the working copy parent.
+
+ You can also evolve changesets affected by troubles of the selected
+ category using the --rev options. You can pick the next one anywhere in the
+ repo using --any.
+
+ You can evolve all the changesets affected by troubles of the selected
+ category using --all.
The working directory is updated to the newly created revision.
"""
@@ -1379,6 +1390,15 @@
dryrunopt = opts['dry_run']
confirmopt = opts['confirm']
revopt = opts['rev']
+ troublecategories = ['bumped', 'divergent', 'unstable']
+ specifiedcategories = [t for t in troublecategories if opts[t]]
+ targetcat = 'unstable'
+ if 1 < len(specifiedcategories):
+ msg = _('cannot specify more than one trouble category to solve (yet)')
+ raise util.Abort(msg)
+ elif len(specifiedcategories) == 1:
+ targetcat = specifiedcategories[0]
+
ui.setconfig('ui', 'forcemerge', opts.get('tool', ''), 'evolve')
troubled = set(repo.revs('troubled()'))
@@ -1401,61 +1421,42 @@
return graftcmd(ui, repo, old_obsolete=True, **{'continue': True})
cmdutil.bailifchanged(repo)
- # Rev specified on the commands line
- if revopt:
- revs = repo.revs(revopt)
- troubled = repo.revs('troubled()')
- _revs = revs & troubled
- if not _revs:
- ui.write_err("No troubled changes in the specified revisions\n")
- else:
- # For the progress bar to show
- count = len(_revs)
- # Order the revisions
- _revs = orderrevs(repo, _revs)
- for rev in _revs:
- progresscb()
- _solveone(ui, repo, repo[rev], dryrunopt, confirmopt,
- progresscb)
- seen += 1
- progresscb()
- _cleanup(ui, repo, startnode, showprogress)
- return
- nexttrouble = _picknexttroubled(ui, repo, anyopt or allopt)
- # No trouble to resolve
- if not nexttrouble:
- return _handlenotrouble(ui, repo, startnode, dryrunopt)
-
- if allopt:
- # Resolving all the troubles
- while nexttrouble:
- progresscb()
- _solveone(ui, repo, nexttrouble, dryrunopt, confirmopt, progresscb)
- seen += 1
- progresscb()
- nexttrouble= _picknexttroubled(ui, repo, anyopt or allopt)
- else:
- # Resolving a single trouble
- _solveone(ui, repo, nexttrouble, dryrunopt, confirmopt, progresscb)
-
+
+ if revopt and allopt:
+ raise util.Abort('cannot specify both "--rev" and "--all"')
+
+ revs = set()
+ if allopt or revopt:
+ revs = repo.revs(targetcat+'()')
+ if revopt:
+ revs = repo.revs(revopt) & revs
+ elif anyopt:
+ revs = repo.revs('first(%s())' % (targetcat))
+ elif targetcat == 'unstable':
+ tro = _stabilizableunstable(repo, repo['.'])
+ if tro is None:
+ return _handlenotrouble(ui, repo, startnode, dryrunopt)
+ revs = set([tro])
+ elif targetcat in repo['.'].troubles():
+ revs = set([repo['.'].rev()])
+ if not revs:
+ msg = "no troubled changes in the specified revisions"
+ raise util.Abort(msg)
+
+ # For the progress bar to show
+ count = len(revs)
+ # Order the revisions
+ if targetcat == 'unstable':
+ revs = orderrevs(repo, revs)
+ for rev in revs:
+ progresscb()
+ _solveone(ui, repo, repo[rev], dryrunopt, confirmopt,
+ progresscb, targetcat)
+ seen += 1
+ progresscb()
_cleanup(ui, repo, startnode, showprogress)
-
-def _evolveany(ui, repo, tro, dryrunopt, confirmopt, progresscb):
- repo = repo.unfiltered()
- tro = repo[tro.rev()]
- troubles = tro.troubles()
- if 'unstable' in troubles:
- return _solveunstable(ui, repo, tro, dryrunopt, confirmopt, progresscb)
- elif 'bumped' in troubles:
- return _solvebumped(ui, repo, tro, dryrunopt, confirmopt, progresscb)
- elif 'divergent' in troubles:
- return _solvedivergent(ui, repo, tro, dryrunopt, confirmopt,
- progresscb)
- else:
- assert False # WHAT? unknown troubles
-
-def _picknexttroubled(ui, repo, pickany=False, progresscb=None):
+def _picknexttroubled(ui, repo, category, pickany=False, progresscb=None):
"""Pick a the next trouble changeset to solve"""
if progresscb: progresscb()
tro = _stabilizableunstable(repo, repo['.'])
@@ -1555,6 +1556,8 @@
def _solvebumped(ui, repo, bumped, dryrun=False, confirm=False,
progresscb=None):
"""Stabilize a bumped changeset"""
+ repo = repo.unfiltered()
+ bumped = repo[bumped.rev()]
# For now we deny bumped merge
if len(bumped.parents()) > 1:
raise util.Abort('late comer stabilization is confused by bumped'
@@ -1661,6 +1664,8 @@
def _solvedivergent(ui, repo, divergent, dryrun=False, confirm=False,
progresscb=None):
+ repo = repo.unfiltered()
+ divergent = repo[divergent.rev()]
base, others = divergentdata(divergent)
if len(others) > 1:
othersstr = "[%s]" % (','.join([str(i) for i in others]))