mirror of
https://github.com/facebook/sapling.git
synced 2024-10-09 00:14:35 +03:00
hgsubversion: use new-style progress bars
Reviewed By: mjpieters Differential Revision: D7329498 fbshipit-source-id: 138dcd425ceb6e8e35c134555bfb07c1680e5674
This commit is contained in:
parent
b46a47be82
commit
50792d83d8
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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:
|
||||
|
Loading…
Reference in New Issue
Block a user