hgsubversion: use new-style progress bars

Reviewed By: mjpieters

Differential Revision: D7329498

fbshipit-source-id: 138dcd425ceb6e8e35c134555bfb07c1680e5674
This commit is contained in:
Mark Thomas 2018-03-21 13:45:39 -07:00 committed by Saurabh Singh
parent b46a47be82
commit 50792d83d8
3 changed files with 222 additions and 228 deletions

View File

@ -8,6 +8,7 @@ import errno
from mercurial import commands
from mercurial import hg
from mercurial import node
from mercurial import progress
from mercurial import util as hgutil
from mercurial import error
@ -106,167 +107,166 @@ def _buildmeta(ui, repo, args, partial=False, skipuuid=False):
# it would make us use O(revisions^2) time, so we perform an extra traversal
# of the repository instead. During this traversal, we find all converted
# changesets that close a branch, and store their first parent
for ctx in util.get_contexts(repo, startrev):
ui.progress('prepare', ctx.rev() - startrev, total=numrevs)
with progress.bar(ui, 'prepare', total=numrevs) as prog:
for ctx in util.get_contexts(repo, startrev):
prog.value = ctx.rev() - startrev
convinfo = util.getsvnrev(ctx, None)
if not convinfo:
continue
svnrevnum = int(convinfo.rsplit('@', 1)[1])
youngest = max(youngest, svnrevnum)
convinfo = util.getsvnrev(ctx, None)
if not convinfo:
continue
svnrevnum = int(convinfo.rsplit('@', 1)[1])
youngest = max(youngest, svnrevnum)
if ctx.extra().get('close', None) is None:
continue
if ctx.extra().get('close', None) is None:
continue
droprev = lambda x: x.rsplit('@', 1)[0]
parentctx = ctx.parents()[0]
parentinfo = util.getsvnrev(parentctx, '@')
droprev = lambda x: x.rsplit('@', 1)[0]
parentctx = ctx.parents()[0]
parentinfo = util.getsvnrev(parentctx, '@')
if droprev(parentinfo) == droprev(convinfo):
if parentctx.rev() < startrev:
parentbranch = parentctx.branch()
if parentbranch == 'default':
parentbranch = None
branchinfo.pop(parentbranch)
else:
closed.add(parentctx.rev())
ui.progress('prepare', None, total=numrevs)
if droprev(parentinfo) == droprev(convinfo):
if parentctx.rev() < startrev:
parentbranch = parentctx.branch()
if parentbranch == 'default':
parentbranch = None
branchinfo.pop(parentbranch)
else:
closed.add(parentctx.rev())
revmapbuf = []
for ctx in util.get_contexts(repo, startrev):
ui.progress('rebuild', ctx.rev() - startrev, total=numrevs)
with progress.bar(ui, 'rebuild', total=numrevs) as prog:
for ctx in util.get_contexts(repo, startrev):
prog.value = ctx.rev() - startrev
convinfo = util.getsvnrev(ctx, None)
if not convinfo:
continue
if '.hgtags' in ctx.files():
parent = ctx.parents()[0]
parentdata = ''
if '.hgtags' in parent:
parentdata = parent.filectx('.hgtags').data()
newdata = ctx.filectx('.hgtags').data()
for newtag in newdata[len(parentdata):-1].split('\n'):
ha, tag = newtag.split(' ', 1)
tagged = util.getsvnrev(repo[ha], None)
if tagged is None:
tagged = -1
convinfo = util.getsvnrev(ctx, None)
if not convinfo:
continue
if '.hgtags' in ctx.files():
parent = ctx.parents()[0]
parentdata = ''
if '.hgtags' in parent:
parentdata = parent.filectx('.hgtags').data()
newdata = ctx.filectx('.hgtags').data()
for newtag in newdata[len(parentdata):-1].split('\n'):
ha, tag = newtag.split(' ', 1)
tagged = util.getsvnrev(repo[ha], None)
if tagged is None:
tagged = -1
else:
tagged = int(tagged[40:].split('@')[1])
# This is max(tagged rev, tagging rev) because if it is a
# normal tag, the tagging revision has the right rev number.
# However, if it was an edited tag, then the tagged revision
# has the correct revision number.
tagging = int(convinfo[40:].split('@')[1])
tagrev = max(tagged, tagging)
meta.tags[tag] = node.bin(ha), tagrev
# check that the conversion metadata matches expectations
assert convinfo.startswith('svn:')
revpath, revision = convinfo[40:].split('@')
# use tmp variable for testing
subdir = meta.subdir
if subdir and subdir[0] != '/':
subdir = '/' + subdir
if subdir and subdir[-1] == '/':
subdir = subdir[:-1]
assert revpath.startswith(subdir), ('That does not look like the '
'right location in the repo.')
# meta.layout is a config-cached property so instead of testing for
# None we test to see if the layout is 'auto' and, if so, try to
# guess the layout based on the commits (where subdir is compared to
# the revpath extracted from the commit)
if meta.layout == 'auto':
meta.layout = meta.layout_from_commit(subdir, revpath,
ctx.branch())
elif meta.layout == 'single':
assert (subdir or '/') == revpath, ('Possible layout detection'
' defect in replay')
# write repository uuid if required
if meta.uuid is None or validateuuid:
validateuuid = False
uuid = convinfo[4:40]
if not skipuuid:
if svn is None:
svn = svnrepo.svnremoterepo(ui, url).svn
if uuid != svn.uuid:
raise hgutil.Abort('remote svn repository identifier '
'does not match')
meta.uuid = uuid
# don't reflect closed branches
if (ctx.extra().get('close') and not ctx.files() or
ctx.parents()[0].node() in skipped):
skipped.add(ctx.node())
continue
# find commitpath, write to revmap
commitpath = revpath[len(subdir)+1:]
tag_locations = meta.layoutobj.taglocations
found_tag = False
for location in tag_locations:
if commitpath.startswith(location + '/'):
found_tag = True
break
if found_tag and ctx.extra().get('close'):
continue
branch = meta.layoutobj.localname(commitpath)
revmapbuf.append((revision, branch, ctx.node()))
revision = int(revision)
if revision > last_rev:
last_rev = revision
# deal with branches
if branch and branch.startswith('../'):
parent = ctx
while parent.node() != node.nullid:
parentextra = parent.extra()
parentinfo = util.getsvnrev(parent)
assert parentinfo
parent = parent.parents()[0]
parentpath = parentinfo[40:].split('@')[0][len(subdir) + 1:]
found_tag = False
for location in tag_locations:
if parentpath.startswith(location + '/'):
found_tag = True
break
if found_tag and parentextra.get('close'):
continue
branch = meta.layoutobj.localname(parentpath)
break
if ctx.rev() in closed:
# a direct child of this changeset closes the branch; drop it
branchinfo.pop(branch, None)
elif ctx.extra().get('close'):
pass
elif branch not in branchinfo:
parent = ctx.parents()[0]
if (parent.node() not in skipped
and util.getsvnrev(parent, '').startswith('svn:')
and parent.branch() != ctx.branch()):
parentbranch = parent.branch()
if parentbranch == 'default':
parentbranch = None
else:
tagged = int(tagged[40:].split('@')[1])
# This is max(tagged rev, tagging rev) because if it is a normal
# tag, the tagging revision has the right rev number. However, if it
# was an edited tag, then the tagged revision has the correct revision
# number.
tagging = int(convinfo[40:].split('@')[1])
tagrev = max(tagged, tagging)
meta.tags[tag] = node.bin(ha), tagrev
# check that the conversion metadata matches expectations
assert convinfo.startswith('svn:')
revpath, revision = convinfo[40:].split('@')
# use tmp variable for testing
subdir = meta.subdir
if subdir and subdir[0] != '/':
subdir = '/' + subdir
if subdir and subdir[-1] == '/':
subdir = subdir[:-1]
assert revpath.startswith(subdir), ('That does not look like the '
'right location in the repo.')
# meta.layout is a config-cached property so instead of testing for
# None we test to see if the layout is 'auto' and, if so, try to guess
# the layout based on the commits (where subdir is compared to the
# revpath extracted from the commit)
if meta.layout == 'auto':
meta.layout = meta.layout_from_commit(subdir, revpath,
ctx.branch())
elif meta.layout == 'single':
assert (subdir or '/') == revpath, ('Possible layout detection'
' defect in replay')
# write repository uuid if required
if meta.uuid is None or validateuuid:
validateuuid = False
uuid = convinfo[4:40]
if not skipuuid:
if svn is None:
svn = svnrepo.svnremoterepo(ui, url).svn
if uuid != svn.uuid:
raise hgutil.Abort('remote svn repository identifier '
'does not match')
meta.uuid = uuid
# don't reflect closed branches
if (ctx.extra().get('close') and not ctx.files() or
ctx.parents()[0].node() in skipped):
skipped.add(ctx.node())
continue
# find commitpath, write to revmap
commitpath = revpath[len(subdir)+1:]
tag_locations = meta.layoutobj.taglocations
found_tag = False
for location in tag_locations:
if commitpath.startswith(location + '/'):
found_tag = True
break
if found_tag and ctx.extra().get('close'):
continue
branch = meta.layoutobj.localname(commitpath)
revmapbuf.append((revision, branch, ctx.node()))
revision = int(revision)
if revision > last_rev:
last_rev = revision
# deal with branches
if branch and branch.startswith('../'):
parent = ctx
while parent.node() != node.nullid:
parentextra = parent.extra()
parentinfo = util.getsvnrev(parent)
assert parentinfo
parent = parent.parents()[0]
parentpath = parentinfo[40:].split('@')[0][len(subdir) + 1:]
found_tag = False
for location in tag_locations:
if parentpath.startswith(location + '/'):
found_tag = True
break
if found_tag and parentextra.get('close'):
continue
branch = meta.layoutobj.localname(parentpath)
break
if ctx.rev() in closed:
# a direct child of this changeset closes the branch; drop it
branchinfo.pop(branch, None)
elif ctx.extra().get('close'):
pass
elif branch not in branchinfo:
parent = ctx.parents()[0]
if (parent.node() not in skipped
and util.getsvnrev(parent, '').startswith('svn:')
and parent.branch() != ctx.branch()):
parentbranch = parent.branch()
if parentbranch == 'default':
parentbranch = None
else:
parentbranch = None
# branchinfo is a map from mercurial branch to a
# (svn branch, svn parent revision, svn revision) tuple
parentrev = util.getsvnrev(parent, '@').split('@')[1] or 0
branchinfo[branch] = (parentbranch,
int(parentrev),
revision)
# branchinfo is a map from mercurial branch to a
# (svn branch, svn parent revision, svn revision) tuple
parentrev = util.getsvnrev(parent, '@').split('@')[1] or 0
branchinfo[branch] = (parentbranch,
int(parentrev),
revision)
revmap.batchset(revmapbuf, youngest)
ui.progress('rebuild', None, total=numrevs)
revmap.batchset(revmapbuf, youngest)
# save off branch info
util.dump(branchinfo, meta.branch_info_file)

