diff -r 9e0f3ba4a9c2 -r 1c0c413cccdd mercurial/commands.py --- a/mercurial/commands.py Sat Jul 16 15:13:40 2005 -0800 +++ b/mercurial/commands.py Mon Jul 18 06:54:21 2005 -0800 @@ -36,6 +36,39 @@ for x in args] return args +def matchpats(ui, cwd, pats = [], opts = {}): + head = '' + if opts.get('rootless'): head = '(?:.*/|)' + def reify(name, tail): + if name.startswith('re:'): + return name[3:] + elif name.startswith('glob:'): + return head + util.globre(name[5:], '', tail) + elif name.startswith('path:'): + return '^' + re.escape(name[5:]) + '$' + return head + util.globre(name, '', tail) + cwdsep = cwd + os.sep + def under(fn): + if not cwd or fn.startswith(cwdsep): return True + def matchfn(pats, tail, ifempty = util.always): + if not pats: return ifempty + pat = '(?:%s)' % '|'.join([reify(p, tail) for p in pats]) + if cwd: pat = re.escape(cwd + os.sep) + pat + ui.debug('regexp: %s\n' % pat) + return re.compile(pat).match + patmatch = matchfn(pats, '$') + incmatch = matchfn(opts.get('include'), '(?:/|$)', under) + excmatch = matchfn(opts.get('exclude'), '(?:/|$)', util.never) + return lambda fn: (incmatch(fn) and not excmatch(fn) and + (fn.endswith('/') or patmatch(fn))) + +def walk(repo, pats, opts): + cwd = repo.getcwd() + if cwd: c = len(cwd) + 1 + for fn in repo.walk(match = matchpats(repo.ui, cwd, pats, opts)): + if cwd: yield fn, fn[c:] + else: yield fn, fn + revrangesep = ':' def revrange(ui, repo, revs, revlog=None): @@ -288,9 +321,17 @@ # Commands start here, listed alphabetically -def add(ui, repo, file1, *files): +def add(ui, repo, *pats, **opts): '''add the specified files on the next commit''' - repo.add(relpath(repo, (file1,) + files)) + names = [] + q = dict(zip(pats, pats)) + for abs, rel in walk(repo, pats, opts): + if rel in q or abs in q: + names.append(abs) + elif repo.dirstate.state(abs) == '?': + ui.status('adding %s\n' % rel) + names.append(abs) + repo.add(names) def addremove(ui, repo, *files): """add all new files, delete all missing files""" @@ -669,46 +710,15 @@ def locate(ui, repo, *pats, **opts): """locate files matching specific patterns""" - if [p for p in pats if os.sep in p]: - ui.warn("error: patterns may not contain '%s'\n" % os.sep) - ui.warn("use '-i ' instead\n") - sys.exit(1) - def compile(pats, head='^', tail=os.sep, on_empty=True): - if not pats: - class c: - def match(self, x): - return on_empty - return c() - fnpats = [fnmatch.translate(os.path.normpath(os.path.normcase(p)))[:-1] - for p in pats] - regexp = r'%s(?:%s)%s' % (head, '|'.join(fnpats), tail) - return re.compile(regexp) - exclude = compile(opts['exclude'], on_empty=False) - include = compile(opts['include']) - pat = compile(pats, head='', tail='$') - end = opts['print0'] and '\0' or '\n' - if opts['rev']: - node = repo.manifest.lookup(opts['rev']) - else: - node = repo.manifest.tip() - manifest = repo.manifest.read(node) - cwd = repo.getcwd() - cwd_plus = cwd and (cwd + os.sep) - found = [] - for f in manifest: - f = os.path.normcase(f) - if exclude.match(f) or not(include.match(f) and - f.startswith(cwd_plus) and - pat.match(os.path.basename(f))): - continue + if opts['print0']: end = '\0' + else: end = '\n' + opts['rootless'] = True + for abs, rel in walk(repo, pats, opts): + if repo.dirstate.state(abs) == '?': continue if opts['fullpath']: - f = os.path.join(repo.root, f) - elif cwd: - f = f[len(cwd_plus):] - found.append(f) - found.sort() - for f in found: - ui.write(f, end) + ui.write(os.path.join(repo.root, abs), end) + else: + ui.write(rel, end) def log(ui, repo, f=None, **opts): """show the revision history of the repository or a single file""" @@ -1087,7 +1097,10 @@ # Command options and aliases are listed here, alphabetically table = { - "^add": (add, [], "hg add [files]"), + "^add": (add, + [('I', 'include', [], 'include path in search'), + ('X', 'exclude', [], 'exclude path from search')], + "hg add [options] [files]"), "addremove": (addremove, [], "hg addremove [files]"), "^annotate": (annotate, @@ -1139,9 +1152,9 @@ (locate, [('0', 'print0', None, 'end records with NUL'), ('f', 'fullpath', None, 'print complete paths'), - ('i', 'include', [], 'include path in search'), + ('I', 'include', [], 'include path in search'), ('r', 'rev', '', 'revision'), - ('x', 'exclude', [], 'exclude path from search')], + ('X', 'exclude', [], 'exclude path from search')], 'hg locate [options] [files]'), "^log|history": (log,