mercurial/commands.py
changeset 724 1c0c413cccdd
parent 723 9e0f3ba4a9c2
child 725 c6b912f8b5b2
equal deleted inserted replaced
723:9e0f3ba4a9c2 724:1c0c413cccdd
    33     cwd = repo.getcwd()
    33     cwd = repo.getcwd()
    34     if cwd:
    34     if cwd:
    35         return [util.pconvert(os.path.normpath(os.path.join(cwd, x)))
    35         return [util.pconvert(os.path.normpath(os.path.join(cwd, x)))
    36                 for x in args]
    36                 for x in args]
    37     return args
    37     return args
       
    38 
       
    39 def matchpats(ui, cwd, pats = [], opts = {}):
       
    40     head = ''
       
    41     if opts.get('rootless'): head = '(?:.*/|)'
       
    42     def reify(name, tail):
       
    43         if name.startswith('re:'):
       
    44             return name[3:]
       
    45         elif name.startswith('glob:'):
       
    46             return head + util.globre(name[5:], '', tail)
       
    47         elif name.startswith('path:'):
       
    48             return '^' + re.escape(name[5:]) + '$'
       
    49         return head + util.globre(name, '', tail)
       
    50     cwdsep = cwd + os.sep
       
    51     def under(fn):
       
    52         if not cwd or fn.startswith(cwdsep): return True
       
    53     def matchfn(pats, tail, ifempty = util.always):
       
    54         if not pats: return ifempty
       
    55         pat = '(?:%s)' % '|'.join([reify(p, tail) for p in pats])
       
    56         if cwd: pat = re.escape(cwd + os.sep) + pat
       
    57         ui.debug('regexp: %s\n' % pat)
       
    58         return re.compile(pat).match
       
    59     patmatch = matchfn(pats, '$')
       
    60     incmatch = matchfn(opts.get('include'), '(?:/|$)', under)
       
    61     excmatch = matchfn(opts.get('exclude'), '(?:/|$)', util.never)
       
    62     return lambda fn: (incmatch(fn) and not excmatch(fn) and
       
    63                        (fn.endswith('/') or patmatch(fn)))
       
    64 
       
    65 def walk(repo, pats, opts):
       
    66     cwd = repo.getcwd()
       
    67     if cwd: c = len(cwd) + 1
       
    68     for fn in repo.walk(match = matchpats(repo.ui, cwd, pats, opts)):
       
    69         if cwd: yield fn, fn[c:]
       
    70         else: yield fn, fn
    38 
    71 
    39 revrangesep = ':'
    72 revrangesep = ':'
    40 
    73 
    41 def revrange(ui, repo, revs, revlog=None):
    74 def revrange(ui, repo, revs, revlog=None):
    42     if revlog is None:
    75     if revlog is None:
   286         for f in fns:
   319         for f in fns:
   287             ui.write(' %-*s   %s\n' % (m, f, h[f]))
   320             ui.write(' %-*s   %s\n' % (m, f, h[f]))
   288 
   321 
   289 # Commands start here, listed alphabetically
   322 # Commands start here, listed alphabetically
   290 
   323 
   291 def add(ui, repo, file1, *files):
   324 def add(ui, repo, *pats, **opts):
   292     '''add the specified files on the next commit'''
   325     '''add the specified files on the next commit'''
   293     repo.add(relpath(repo, (file1,) + files))
   326     names = []
       
   327     q = dict(zip(pats, pats))
       
   328     for abs, rel in walk(repo, pats, opts):
       
   329         if rel in q or abs in q:
       
   330             names.append(abs)
       
   331         elif repo.dirstate.state(abs) == '?':
       
   332             ui.status('adding %s\n' % rel)
       
   333             names.append(abs)
       
   334     repo.add(names)
   294 
   335 
   295 def addremove(ui, repo, *files):
   336 def addremove(ui, repo, *files):
   296     """add all new files, delete all missing files"""
   337     """add all new files, delete all missing files"""
   297     if files:
   338     if files:
   298         files = relpath(repo, files)
   339         files = relpath(repo, files)
   667         sys.exit(1)
   708         sys.exit(1)
   668     hg.repository(ui, ".", create=1)
   709     hg.repository(ui, ".", create=1)
   669 
   710 
   670 def locate(ui, repo, *pats, **opts):
   711 def locate(ui, repo, *pats, **opts):
   671     """locate files matching specific patterns"""
   712     """locate files matching specific patterns"""
   672     if [p for p in pats if os.sep in p]:
   713     if opts['print0']: end = '\0'
   673         ui.warn("error: patterns may not contain '%s'\n" % os.sep)
   714     else: end = '\n'
   674         ui.warn("use '-i <dir>' instead\n")
   715     opts['rootless'] = True
   675         sys.exit(1)
   716     for abs, rel in walk(repo, pats, opts):
   676     def compile(pats, head='^', tail=os.sep, on_empty=True):
   717         if repo.dirstate.state(abs) == '?': continue
   677         if not pats:
       
   678             class c:
       
   679                 def match(self, x):
       
   680                     return on_empty
       
   681             return c()
       
   682         fnpats = [fnmatch.translate(os.path.normpath(os.path.normcase(p)))[:-1]
       
   683                   for p in pats]
       
   684         regexp = r'%s(?:%s)%s' % (head, '|'.join(fnpats), tail)
       
   685         return re.compile(regexp)
       
   686     exclude = compile(opts['exclude'], on_empty=False)
       
   687     include = compile(opts['include'])
       
   688     pat = compile(pats, head='', tail='$')
       
   689     end = opts['print0'] and '\0' or '\n'
       
   690     if opts['rev']:
       
   691         node = repo.manifest.lookup(opts['rev'])
       
   692     else:
       
   693         node = repo.manifest.tip()
       
   694     manifest = repo.manifest.read(node)
       
   695     cwd = repo.getcwd()
       
   696     cwd_plus = cwd and (cwd + os.sep)
       
   697     found = []
       
   698     for f in manifest:
       
   699         f = os.path.normcase(f)
       
   700         if exclude.match(f) or not(include.match(f) and
       
   701                                    f.startswith(cwd_plus) and
       
   702                                    pat.match(os.path.basename(f))):
       
   703             continue
       
   704         if opts['fullpath']:
   718         if opts['fullpath']:
   705             f = os.path.join(repo.root, f)
   719             ui.write(os.path.join(repo.root, abs), end)
   706         elif cwd:
   720         else:
   707             f = f[len(cwd_plus):]
   721             ui.write(rel, end)
   708         found.append(f)
       
   709     found.sort()
       
   710     for f in found:
       
   711         ui.write(f, end)
       
   712 
   722 
   713 def log(ui, repo, f=None, **opts):
   723 def log(ui, repo, f=None, **opts):
   714     """show the revision history of the repository or a single file"""
   724     """show the revision history of the repository or a single file"""
   715     if f:
   725     if f:
   716         files = relpath(repo, [f])
   726         files = relpath(repo, [f])
  1085     return repo.verify()
  1095     return repo.verify()
  1086 
  1096 
  1087 # Command options and aliases are listed here, alphabetically
  1097 # Command options and aliases are listed here, alphabetically
  1088 
  1098 
  1089 table = {
  1099 table = {
  1090     "^add": (add, [], "hg add [files]"),
  1100     "^add": (add,
       
  1101              [('I', 'include', [], 'include path in search'),
       
  1102               ('X', 'exclude', [], 'exclude path from search')],
       
  1103              "hg add [options] [files]"),
  1091     "addremove": (addremove, [], "hg addremove [files]"),
  1104     "addremove": (addremove, [], "hg addremove [files]"),
  1092     "^annotate":
  1105     "^annotate":
  1093         (annotate,
  1106         (annotate,
  1094          [('r', 'revision', '', 'revision'),
  1107          [('r', 'revision', '', 'revision'),
  1095           ('u', 'user', None, 'show user'),
  1108           ('u', 'user', None, 'show user'),
  1137     "^init": (init, [], 'hg init'),
  1150     "^init": (init, [], 'hg init'),
  1138     "locate":
  1151     "locate":
  1139         (locate,
  1152         (locate,
  1140          [('0', 'print0', None, 'end records with NUL'),
  1153          [('0', 'print0', None, 'end records with NUL'),
  1141           ('f', 'fullpath', None, 'print complete paths'),
  1154           ('f', 'fullpath', None, 'print complete paths'),
  1142           ('i', 'include', [], 'include path in search'),
  1155           ('I', 'include', [], 'include path in search'),
  1143           ('r', 'rev', '', 'revision'),
  1156           ('r', 'rev', '', 'revision'),
  1144           ('x', 'exclude', [], 'exclude path from search')],
  1157           ('X', 'exclude', [], 'exclude path from search')],
  1145          'hg locate [options] [files]'),
  1158          'hg locate [options] [files]'),
  1146     "^log|history":
  1159     "^log|history":
  1147         (log,
  1160         (log,
  1148          [('r', 'rev', [], 'revision'),
  1161          [('r', 'rev', [], 'revision'),
  1149           ('p', 'patch', None, 'show patch')],
  1162           ('p', 'patch', None, 'show patch')],