##// END OF EJS Templates
use untrusted settings in hgweb...
use untrusted settings in hgweb The only exceptions are web.static and web.templates, since they can be used to get any file that is readable by the user running the CGI script. Other options can be (ab)used to increase the use of the cpu (allow_bz2) or of the bandwidth (server.uncompressed), but they're trusted anyway.

File last commit:

r3531:730ca93e default
r3555:88106400 default
Show More
cmdutil.py
215 lines | 7.9 KiB | text/x-python | PythonLexer
Vadim Gelfer
fix comment.
r2957 # cmdutil.py - help for command processing in mercurial
Vadim Gelfer
refactor text diff/patch code....
r2874 #
# Copyright 2005, 2006 Matt Mackall <mpm@selenic.com>
#
# This software may be used and distributed according to the terms
# of the GNU General Public License, incorporated herein by reference.
from demandload import demandload
from node import *
from i18n import gettext as _
Vadim Gelfer
addremove: add -s/--similarity option...
r2958 demandload(globals(), 'mdiff util')
Vadim Gelfer
refactor text diff/patch code....
r2874 demandload(globals(), 'os sys')
Brendan Cully
Move revision parsing into cmdutil.
r3090 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.'''
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)
start = revfix(repo, start, 0)
end = revfix(repo, end, repo.changelog.count() - 1)
else:
start = revfix(repo, start, None)
elif len(revs) == 2:
if revrangesep in revs[0] or revrangesep in revs[1]:
raise util.Abort(_('too many revisions specified'))
start = revfix(repo, revs[0], None)
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
def revrange(ui, repo, revs):
"""Yield revision as strings from a list of revision specifications."""
seen = {}
for spec in revs:
if revrangesep in spec:
start, end = spec.split(revrangesep, 1)
start = revfix(repo, start, 0)
end = revfix(repo, end, repo.changelog.count() - 1)
step = start > end and -1 or 1
for rev in xrange(start, end+step, step):
if rev in seen:
continue
seen[rev] = 1
yield str(rev)
else:
rev = revfix(repo, spec, None)
if rev in seen:
continue
seen[rev] = 1
yield str(rev)
Vadim Gelfer
refactor text diff/patch code....
r2874 def make_filename(repo, pat, node,
total=None, seqno=None, revwidth=None, pathname=None):
node_expander = {
'H': lambda: hex(node),
'R': lambda: str(repo.changelog.rev(node)),
'h': lambda: short(node),
}
expander = {
'%': lambda: '%',
'b': lambda: os.path.basename(repo.root),
}
try:
if node:
expander.update(node_expander)
if node and revwidth is not None:
expander['r'] = (lambda:
str(repo.changelog.rev(node)).zfill(revwidth))
if total is not None:
expander['N'] = lambda: str(total)
if seqno is not None:
expander['n'] = lambda: str(seqno)
if total is not None and seqno is not None:
expander['n'] = lambda:str(seqno).zfill(len(str(total)))
if pathname is not None:
expander['s'] = lambda: os.path.basename(pathname)
expander['d'] = lambda: os.path.dirname(pathname) or '.'
expander['p'] = lambda: pathname
newname = []
patlen = len(pat)
i = 0
while i < patlen:
c = pat[i]
if c == '%':
i += 1
c = pat[i]
c = expander[c]()
newname.append(c)
i += 1
return ''.join(newname)
except KeyError, inst:
Thomas Arendsen Hein
Never apply string formatting to generated errors with util.Abort....
r3072 raise util.Abort(_("invalid format spec '%%%s' in output file name") %
inst.args[0])
Vadim Gelfer
refactor text diff/patch code....
r2874
def make_file(repo, pat, node=None,
total=None, seqno=None, revwidth=None, mode='wb', pathname=None):
if not pat or pat == '-':
return 'w' in mode and sys.stdout or sys.stdin
if hasattr(pat, 'write') and 'w' in mode:
return pat
if hasattr(pat, 'read') and 'r' in mode:
return pat
return open(make_filename(repo, pat, node, total, seqno, revwidth,
pathname),
mode)
Vadim Gelfer
move walk and matchpats from commands to cmdutil.
r2882
def matchpats(repo, pats=[], opts={}, head=''):
cwd = repo.getcwd()
if not pats and cwd:
Vadim Gelfer
cmdutil.matchpats: allow include/exclude to be optional.
r2885 opts['include'] = [os.path.join(cwd, i)
for i in opts.get('include', [])]
opts['exclude'] = [os.path.join(cwd, x)
for x in opts.get('exclude', [])]
Vadim Gelfer
move walk and matchpats from commands to cmdutil.
r2882 cwd = ''
return util.cmdmatcher(repo.root, cwd, pats or ['.'], opts.get('include'),
opts.get('exclude'), head)
Vadim Gelfer
add default values to arguments of walk etc.
r2884 def makewalk(repo, pats=[], opts={}, node=None, head='', badmatch=None):
Vadim Gelfer
move walk and matchpats from commands to cmdutil.
r2882 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()
Vadim Gelfer
add default values to arguments of walk etc.
r2884 def walk(repo, pats=[], opts={}, node=None, head='', badmatch=None):
Vadim Gelfer
move walk and matchpats from commands to cmdutil.
r2882 files, matchfn, results = makewalk(repo, pats, opts, node, head, badmatch)
for r in results:
yield r
Vadim Gelfer
move commands.addremove_lock to cmdutil.addremove
r2883
Vadim Gelfer
addremove: add -s/--similarity option...
r2958 def findrenames(repo, added=None, removed=None, threshold=0.5):
if added is None or removed is None:
added, removed = repo.status()[1:3]
changes = repo.changelog.read(repo.dirstate.parents()[0])
mf = repo.manifest.read(changes[0])
for a in added:
aa = repo.wread(a)
bestscore, bestname = None, None
for r in removed:
rr = repo.file(r).read(mf[r])
delta = mdiff.textdiff(aa, rr)
if len(delta) < len(aa):
myscore = 1.0 - (float(len(delta)) / len(aa))
if bestscore is None or myscore > bestscore:
bestscore, bestname = myscore, r
if bestname and bestscore >= threshold:
yield bestname, a, bestscore
def addremove(repo, pats=[], opts={}, wlock=None, dry_run=None,
similarity=None):
Vadim Gelfer
move commands.addremove_lock to cmdutil.addremove
r2883 if dry_run is None:
dry_run = opts.get('dry_run')
Vadim Gelfer
addremove: add -s/--similarity option...
r2958 if similarity is None:
similarity = float(opts.get('similarity') or 0)
Vadim Gelfer
move commands.addremove_lock to cmdutil.addremove
r2883 add, remove = [], []
Vadim Gelfer
addremove: add -s/--similarity option...
r2958 mapping = {}
Vadim Gelfer
move commands.addremove_lock to cmdutil.addremove
r2883 for src, abs, rel, exact in walk(repo, pats, opts):
if src == 'f' and repo.dirstate.state(abs) == '?':
add.append(abs)
Vadim Gelfer
addremove: add -s/--similarity option...
r2958 mapping[abs] = rel, exact
Vadim Gelfer
move commands.addremove_lock to cmdutil.addremove
r2883 if repo.ui.verbose or not exact:
repo.ui.status(_('adding %s\n') % ((pats and rel) or abs))
if repo.dirstate.state(abs) != 'r' and not os.path.exists(rel):
remove.append(abs)
Vadim Gelfer
addremove: add -s/--similarity option...
r2958 mapping[abs] = rel, exact
Vadim Gelfer
move commands.addremove_lock to cmdutil.addremove
r2883 if repo.ui.verbose or not exact:
repo.ui.status(_('removing %s\n') % ((pats and rel) or abs))
if not dry_run:
repo.add(add, wlock=wlock)
repo.remove(remove, wlock=wlock)
Vadim Gelfer
addremove: add -s/--similarity option...
r2958 if similarity > 0:
for old, new, score in findrenames(repo, add, remove, similarity):
oldrel, oldexact = mapping[old]
newrel, newexact = mapping[new]
if repo.ui.verbose or not oldexact or not newexact:
repo.ui.status(_('recording removal of %s as rename to %s '
'(%d%% similar)\n') %
(oldrel, newrel, score * 100))
if not dry_run:
repo.copy(old, new, wlock=wlock)