[PATCH 01 of 23 v2] rebase: move originalwd, external, state and activebookmark to the class
Kostia Balytskyi
ikostia at fb.com
Tue May 31 23:23:21 UTC 2016
# HG changeset patch
# User Kostia Balytskyi <ikostia at fb.com>
# Date 1464736907 -3600
# Wed Jun 01 00:21:47 2016 +0100
# Node ID 10ef01af780db775aa8b9758d992c7435f24932a
# Parent 318534bb5dfd37b1c95f10ba90b73c5ce562713f
rebase: move originalwd, external, state and activebookmark to the class
This is an initial piece of my effort to refactor rebase. At first I tried to
break the main rebase function into smaller helper functions, but the amount
of state main function maintains as local variables is too big and means that
helper functions would have to be called this way:
'(v0, v1, v2, v3, ..., vn) = helperfunction(v0, v1, v2, v3, ..., vn)'
So I want to turn rebase into a class in a couple of stages:
- move most of the local variables to be scoped under a RebaseRuntimeState
- break rebase function into pieces and make them methods of this class
- move some other functions to be methods of this class
After I've spent a day on this I realized that I'd better get some feedback
earleir in the process, so please tell me if the above sounds reasonable.
diff --git a/hgext/rebase.py b/hgext/rebase.py
--- a/hgext/rebase.py
+++ b/hgext/rebase.py
@@ -119,6 +119,17 @@
sourceset = revset.getset(repo, revset.fullreposet(repo), x)
return subset & revset.baseset([_destrebase(repo, sourceset)])
+class RebaseRuntimeState(object):
+ """This class is a container for rebase runtime state"""
+ def __init__(self):
+ self.originalwd = None
+ self.external = nullrev
+ # Mapping between the old revision id and either what is the new rebased
+ # revision or what needs to be done with the old revision. The state
+ # dict will be what contains most of the rebase progress state.
+ self.state = {}
+ self.activebookmark = None
+
@command('rebase',
[('s', 'source', '',
_('rebase the specified changeset and descendants'), _('REV')),
@@ -229,13 +240,8 @@
unresolved conflicts.
"""
- originalwd = target = None
- activebookmark = None
- external = nullrev
- # Mapping between the old revision id and either what is the new rebased
- # revision or what needs to be done with the old revision. The state dict
- # will be what contains most of the rebase progress state.
- state = {}
+ rtstate = RebaseRuntimeState()
+ target = None
skipped = set()
targetancestors = set()
@@ -296,8 +302,9 @@
ui.warn(_('tool option will be ignored\n'))
try:
- (originalwd, target, state, skipped, collapsef, keepf,
- keepbranchesf, external, activebookmark) = restorestatus(repo)
+ (rtstate.originalwd, target, rtstate.state, skipped,
+ collapsef, keepf, keepbranchesf, rtstate.external,
+ rtstate.activebookmark) = restorestatus(repo)
collapsemsg = restorecollapsemsg(repo)
except error.RepoLookupError:
if abortf:
@@ -311,18 +318,17 @@
hint = _('use "hg rebase --abort" to clear broken state')
raise error.Abort(msg, hint=hint)
if abortf:
- return abort(repo, originalwd, target, state,
- activebookmark=activebookmark)
+ return abort(repo, rtstate.originalwd, target, rtstate.state,
+ activebookmark=rtstate.activebookmark)
obsoletenotrebased = {}
if ui.configbool('experimental', 'rebaseskipobsolete',
default=True):
- rebaseobsrevs = set([r for r, status in state.items()
- if status == revprecursor])
- rebasesetrevs = set(state.keys())
+ rebaseobsrevs = set([r for r, st in rtstate.state.items()
+ if st == revprecursor])
+ rebasesetrevs = set(rtstate.state.keys())
obsoletenotrebased = _computeobsoletenotrebased(repo,
- rebaseobsrevs,
- target)
+ rebaseobsrevs, target)
rebaseobsskipped = set(obsoletenotrebased)
_checkobsrebase(repo, ui, rebaseobsrevs, rebasesetrevs,
rebaseobsskipped)
@@ -368,11 +374,12 @@
% repo[root],
hint=_('see "hg help phases" for details'))
- originalwd, target, state = result
+ (rtstate.originalwd, target, rtstate.state) = result
if collapsef:
targetancestors = repo.changelog.ancestors([target],
inclusive=True)
- external = externalparent(repo, state, targetancestors)
+ rtstate.external = externalparent(repo, rtstate.state,
+ targetancestors)
if dest.closesbranch() and not keepbranchesf:
ui.status(_('reopening closed branch head %s\n') % dest)
@@ -384,7 +391,7 @@
extrafns.insert(0, _savebranch)
if collapsef:
branches = set()
- for rev in state:
+ for rev in rtstate.state:
branches.add(repo[rev].branch())
if len(branches) > 1:
raise error.Abort(_('cannot collapse multiple named '
@@ -396,13 +403,13 @@
# Keep track of the current bookmarks in order to reset them later
currentbookmarks = repo._bookmarks.copy()
- activebookmark = activebookmark or repo._activebookmark
- if activebookmark:
+ rtstate.activebookmark = rtstate.activebookmark or repo._activebookmark
+ if rtstate.activebookmark:
bookmarks.deactivate(repo)
extrafn = _makeextrafn(extrafns)
- sortedstate = sorted(state)
+ sortedstate = sorted(rtstate.state)
total = len(sortedstate)
pos = 0
for rev in sortedstate:
@@ -413,15 +420,16 @@
if names:
desc += ' (%s)' % ' '.join(names)
pos += 1
- if state[rev] == revtodo:
+ if rtstate.state[rev] == revtodo:
ui.status(_('rebasing %s\n') % desc)
ui.progress(_("rebasing"), pos, ("%d:%s" % (rev, ctx)),
_('changesets'), total)
- p1, p2, base = defineparents(repo, rev, target, state,
+ p1, p2, base = defineparents(repo, rev, target, rtstate.state,
targetancestors,
obsoletenotrebased)
- storestatus(repo, originalwd, target, state, collapsef, keepf,
- keepbranchesf, external, activebookmark)
+ storestatus(repo, rtstate.originalwd, target, rtstate.state,
+ collapsef, keepf, keepbranchesf,
+ rtstate.external, rtstate.activebookmark)
storecollapsemsg(repo, collapsemsg)
if len(repo[None].parents()) == 2:
repo.ui.debug('resuming interrupted rebase\n')
@@ -429,7 +437,7 @@
try:
ui.setconfig('ui', 'forcemerge', opts.get('tool', ''),
'rebase')
- stats = rebasenode(repo, rev, p1, base, state,
+ stats = rebasenode(repo, rev, p1, base, rtstate.state,
collapsef, target)
if stats and stats[3] > 0:
raise error.InterventionRequired(
@@ -453,38 +461,38 @@
newnode = None
# Update the state
if newnode is not None:
- state[rev] = repo[newnode].rev()
+ rtstate.state[rev] = repo[newnode].rev()
ui.debug('rebased as %s\n' % short(newnode))
else:
if not collapsef:
ui.warn(_('note: rebase of %d:%s created no changes '
'to commit\n') % (rev, ctx))
skipped.add(rev)
- state[rev] = p1
+ rtstate.state[rev] = p1
ui.debug('next revision set to %s\n' % p1)
- elif state[rev] == nullmerge:
+ elif rtstate.state[rev] == nullmerge:
ui.debug('ignoring null merge rebase of %s\n' % rev)
- elif state[rev] == revignored:
+ elif rtstate.state[rev] == revignored:
ui.status(_('not rebasing ignored %s\n') % desc)
- elif state[rev] == revprecursor:
+ elif rtstate.state[rev] == revprecursor:
targetctx = repo[obsoletenotrebased[rev]]
desctarget = '%d:%s "%s"' % (targetctx.rev(), targetctx,
targetctx.description().split('\n', 1)[0])
msg = _('note: not rebasing %s, already in destination as %s\n')
ui.status(msg % (desc, desctarget))
- elif state[rev] == revpruned:
+ elif rtstate.state[rev] == revpruned:
msg = _('note: not rebasing %s, it has no successor\n')
ui.status(msg % desc)
else:
ui.status(_('already rebased %s as %s\n') %
- (desc, repo[state[rev]]))
+ (desc, repo[rtstate.state[rev]]))
ui.progress(_('rebasing'), None)
ui.note(_('rebase merging completed\n'))
if collapsef and not keepopen:
- p1, p2, _base = defineparents(repo, min(state), target,
- state, targetancestors,
+ p1, p2, _base = defineparents(repo, min(rtstate.state), target,
+ rtstate.state, targetancestors,
obsoletenotrebased)
editopt = opts.get('edit')
editform = 'rebase.collapse'
@@ -492,12 +500,14 @@
commitmsg = collapsemsg
else:
commitmsg = 'Collapsed revision'
- for rebased in state:
- if rebased not in skipped and state[rebased] > nullmerge:
+ for rebased in rtstate.state:
+ if rebased not in skipped and\
+ rtstate.state[rebased] > nullmerge:
commitmsg += '\n* %s' % repo[rebased].description()
editopt = True
editor = cmdutil.getcommiteditor(edit=editopt, editform=editform)
- newnode = concludenode(repo, rev, p1, external, commitmsg=commitmsg,
+ newnode = concludenode(repo, rev, p1, rtstate.external,
+ commitmsg=commitmsg,
extrafn=extrafn, editor=editor,
keepbranches=keepbranchesf,
date=date)
@@ -505,17 +515,17 @@
newrev = target
else:
newrev = repo[newnode].rev()
- for oldrev in state.iterkeys():
- if state[oldrev] > nullmerge:
- state[oldrev] = newrev
+ for oldrev in rtstate.state.iterkeys():
+ if rtstate.state[oldrev] > nullmerge:
+ rtstate.state[oldrev] = newrev
if 'qtip' in repo.tags():
- updatemq(repo, state, skipped, **opts)
+ updatemq(repo, rtstate.state, skipped, **opts)
if currentbookmarks:
# Nodeids are needed to reset bookmarks
nstate = {}
- for k, v in state.iteritems():
+ for k, v in rtstate.state.iteritems():
if v > nullmerge:
nstate[repo[k].node()] = repo[v].node()
# XXX this is the same as dest.node() for the non-continue path --
@@ -524,10 +534,10 @@
# restore original working directory
# (we do this before stripping)
- newwd = state.get(originalwd, originalwd)
+ newwd = rtstate.state.get(rtstate.originalwd, rtstate.originalwd)
if newwd < 0:
# original directory is a parent of rebase set root or ignored
- newwd = originalwd
+ newwd = rtstate.originalwd
if newwd not in [c.rev() for c in repo[None].parents()]:
ui.note(_("update back to initial working directory parent\n"))
hg.updaterepo(repo, newwd, False)
@@ -536,14 +546,14 @@
collapsedas = None
if collapsef:
collapsedas = newnode
- clearrebased(ui, repo, state, skipped, collapsedas)
+ clearrebased(ui, repo, rtstate.state, skipped, collapsedas)
with repo.transaction('bookmark') as tr:
if currentbookmarks:
updatebookmarks(repo, targetnode, nstate, currentbookmarks, tr)
- if activebookmark not in repo._bookmarks:
+ if rtstate.activebookmark not in repo._bookmarks:
# active bookmark was divergent one and has been deleted
- activebookmark = None
+ rtstate.activebookmark = None
clearstatus(repo)
clearcollapsemsg(repo)
@@ -552,9 +562,9 @@
if skipped:
ui.note(_("%d revisions have been skipped\n") % len(skipped))
- if (activebookmark and
- repo['.'].node() == repo._bookmarks[activebookmark]):
- bookmarks.activate(repo, activebookmark)
+ if (rtstate.activebookmark and
+ repo['.'].node() == repo._bookmarks[rtstate.activebookmark]):
+ bookmarks.activate(repo, rtstate.activebookmark)
finally:
release(lock, wlock)
More information about the Mercurial-devel
mailing list