View File

@ -5,6 +5,7 @@ import posixpath
from mercurial import util as hgutil
from mercurial import error
from mercurial import progress
from mercurial import worker
import svnwrap
@ -95,14 +96,13 @@ def verify(ui, repo, args=None, **opts):
svndata = svn.list_files(branchpath, srev)
w = worker.worker(repo.ui, perarg, verifydata, (), tuple(svndata))
i = 0
for _, t in w:
ui.progress('verify', i, total=len(hgfiles))
i += 1
fn, ok = t.split('\0', 2)
if not bool(ok):
result = 1
svnfiles.add(fn)
with progress.bar(ui, 'verify', total=len(hgfiles)) as prog:
for _, t in w:
prog.value += 1
fn, ok = t.split('\0', 2)
if not bool(ok):
result = 1
svnfiles.add(fn)
if hgfiles != svnfiles:
unexpected = hgfiles - svnfiles
@ -113,20 +113,18 @@ def verify(ui, repo, args=None, **opts):
ui.write('missing file: %s\n' % f)
result = 1
ui.progress('verify', None, total=len(hgfiles))
else:
class VerifyEditor(svnwrap.Editor):
"""editor that verifies a repository against the given context."""
def __init__(self, ui, ctx):
def __init__(self, ui, ctx, prog):
self.ui = ui
self.ctx = ctx
self.prog = prog
self.unexpected = set(ctx) - util.ignoredfiles
self.missing = set()
self.failed = False
self.total = len(self.unexpected)
self.seen = 0
self.prog._total = len(self.unexpected)
def open_root(self, base_revnum, pool=None):
pass
@ -148,14 +146,13 @@ def verify(ui, repo, args=None, **opts):
self.file = path
self.props = {}
else:
self.total += 1
self.prog._total += 1
self.missing.add(path)
self.failed = True
self.file = None
self.props = None
self.seen += 1
self.ui.progress('verify', self.seen, total=self.total)
self.prog.value += 1
def open_file(self, path, base_revnum):
raise NotImplementedError()
@ -214,8 +211,6 @@ def verify(ui, repo, args=None, **opts):
raise NotImplementedError()
def check(self):
self.ui.progress('verify', None, total=self.total)
for f in self.unexpected:
self.ui.warn('unexpected file: %s\n' % f)
self.failed = True
@ -224,11 +219,9 @@ def verify(ui, repo, args=None, **opts):
self.failed = True
return not self.failed
v = VerifyEditor(ui, ctx)
svnrepo.svnremoterepo(ui, branchurl).svn.get_revision(srev, v)
if v.check():
result = 0
else:
result = 1
with progress.bar(ui, 'verify') as prog:
v = VerifyEditor(ui, ctx, prog)
svnrepo.svnremoterepo(ui, branchurl).svn.get_revision(srev, v)
result = 0 if v.check() else 1
return result

