convert: use new-style progress bars

Reviewed By: quark-zju

Differential Revision: D7329501

fbshipit-source-id: 5312f905b513200904c79acbdb1c7b17968a8aba
This commit is contained in:
Mark Thomas 2018-03-21 13:41:26 -07:00 committed by Saurabh Singh
parent af359e3856
commit eb318ffa63
4 changed files with 135 additions and 131 deletions

View File

@ -15,6 +15,7 @@ from mercurial import (
encoding,
error,
hg,
progress,
scmutil,
util,
)
@ -53,7 +54,7 @@ svn_source = subversion.svn_source
orig_encoding = 'ascii'
def recode(s):
if isinstance(s, unicode):
if isinstance(s, unicode): # noqa
return s.encode(orig_encoding, 'replace')
else:
return s.decode('utf-8').encode(orig_encoding, 'replace')
@ -137,16 +138,14 @@ def convertsink(ui, path, type):
raise error.Abort(_('%s: unknown repository type') % path)
class progresssource(object):
def __init__(self, ui, source, filecount):
self.ui = ui
def __init__(self, source, prog):
self.source = source
self.filecount = filecount
self.prog = prog
self.retrieved = 0
def getfile(self, file, rev):
self.retrieved += 1
self.ui.progress(_('getting files'), self.retrieved,
item=file, total=self.filecount, unit=_('files'))
self.prog.value = (self.retrieved, file)
return self.source.getfile(file, rev)
def targetfilebelongstosource(self, targetfilename):
@ -155,9 +154,6 @@ class progresssource(object):
def lookuprev(self, rev):
return self.source.lookuprev(rev)
def close(self):
self.ui.progress(_('getting files'), None)
class converter(object):
def __init__(self, ui, source, dest, revmapfile, opts):
@ -236,23 +232,23 @@ class converter(object):
known = set()
parents = {}
numcommits = self.source.numcommits()
while visit:
n = visit.pop(0)
if n in known:
continue
if n in self.map:
m = self.map[n]
if m == SKIPREV or self.dest.hascommitfrommap(m):
with progress.bar(self.ui, _('scanning'), _('revisions'),
numcommits) as prog:
while visit:
n = visit.pop(0)
if n in known:
continue
known.add(n)
self.ui.progress(_('scanning'), len(known), unit=_('revisions'),
total=numcommits)
commit = self.cachecommit(n)
parents[n] = []
for p in commit.parents:
parents[n].append(p)
visit.append(p)
self.ui.progress(_('scanning'), None)
if n in self.map:
m = self.map[n]
if m == SKIPREV or self.dest.hascommitfrommap(m):
continue
known.add(n)
prog.value = len(known)
commit = self.cachecommit(n)
parents[n] = []
for p in commit.parents:
parents[n].append(p)
visit.append(p)
return parents
@ -478,17 +474,19 @@ class converter(object):
if len(pbranches) != 2:
cleanp2 = set()
if len(parents) < 3:
source = progresssource(self.ui, self.source, len(files))
sourcelength = len(files)
else:
# For an octopus merge, we end up traversing the list of
# changed files N-1 times. This tweak to the number of
# files makes it so the progress bar doesn't overflow
# itself.
source = progresssource(self.ui, self.source,
len(files) * (len(parents) - 1))
newnode = self.dest.putcommit(files, copies, parents, commit,
source, self.map, full, cleanp2)
source.close()
sourcelength = len(files) * (len(parents) - 1)
with progress.bar(self.ui, _('getting files'), _('files'),
sourcelength) as prog:
source = progresssource(self.source, prog)
newnode = self.dest.putcommit(files, copies, parents, commit,
source, self.map, full, cleanp2)
self.source.converted(rev, newnode)
self.map[rev] = newnode
@ -507,20 +505,20 @@ class converter(object):
c = None
self.ui.status(_("converting...\n"))
for i, c in enumerate(t):
num -= 1
desc = self.commitcache[c].desc
if "\n" in desc:
desc = desc.splitlines()[0]
# convert log message to local encoding without using
# tolocal() because the encoding.encoding convert()
# uses is 'utf-8'
self.ui.status("%d %s\n" % (num, recode(desc)))
self.ui.note(_("source: %s\n") % recode(c))
self.ui.progress(_('converting'), i, unit=_('revisions'),
total=len(t))
self.copy(c)
self.ui.progress(_('converting'), None)
with progress.bar(self.ui, _('converting'), _('revisions'),
len(t)) as prog:
for i, c in enumerate(t):
num -= 1
desc = self.commitcache[c].desc
if "\n" in desc:
desc = desc.splitlines()[0]
# convert log message to local encoding without using
# tolocal() because the encoding.encoding convert()
# uses is 'utf-8'
self.ui.status("%d %s\n" % (num, recode(desc)))
self.ui.note(_("source: %s\n") % recode(c))
prog.value = i
self.copy(c)
if not self.ui.configbool('convert', 'skiptags'):
tags = self.source.gettags()

View File

@ -12,6 +12,7 @@ from mercurial.i18n import _
from mercurial import (
encoding,
error,
progress,
pycompat,
util,
vfs as vfsmod,
@ -745,95 +746,97 @@ class svn_source(converter_source):
self.module = new_module
self.reparent(self.module)
for i, (path, ent) in enumerate(paths):
self.ui.progress(_('scanning paths'), i, item=path,
total=len(paths), unit=_('paths'))
entrypath = self.getrelpath(path)
with progress.bar(self.ui, _('scanning paths'), _('paths'),
len(paths)) as prog:
for i, (path, ent) in enumerate(paths):
prog.value = (i, path)
entrypath = self.getrelpath(path)
kind = self._checkpath(entrypath, revnum)
if kind == svn.core.svn_node_file:
changed.add(self.recode(entrypath))
if not ent.copyfrom_path or not parents:
continue
# Copy sources not in parent revisions cannot be
# represented, ignore their origin for now
pmodule, prevnum = revsplit(parents[0])[1:]
if ent.copyfrom_rev < prevnum:
continue
copyfrom_path = self.getrelpath(ent.copyfrom_path, pmodule)
if not copyfrom_path:
continue
self.ui.debug("copied to %s from %s@%s\n" %
(entrypath, copyfrom_path, ent.copyfrom_rev))
copies[self.recode(entrypath)] = self.recode(copyfrom_path)
elif kind == 0: # gone, but had better be a deleted *file*
self.ui.debug("gone from %s\n" % ent.copyfrom_rev)
pmodule, prevnum = revsplit(parents[0])[1:]
parentpath = pmodule + "/" + entrypath
fromkind = self._checkpath(entrypath, prevnum, pmodule)
if fromkind == svn.core.svn_node_file:
removed.add(self.recode(entrypath))
elif fromkind == svn.core.svn_node_dir:
oroot = parentpath.strip('/')
nroot = path.strip('/')
children = self._iterfiles(oroot, prevnum)
for childpath in children:
childpath = childpath.replace(oroot, nroot)
childpath = self.getrelpath("/" + childpath, pmodule)
if childpath:
removed.add(self.recode(childpath))
else:
self.ui.debug('unknown path in revision %d: %s\n' % \
(revnum, path))
elif kind == svn.core.svn_node_dir:
if ent.action == 'M':
# If the directory just had a prop change,
# then we shouldn't need to look for its children.
continue
if ent.action == 'R' and parents:
# If a directory is replacing a file, mark the previous
# file as deleted
pmodule, prevnum = revsplit(parents[0])[1:]
pkind = self._checkpath(entrypath, prevnum, pmodule)
if pkind == svn.core.svn_node_file:
removed.add(self.recode(entrypath))
elif pkind == svn.core.svn_node_dir:
# We do not know what files were kept or removed,
# mark them all as changed.
for childpath in self._iterfiles(pmodule, prevnum):
childpath = self.getrelpath("/" + childpath)
if childpath:
changed.add(self.recode(childpath))
for childpath in self._iterfiles(path, revnum):
childpath = self.getrelpath("/" + childpath)
if childpath:
changed.add(self.recode(childpath))
# Handle directory copies
if not ent.copyfrom_path or not parents:
continue
# Copy sources not in parent revisions cannot be
# represented, ignore their origin for now
pmodule, prevnum = revsplit(parents[0])[1:]
if ent.copyfrom_rev < prevnum:
continue
copyfrompath = self.getrelpath(ent.copyfrom_path, pmodule)
if not copyfrompath:
continue
self.ui.debug("mark %s came from %s:%d\n"
% (path, copyfrompath, ent.copyfrom_rev))
children = self._iterfiles(ent.copyfrom_path, ent.copyfrom_rev)
for childpath in children:
childpath = self.getrelpath("/" + childpath, pmodule)
if not childpath:
kind = self._checkpath(entrypath, revnum)
if kind == svn.core.svn_node_file:
changed.add(self.recode(entrypath))
if not ent.copyfrom_path or not parents:
continue
copytopath = path + childpath[len(copyfrompath):]
copytopath = self.getrelpath(copytopath)
copies[self.recode(copytopath)] = self.recode(childpath)
# Copy sources not in parent revisions cannot be
# represented, ignore their origin for now
pmodule, prevnum = revsplit(parents[0])[1:]
if ent.copyfrom_rev < prevnum:
continue
copyfrom_path = self.getrelpath(ent.copyfrom_path, pmodule)
if not copyfrom_path:
continue
self.ui.debug("copied to %s from %s@%s\n" %
(entrypath, copyfrom_path, ent.copyfrom_rev))
copies[self.recode(entrypath)] = self.recode(copyfrom_path)
elif kind == 0: # gone, but had better be a deleted *file*
self.ui.debug("gone from %s\n" % ent.copyfrom_rev)
pmodule, prevnum = revsplit(parents[0])[1:]
parentpath = pmodule + "/" + entrypath
fromkind = self._checkpath(entrypath, prevnum, pmodule)
if fromkind == svn.core.svn_node_file:
removed.add(self.recode(entrypath))
elif fromkind == svn.core.svn_node_dir:
oroot = parentpath.strip('/')
nroot = path.strip('/')
children = self._iterfiles(oroot, prevnum)
for childpath in children:
childpath = childpath.replace(oroot, nroot)
childpath = self.getrelpath("/" + childpath,
pmodule)
if childpath:
removed.add(self.recode(childpath))
else:
self.ui.debug('unknown path in revision %d: %s\n' % \
(revnum, path))
elif kind == svn.core.svn_node_dir:
if ent.action == 'M':
# If the directory just had a prop change,
# then we shouldn't need to look for its children.
continue
if ent.action == 'R' and parents:
# If a directory is replacing a file, mark the previous
# file as deleted
pmodule, prevnum = revsplit(parents[0])[1:]
pkind = self._checkpath(entrypath, prevnum, pmodule)
if pkind == svn.core.svn_node_file:
removed.add(self.recode(entrypath))
elif pkind == svn.core.svn_node_dir:
# We do not know what files were kept or removed,
# mark them all as changed.
for childpath in self._iterfiles(pmodule, prevnum):
childpath = self.getrelpath("/" + childpath)
if childpath:
changed.add(self.recode(childpath))
for childpath in self._iterfiles(path, revnum):
childpath = self.getrelpath("/" + childpath)
if childpath:
changed.add(self.recode(childpath))
# Handle directory copies
if not ent.copyfrom_path or not parents:
continue
# Copy sources not in parent revisions cannot be
# represented, ignore their origin for now
pmodule, prevnum = revsplit(parents[0])[1:]
if ent.copyfrom_rev < prevnum:
continue
copyfrompath = self.getrelpath(ent.copyfrom_path, pmodule)
if not copyfrompath:
continue
self.ui.debug("mark %s came from %s:%d\n"
% (path, copyfrompath, ent.copyfrom_rev))
children = self._iterfiles(ent.copyfrom_path,
ent.copyfrom_rev)
for childpath in children:
childpath = self.getrelpath("/" + childpath, pmodule)
if not childpath:
continue
copytopath = path + childpath[len(copyfrompath):]
copytopath = self.getrelpath(copytopath)
copies[self.recode(copytopath)] = self.recode(childpath)
self.ui.progress(_('scanning paths'), None)
changed.update(removed)
return (list(changed), removed, copies)

View File

@ -58,6 +58,7 @@ Remove the directory, then try to replace it with a file (issue754)
$ hg convert --config extensions.progress= --config progress.assume-tty=1 \
> --config progress.delay=0 --config progress.changedelay=0 \
> --config progress.refresh=0 --config progress.width=60 \
> --config progress.debug=1 \
> --config progress.format='topic, bar, number' --datesort git-repo
\r (no-eol) (esc)
scanning [======> ] 1/6\r (no-eol) (esc)
@ -178,6 +179,7 @@ full conversion
> --config extensions.progress= --config progress.assume-tty=1 \
> --config progress.delay=0 --config progress.changedelay=0 \
> --config progress.refresh=0 --config progress.width=60 \
> --config progress.debug=1 \
> --config progress.format='topic, bar, number'
\r (no-eol) (esc)
scanning [===> ] 1/9\r (no-eol) (esc)

View File

@ -161,6 +161,7 @@ Test convert progress bar
> format = topic bar number
> refresh = 0
> width = 60
> debug = true
> EOF
$ hg convert svn-repo hg-progress