--- a/hgext/mq.py Fri Oct 27 19:24:57 2006 +0200
+++ b/hgext/mq.py Fri Oct 27 23:09:46 2006 +0200
@@ -502,7 +502,7 @@
if opts.get('rev'):
if not self.applied:
raise util.Abort(_('no patches applied'))
- revs = [int(r) for r in cmdutil.revrange(ui, repo, opts['rev'])]
+ revs = cmdutil.revrange(ui, repo, opts['rev'])
if len(revs) > 1 and revs[0] > revs[1]:
revs.reverse()
for rev in revs:
@@ -1015,9 +1015,9 @@
del mm[mm.index(x)]
dd.append(x)
- m = list(util.unique(mm))
- r = list(util.unique(dd))
- a = list(util.unique(aa))
+ m = util.unique(mm)
+ r = util.unique(dd)
+ a = util.unique(aa)
filelist = filter(matchfn, util.unique(m + r + a))
if opts.get('git'):
self.diffopts().git = True
@@ -1276,7 +1276,7 @@
if files:
raise util.Abort(_('option "-r" not valid when importing '
'files'))
- rev = [int(r) for r in cmdutil.revrange(self.ui, repo, rev)]
+ rev = cmdutil.revrange(self.ui, repo, rev)
rev.sort(lambda x, y: cmp(y, x))
if (len(files) > 1 or len(rev) > 1) and patchname:
raise util.Abort(_('option "-n" not valid when importing multiple '
--- a/mercurial/cmdutil.py Fri Oct 27 19:24:57 2006 +0200
+++ b/mercurial/cmdutil.py Fri Oct 27 23:09:46 2006 +0200
@@ -13,43 +13,25 @@
revrangesep = ':'
-def revfix(repo, val, defval):
- '''turn user-level id of changeset into rev number.
- user-level id can be tag, changeset, rev number, or negative rev
- number relative to number of revs (-1 is tip, etc).'''
- if not val:
- return defval
- try:
- num = int(val)
- if str(num) != val:
- raise ValueError
- if num < 0:
- num += repo.changelog.count()
- if num < 0:
- num = 0
- elif num >= repo.changelog.count():
- raise ValueError
- except ValueError:
- try:
- num = repo.changelog.rev(repo.lookup(val))
- except KeyError:
- raise util.Abort(_('invalid revision identifier %s') % val)
- return num
-
def revpair(ui, repo, revs):
'''return pair of nodes, given list of revisions. second item can
be None, meaning use working dir.'''
+
+ def revfix(repo, val, defval):
+ if not val and val != 0:
+ val = defval
+ return repo.lookup(val)
+
if not revs:
return repo.dirstate.parents()[0], None
end = None
if len(revs) == 1:
- start = revs[0]
- if revrangesep in start:
- start, end = start.split(revrangesep, 1)
+ if revrangesep in revs[0]:
+ start, end = revs[0].split(revrangesep, 1)
start = revfix(repo, start, 0)
end = revfix(repo, end, repo.changelog.count() - 1)
else:
- start = revfix(repo, start, None)
+ start = revfix(repo, revs[0], None)
elif len(revs) == 2:
if revrangesep in revs[0] or revrangesep in revs[1]:
raise util.Abort(_('too many revisions specified'))
@@ -57,12 +39,17 @@
end = revfix(repo, revs[1], None)
else:
raise util.Abort(_('too many revisions specified'))
- if end is not None: end = repo.lookup(str(end))
- return repo.lookup(str(start)), end
+ return start, end
def revrange(ui, repo, revs):
"""Yield revision as strings from a list of revision specifications."""
- seen = {}
+
+ def revfix(repo, val, defval):
+ if not val and val != 0:
+ return defval
+ return repo.changelog.rev(repo.lookup(val))
+
+ seen, l = {}, []
for spec in revs:
if revrangesep in spec:
start, end = spec.split(revrangesep, 1)
@@ -73,13 +60,15 @@
if rev in seen:
continue
seen[rev] = 1
- yield str(rev)
+ l.append(rev)
else:
rev = revfix(repo, spec, None)
if rev in seen:
continue
seen[rev] = 1
- yield str(rev)
+ l.append(rev)
+
+ return l
def make_filename(repo, pat, node,
total=None, seqno=None, revwidth=None, pathname=None):
@@ -149,19 +138,12 @@
return util.cmdmatcher(repo.root, cwd, pats or ['.'], opts.get('include'),
opts.get('exclude'), head)
-def makewalk(repo, pats=[], opts={}, node=None, head='', badmatch=None):
+def walk(repo, pats=[], opts={}, node=None, head='', badmatch=None):
files, matchfn, anypats = matchpats(repo, pats, opts, head)
- exact = dict(zip(files, files))
- def walk():
- for src, fn in repo.walk(node=node, files=files, match=matchfn,
- badmatch=badmatch):
- yield src, fn, util.pathto(repo.getcwd(), fn), fn in exact
- return files, matchfn, walk()
-
-def walk(repo, pats=[], opts={}, node=None, head='', badmatch=None):
- files, matchfn, results = makewalk(repo, pats, opts, node, head, badmatch)
- for r in results:
- yield r
+ exact = dict.fromkeys(files)
+ for src, fn in repo.walk(node=node, files=files, match=matchfn,
+ badmatch=badmatch):
+ yield src, fn, util.pathto(repo.getcwd(), fn), fn in exact
def findrenames(repo, added=None, removed=None, threshold=0.5):
if added is None or removed is None:
--- a/mercurial/commands.py Fri Oct 27 19:24:57 2006 +0200
+++ b/mercurial/commands.py Fri Oct 27 23:09:46 2006 +0200
@@ -50,7 +50,7 @@
(logfile, inst.strerror))
return message
-def walkchangerevs(ui, repo, pats, opts):
+def walkchangerevs(ui, repo, pats, change, opts):
'''Iterate over files and the revs they changed in.
Callers most commonly need to iterate backwards over the history
@@ -61,10 +61,8 @@
window, we first walk forwards to gather data, then in the desired
order (usually backwards) to display it.
- This function returns an (iterator, getchange, matchfn) tuple. The
- getchange function returns the changelog entry for a numeric
- revision. The iterator yields 3-tuples. They will be of one of
- the following forms:
+ This function returns an (iterator, matchfn) tuple. The iterator
+ yields 3-tuples. They will be of one of the following forms:
"window", incrementing, lastrev: stepping through a window,
positive if walking forwards through revs, last rev in the
@@ -91,32 +89,24 @@
if windowsize < sizelimit:
windowsize *= 2
-
files, matchfn, anypats = cmdutil.matchpats(repo, pats, opts)
follow = opts.get('follow') or opts.get('follow_first')
if repo.changelog.count() == 0:
- return [], False, matchfn
+ return [], matchfn
if follow:
defrange = '%s:0' % repo.changectx().rev()
else:
defrange = 'tip:0'
- revs = map(int, cmdutil.revrange(ui, repo, opts['rev'] or [defrange]))
+ revs = cmdutil.revrange(ui, repo, opts['rev'] or [defrange])
wanted = {}
slowpath = anypats
fncache = {}
- chcache = {}
- def getchange(rev):
- ch = chcache.get(rev)
- if ch is None:
- chcache[rev] = ch = repo.changelog.read(repo.lookup(str(rev)))
- return ch
-
if not slowpath and not files:
# No files, no patterns. Display all revs.
- wanted = dict(zip(revs, revs))
+ wanted = dict.fromkeys(revs)
copies = []
if not slowpath:
# Only files, no patterns. Check the history of each file.
@@ -169,7 +159,7 @@
def changerevgen():
for i, window in increasing_windows(repo.changelog.count()-1, -1):
for j in xrange(i - window, i + 1):
- yield j, getchange(j)[3]
+ yield j, change(j)[3]
for rev, changefiles in changerevgen():
matches = filter(matchfn, changefiles)
@@ -220,7 +210,7 @@
ff = followfilter()
stop = min(revs[0], revs[-1])
for x in xrange(rev, stop-1, -1):
- if ff.match(x) and wanted.has_key(x):
+ if ff.match(x) and x in wanted:
del wanted[x]
def iterate():
@@ -240,11 +230,11 @@
srevs = list(nrevs)
srevs.sort()
for rev in srevs:
- fns = fncache.get(rev) or filter(matchfn, getchange(rev)[3])
+ fns = fncache.get(rev) or filter(matchfn, change(rev)[3])
yield 'add', rev, fns
for rev in nrevs:
yield 'iter', rev, None
- return iterate(), getchange, matchfn
+ return iterate(), matchfn
def write_bundle(cg, filename=None, compress=True):
"""Write a bundle file and return its filename.
@@ -298,13 +288,6 @@
if cleanup is not None:
os.unlink(cleanup)
-def trimuser(ui, name, rev, revcache):
- """trim the name of the user who committed a change"""
- user = revcache.get(rev)
- if user is None:
- user = revcache[rev] = ui.shortuser(name)
- return user
-
class changeset_printer(object):
'''show changeset information when templating not requested.'''
@@ -1383,7 +1366,7 @@
"""
if not changesets:
raise util.Abort(_("export requires at least one changeset"))
- revs = list(cmdutil.revrange(ui, repo, changesets))
+ revs = cmdutil.revrange(ui, repo, changesets)
if len(revs) > 1:
ui.note(_('exporting patches:\n'))
else:
@@ -1471,29 +1454,23 @@
yield ('+', b[i])
prev = {}
- ucache = {}
def display(fn, rev, states, prevstates):
counts = {'-': 0, '+': 0}
filerevmatches = {}
if incrementing or not opts['all']:
- a, b = prevstates, states
+ a, b, r = prevstates, states, rev
else:
- a, b = states, prevstates
+ a, b, r = states, prevstates, prev.get(fn, -1)
for change, l in difflinestates(a, b):
- if incrementing or not opts['all']:
- r = rev
- else:
- r = prev[fn]
cols = [fn, str(r)]
if opts['line_number']:
cols.append(str(l.linenum))
if opts['all']:
cols.append(change)
if opts['user']:
- cols.append(trimuser(ui, getchange(r)[1], rev,
- ucache))
+ cols.append(ui.shortuser(getchange(r)[1]))
if opts['files_with_matches']:
- c = (fn, rev)
+ c = (fn, r)
if c in filerevmatches:
continue
filerevmatches[c] = 1
@@ -1505,7 +1482,8 @@
fstate = {}
skip = {}
- changeiter, getchange, matchfn = walkchangerevs(ui, repo, pats, opts)
+ getchange = util.cachefunc(lambda r:repo.changectx(r).changeset())
+ changeiter, matchfn = walkchangerevs(ui, repo, pats, getchange, opts)
count = 0
incrementing = False
follow = opts.get('follow')
@@ -1514,8 +1492,7 @@
incrementing = rev
matches.clear()
elif st == 'add':
- change = repo.changelog.read(repo.lookup(str(rev)))
- mf = repo.manifest.read(change[0])
+ mf = repo.changectx(rev).manifest()
matches[rev] = {}
for fn in fns:
if fn in skip:
@@ -1838,7 +1815,8 @@
def __getattr__(self, key):
return getattr(self.ui, key)
- changeiter, getchange, matchfn = walkchangerevs(ui, repo, pats, opts)
+ getchange = util.cachefunc(lambda r:repo.changectx(r).changeset())
+ changeiter, matchfn = walkchangerevs(ui, repo, pats, getchange, opts)
if opts['branches']:
ui.warn(_("the --branches option is deprecated, "
@@ -1855,8 +1833,7 @@
count = 0
if opts['copies'] and opts['rev']:
- endrev = max([int(i)
- for i in cmdutil.revrange(ui, repo, opts['rev'])]) + 1
+ endrev = max(cmdutil.revrange(ui, repo, opts['rev'])) + 1
else:
endrev = repo.changelog.count()
rcache = {}
--- a/mercurial/dirstate.py Fri Oct 27 19:24:57 2006 +0200
+++ b/mercurial/dirstate.py Fri Oct 27 23:09:46 2006 +0200
@@ -25,7 +25,6 @@
self.dirs = None
self.copymap = {}
self.ignorefunc = None
- self.blockignore = False
def wjoin(self, f):
return os.path.join(self.root, f)
@@ -98,8 +97,6 @@
'''default match function used by dirstate and
localrepository. this honours the repository .hgignore file
and any other files specified in the [ui] section of .hgrc.'''
- if self.blockignore:
- return False
if not self.ignorefunc:
ignore = self.hgignore()
allpats = []
@@ -350,45 +347,42 @@
kind))
return False
- def statwalk(self, files=None, match=util.always, dc=None, ignored=False,
+ def walk(self, files=None, match=util.always, badmatch=None):
+ # filter out the stat
+ for src, f, st in self.statwalk(files, match, badmatch=badmatch):
+ yield src, f
+
+ def statwalk(self, files=None, match=util.always, ignored=False,
badmatch=None):
+ '''
+ walk recursively through the directory tree, finding all files
+ matched by the match function
+
+ results are yielded in a tuple (src, filename, st), where src
+ is one of:
+ 'f' the file was found in the directory tree
+ 'm' the file was only in the dirstate and not in the tree
+ 'b' file was not found and matched badmatch
+
+ and st is the stat result if the file was found in the directory.
+ '''
self.lazyread()
# walk all files by default
if not files:
files = [self.root]
- if not dc:
- dc = self.map.copy()
- elif not dc:
+ dc = self.map.copy()
+ else:
+ files = util.unique(files)
dc = self.filterfiles(files)
- def statmatch(file_, stat):
- file_ = util.pconvert(file_)
- if not ignored and file_ not in dc and self.ignore(file_):
+ def imatch(file_):
+ if file_ not in dc and self.ignore(file_):
return False
return match(file_)
- return self.walkhelper(files=files, statmatch=statmatch, dc=dc,
- badmatch=badmatch)
-
- def walk(self, files=None, match=util.always, dc=None, badmatch=None):
- # filter out the stat
- for src, f, st in self.statwalk(files, match, dc, badmatch=badmatch):
- yield src, f
+ if ignored: imatch = match
- # walk recursively through the directory tree, finding all files
- # matched by the statmatch function
- #
- # results are yielded in a tuple (src, filename, st), where src
- # is one of:
- # 'f' the file was found in the directory tree
- # 'm' the file was only in the dirstate and not in the tree
- # and st is the stat result if the file was found in the directory.
- #
- # dc is an optional arg for the current dirstate. dc is not modified
- # directly by this function, but might be modified by your statmatch call.
- #
- def walkhelper(self, files, statmatch, dc, badmatch=None):
# self.root may end with a path separator when self.root == '/'
common_prefix_len = len(self.root)
if not self.root.endswith('/'):
@@ -420,12 +414,12 @@
# don't trip over symlinks
st = os.lstat(p)
if stat.S_ISDIR(st.st_mode):
- ds = os.path.join(nd, f +'/')
- if statmatch(ds, st):
+ ds = util.pconvert(os.path.join(nd, f +'/'))
+ if imatch(ds):
work.append(p)
- if statmatch(np, st) and np in dc:
+ if imatch(np) and np in dc:
yield 'm', np, st
- elif statmatch(np, st):
+ elif imatch(np):
if self.supported_type(np, st):
yield 'f', np, st
elif np in dc:
@@ -438,12 +432,12 @@
# step one, find all files that match our criteria
files.sort()
- for ff in util.unique(files):
+ for ff in files:
+ nf = util.normpath(ff)
f = self.wjoin(ff)
try:
st = os.lstat(f)
except OSError, inst:
- nf = util.normpath(ff)
found = False
for fn in dc:
if nf == fn or (fn.startswith(nf) and fn[len(nf)] == '/'):
@@ -454,7 +448,7 @@
self.ui.warn('%s: %s\n' % (
util.pathto(self.getcwd(), ff),
inst.strerror))
- elif badmatch and badmatch(ff) and statmatch(ff, None):
+ elif badmatch and badmatch(ff) and imatch(nf):
yield 'b', ff, None
continue
if stat.S_ISDIR(st.st_mode):
@@ -464,23 +458,18 @@
for e in sorted_:
yield e
else:
- ff = util.normpath(ff)
- if seen(ff):
- continue
- self.blockignore = True
- if statmatch(ff, st):
+ if not seen(nf) and match(nf):
if self.supported_type(ff, st, verbose=True):
- yield 'f', ff, st
+ yield 'f', nf, st
elif ff in dc:
- yield 'm', ff, st
- self.blockignore = False
+ yield 'm', nf, st
# step two run through anything left in the dc hash and yield
# if we haven't already seen it
ks = dc.keys()
ks.sort()
for k in ks:
- if not seen(k) and (statmatch(k, None)):
+ if not seen(k) and imatch(k):
yield 'm', k, None
def status(self, files=None, match=util.always, list_ignored=False,
--- a/mercurial/localrepo.py Fri Oct 27 19:24:57 2006 +0200
+++ b/mercurial/localrepo.py Fri Oct 27 23:09:46 2006 +0200
@@ -714,6 +714,18 @@
return n
def walk(self, node=None, files=[], match=util.always, badmatch=None):
+ '''
+ walk recursively through the directory tree or a given
+ changeset, finding all files matched by the match
+ function
+
+ results are yielded in a tuple (src, filename), where src
+ is one of:
+ 'f' the file was found in the directory tree
+ 'm' the file was only in the dirstate and not in the tree
+ 'b' file was not found and matched badmatch
+ '''
+
if node:
fdict = dict.fromkeys(files)
for fn in self.manifest.read(self.changelog.read(node)[0]):
--- a/mercurial/util.py Fri Oct 27 19:24:57 2006 +0200
+++ b/mercurial/util.py Fri Oct 27 23:09:46 2006 +0200
@@ -128,10 +128,12 @@
def unique(g):
"""return the uniq elements of iterable g"""
seen = {}
+ l = []
for f in g:
if f not in seen:
seen[f] = 1
- yield f
+ l.append(f)
+ return l
class Abort(Exception):
"""Raised if a command needs to print an error and exit."""
@@ -985,6 +987,9 @@
f = user.find(' ')
if f >= 0:
user = user[:f]
+ f = user.find('.')
+ if f >= 0:
+ user = user[:f]
return user
def walkrepos(path):
--- a/tests/test-grep.out Fri Oct 27 19:24:57 2006 +0200
+++ b/tests/test-grep.out Fri Oct 27 23:09:46 2006 +0200
@@ -9,7 +9,7 @@
port:2:2:+:spam:vaportight
port:2:3:+:spam:import/export
port:1:2:+:eggs:export
-port:0:1:+:eggs:import
+port:0:1:+:spam:import
port:4:import/export
% follow
port:0:import
@@ -22,4 +22,4 @@
port:2:2:+:spam:vaportight
port:2:3:+:spam:import/export
port:1:2:+:eggs:export
-port:0:1:+:eggs:import
+port:0:1:+:spam:import