mercurial/ignore.py
changeset 4610 b43f17691ae6
child 5029 ac97e065cfc7
equal deleted inserted replaced
4609:220211b88656 4610:b43f17691ae6
       
     1 # ignore.py - ignored file handling for mercurial
       
     2 #
       
     3 # Copyright 2007 Matt Mackall <mpm@selenic.com>
       
     4 #
       
     5 # This software may be used and distributed according to the terms
       
     6 # of the GNU General Public License, incorporated herein by reference.
       
     7 
       
     8 from i18n import _
       
     9 import util
       
    10 
       
    11 def _parselines(fp):
       
    12     for line in fp:
       
    13         if not line.endswith('\n'):
       
    14             line += '\n'
       
    15         escape = False
       
    16         for i in xrange(len(line)):
       
    17             if escape: escape = False
       
    18             elif line[i] == '\\': escape = True
       
    19             elif line[i] == '#': break
       
    20         line = line[:i].rstrip()
       
    21         if line:
       
    22             yield line
       
    23 
       
    24 def ignore(root, files, warn):
       
    25     '''return the contents of .hgignore files as a list of patterns.
       
    26 
       
    27     the files parsed for patterns include:
       
    28     .hgignore in the repository root
       
    29     any additional files specified in the [ui] section of ~/.hgrc
       
    30 
       
    31     trailing white space is dropped.
       
    32     the escape character is backslash.
       
    33     comments start with #.
       
    34     empty lines are skipped.
       
    35 
       
    36     lines can be of the following formats:
       
    37 
       
    38     syntax: regexp # defaults following lines to non-rooted regexps
       
    39     syntax: glob   # defaults following lines to non-rooted globs
       
    40     re:pattern     # non-rooted regular expression
       
    41     glob:pattern   # non-rooted glob
       
    42     pattern        # pattern of the current default type'''
       
    43 
       
    44     syntaxes = {'re': 'relre:', 'regexp': 'relre:', 'glob': 'relglob:'}
       
    45     pats = {}
       
    46     for f in files:
       
    47         try:
       
    48             pats[f] = []
       
    49             fp = open(f)
       
    50             syntax = 'relre:'
       
    51             for line in _parselines(fp):
       
    52                 if line.startswith('syntax:'):
       
    53                     s = line[7:].strip()
       
    54                     try:
       
    55                         syntax = syntaxes[s]
       
    56                     except KeyError:
       
    57                         warn(_("%s: ignoring invalid syntax '%s'\n") % (f, s))
       
    58                     continue
       
    59                 pat = syntax + line
       
    60                 for s in syntaxes.values():
       
    61                     if line.startswith(s):
       
    62                         pat = line
       
    63                         break
       
    64                 pats[f].append(pat)
       
    65         except IOError, inst:
       
    66             if f != files[0]:
       
    67                 warn(_("skipping unreadable ignore file '%s': %s\n") %
       
    68                      (f, inst.strerror))
       
    69 
       
    70     allpats = []
       
    71     [allpats.extend(patlist) for patlist in pats.values()]
       
    72     if not allpats:
       
    73         return util.never
       
    74 
       
    75     try:
       
    76         files, ignorefunc, anypats = (
       
    77             util.matcher(root, inc=allpats, src='.hgignore'))
       
    78     except util.Abort:
       
    79         # Re-raise an exception where the src is the right file
       
    80         for f, patlist in pats.items():
       
    81             files, ignorefunc, anypats = (
       
    82                 util.matcher(root, inc=patlist, src=f))
       
    83 
       
    84     return ignorefunc
       
    85 
       
    86 
       
    87     '''default match function used by dirstate and
       
    88     localrepository.  this honours the repository .hgignore file
       
    89     and any other files specified in the [ui] section of .hgrc.'''
       
    90