View File

@ -14,6 +14,7 @@ except ImportError:
# We only *use* the exchange module in hg 3.2+, so this is safe
pass
from mercurial import patch
from mercurial import progress
from mercurial import hg
from mercurial import util as hgutil
from mercurial import node
@ -21,7 +22,6 @@ from mercurial import i18n
from mercurial import extensions
from mercurial import scmutil
import inspect
import replay
import pushmod
import stupid as stupidmod
@ -463,63 +463,64 @@ def pull(repo, source, heads=None, force=False, meta=None):
try:
# start converting revisions
firstrun = True
for r in svn.revisions(start=start, stop=stopat_rev):
if (r.revnum in skiprevs or
(r.author is None and
r.message == 'This is an empty revision for padding.')):
with progress.bar(ui, 'pull', total=total) as prog:
for r in svn.revisions(start=start, stop=stopat_rev):
if (r.revnum in skiprevs
or (r.author is None
and r.message ==
'This is an empty revision for padding.')):
lastpulled = r.revnum
continue
tbdelta = meta.update_branch_tag_map_for_rev(r)
# got a 502? Try more than once!
tries = 0
converted = False
while not converted:
try:
msg = meta.getmessage(r).strip()
if msg:
msg = [s.strip()
for s in msg.splitlines() if s][0]
if getattr(ui, 'termwidth', False):
w = ui.termwidth()
else:
w = hgutil.termwidth()
bits = (r.revnum, r.author, msg)
ui.status(('[r%d] %s: %s' % bits)[:w] + '\n')
prog.value = r.revnum - start
meta.save_tbdelta(tbdelta)
close = pullfuns[have_replay](ui, meta, svn, r,
tbdelta, firstrun)
meta.committags(r, close)
for branch, parent in close.iteritems():
if parent in (None, node.nullid):
continue
meta.delbranch(branch, parent, r)
meta.save()
converted = True
firstrun = False
except svnwrap.SubversionRepoCanNotReplay as e:
ui.status('%s\n' % e.message)
stupidmod.print_your_svn_is_old_message(ui)
have_replay = False
except svnwrap.SubversionException as e:
if (e.args[1] == svnwrap.ERR_RA_DAV_REQUEST_FAILED
and '502' in str(e)
and tries < 3):
tries += 1
ui.status('Got a 502, retrying (%s)\n' % tries)
else:
ui.traceback()
raise hgutil.Abort(*e.args)
lastpulled = r.revnum
continue
tbdelta = meta.update_branch_tag_map_for_rev(r)
# got a 502? Try more than once!
tries = 0
converted = False
while not converted:
try:
msg = meta.getmessage(r).strip()
if msg:
msg = [s.strip() for s in msg.splitlines() if s][0]
if getattr(ui, 'termwidth', False):
w = ui.termwidth()
else:
w = hgutil.termwidth()
bits = (r.revnum, r.author, msg)
ui.status(('[r%d] %s: %s' % bits)[:w] + '\n')
ui.progress('pull', r.revnum - start, total=total)
meta.save_tbdelta(tbdelta)
close = pullfuns[have_replay](ui, meta, svn, r, tbdelta,
firstrun)
meta.committags(r, close)
for branch, parent in close.iteritems():
if parent in (None, node.nullid):
continue
meta.delbranch(branch, parent, r)
meta.save()
converted = True
firstrun = False
except svnwrap.SubversionRepoCanNotReplay, e: # pragma: no cover
ui.status('%s\n' % e.message)
stupidmod.print_your_svn_is_old_message(ui)
have_replay = False
except svnwrap.SubversionException, e: # pragma: no cover
if (e.args[1] == svnwrap.ERR_RA_DAV_REQUEST_FAILED
and '502' in str(e)
and tries < 3):
tries += 1
ui.status('Got a 502, retrying (%s)\n' % tries)
else:
ui.traceback()
raise hgutil.Abort(*e.args)
lastpulled = r.revnum
except KeyboardInterrupt:
ui.traceback()
finally:
if total is not None:
ui.progress('pull', None, total=total)
util.swap_out_encoding(old_encoding)
if lastpulled is not None: