mercurial/ignore.py
author Martin Geisler <mg@lazybytes.net>
Wed, 10 Jun 2009 01:09:21 +0200
changeset 8774 dbb258564651
parent 8567 fea40a677d43
child 9091 79a886bcf461
permissions -rw-r--r--
hg.1: simplify synopsis Now that arguments can be mixed with options we can simplify the synopsis considerably. Also, highlighting the command name in bold (instead of italics) seem to be the standard convention.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
4609
b43f17691ae6 dirstate: move ignore to its own file
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     1
# ignore.py - ignored file handling for mercurial
b43f17691ae6 dirstate: move ignore to its own file
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     2
#
b43f17691ae6 dirstate: move ignore to its own file
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     3
# Copyright 2007 Matt Mackall <mpm@selenic.com>
b43f17691ae6 dirstate: move ignore to its own file
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     4
#
8225
46293a0c7e9f updated license to be explicit about GPL version 2
Martin Geisler <mg@lazybytes.net>
parents: 7622
diff changeset
     5
# This software may be used and distributed according to the terms of the
46293a0c7e9f updated license to be explicit about GPL version 2
Martin Geisler <mg@lazybytes.net>
parents: 7622
diff changeset
     6
# GNU General Public License version 2, incorporated herein by reference.
4609
b43f17691ae6 dirstate: move ignore to its own file
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     7
b43f17691ae6 dirstate: move ignore to its own file
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     8
from i18n import _
8566
744d6322b05b match: change all users of util.matcher to match.match
Matt Mackall <mpm@selenic.com>
parents: 8312
diff changeset
     9
import util, match
8312
b87a50b7125c separate import lines from mercurial and general python modules
Simon Heimberg <simohe@besonet.ch>
parents: 8225
diff changeset
    10
import re
5640
04c76f296ad6 ignore: fix up comment parsing
Matt Mackall <mpm@selenic.com>
parents: 5271
diff changeset
    11
04c76f296ad6 ignore: fix up comment parsing
Matt Mackall <mpm@selenic.com>
parents: 5271
diff changeset
    12
_commentre = None
4609
b43f17691ae6 dirstate: move ignore to its own file
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    13
b43f17691ae6 dirstate: move ignore to its own file
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    14
def _parselines(fp):
b43f17691ae6 dirstate: move ignore to its own file
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    15
    for line in fp:
5640
04c76f296ad6 ignore: fix up comment parsing
Matt Mackall <mpm@selenic.com>
parents: 5271
diff changeset
    16
        if "#" in line:
04c76f296ad6 ignore: fix up comment parsing
Matt Mackall <mpm@selenic.com>
parents: 5271
diff changeset
    17
            global _commentre
04c76f296ad6 ignore: fix up comment parsing
Matt Mackall <mpm@selenic.com>
parents: 5271
diff changeset
    18
            if not _commentre:
04c76f296ad6 ignore: fix up comment parsing
Matt Mackall <mpm@selenic.com>
parents: 5271
diff changeset
    19
                _commentre = re.compile(r'((^|[^\\])(\\\\)*)#.*')
04c76f296ad6 ignore: fix up comment parsing
Matt Mackall <mpm@selenic.com>
parents: 5271
diff changeset
    20
            # remove comments prefixed by an even number of escapes
04c76f296ad6 ignore: fix up comment parsing
Matt Mackall <mpm@selenic.com>
parents: 5271
diff changeset
    21
            line = _commentre.sub(r'\1', line)
04c76f296ad6 ignore: fix up comment parsing
Matt Mackall <mpm@selenic.com>
parents: 5271
diff changeset
    22
            # fixup properly escaped comments that survived the above
04c76f296ad6 ignore: fix up comment parsing
Matt Mackall <mpm@selenic.com>
parents: 5271
diff changeset
    23
            line = line.replace("\\#", "#")
04c76f296ad6 ignore: fix up comment parsing
Matt Mackall <mpm@selenic.com>
parents: 5271
diff changeset
    24
        line = line.rstrip()
4609
b43f17691ae6 dirstate: move ignore to its own file
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    25
        if line:
b43f17691ae6 dirstate: move ignore to its own file
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    26
            yield line
b43f17691ae6 dirstate: move ignore to its own file
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    27
b43f17691ae6 dirstate: move ignore to its own file
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    28
def ignore(root, files, warn):
b43f17691ae6 dirstate: move ignore to its own file
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    29
    '''return the contents of .hgignore files as a list of patterns.
b43f17691ae6 dirstate: move ignore to its own file
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    30
b43f17691ae6 dirstate: move ignore to its own file
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    31
    the files parsed for patterns include:
b43f17691ae6 dirstate: move ignore to its own file
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    32
    .hgignore in the repository root
b43f17691ae6 dirstate: move ignore to its own file
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    33
    any additional files specified in the [ui] section of ~/.hgrc
b43f17691ae6 dirstate: move ignore to its own file
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    34
b43f17691ae6 dirstate: move ignore to its own file
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    35
    trailing white space is dropped.
b43f17691ae6 dirstate: move ignore to its own file
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    36
    the escape character is backslash.
b43f17691ae6 dirstate: move ignore to its own file
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    37
    comments start with #.
b43f17691ae6 dirstate: move ignore to its own file
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    38
    empty lines are skipped.
b43f17691ae6 dirstate: move ignore to its own file
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    39
b43f17691ae6 dirstate: move ignore to its own file
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    40
    lines can be of the following formats:
b43f17691ae6 dirstate: move ignore to its own file
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    41
b43f17691ae6 dirstate: move ignore to its own file
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    42
    syntax: regexp # defaults following lines to non-rooted regexps
b43f17691ae6 dirstate: move ignore to its own file
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    43
    syntax: glob   # defaults following lines to non-rooted globs
b43f17691ae6 dirstate: move ignore to its own file
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    44
    re:pattern     # non-rooted regular expression
b43f17691ae6 dirstate: move ignore to its own file
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    45
    glob:pattern   # non-rooted glob
b43f17691ae6 dirstate: move ignore to its own file
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    46
    pattern        # pattern of the current default type'''
b43f17691ae6 dirstate: move ignore to its own file
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    47
b43f17691ae6 dirstate: move ignore to its own file
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    48
    syntaxes = {'re': 'relre:', 'regexp': 'relre:', 'glob': 'relglob:'}
b43f17691ae6 dirstate: move ignore to its own file
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    49
    pats = {}
b43f17691ae6 dirstate: move ignore to its own file
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    50
    for f in files:
b43f17691ae6 dirstate: move ignore to its own file
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    51
        try:
b43f17691ae6 dirstate: move ignore to its own file
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    52
            pats[f] = []
b43f17691ae6 dirstate: move ignore to its own file
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    53
            fp = open(f)
b43f17691ae6 dirstate: move ignore to its own file
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    54
            syntax = 'relre:'
b43f17691ae6 dirstate: move ignore to its own file
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    55
            for line in _parselines(fp):
b43f17691ae6 dirstate: move ignore to its own file
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    56
                if line.startswith('syntax:'):
b43f17691ae6 dirstate: move ignore to its own file
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    57
                    s = line[7:].strip()
b43f17691ae6 dirstate: move ignore to its own file
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    58
                    try:
b43f17691ae6 dirstate: move ignore to its own file
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    59
                        syntax = syntaxes[s]
b43f17691ae6 dirstate: move ignore to its own file
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    60
                    except KeyError:
b43f17691ae6 dirstate: move ignore to its own file
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    61
                        warn(_("%s: ignoring invalid syntax '%s'\n") % (f, s))
b43f17691ae6 dirstate: move ignore to its own file
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    62
                    continue
b43f17691ae6 dirstate: move ignore to its own file
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    63
                pat = syntax + line
7622
4dd7b28003d2 use dict.iteritems() rather than dict.items()
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5640
diff changeset
    64
                for s, rels in syntaxes.iteritems():
5029
ac97e065cfc7 Fix re: and glob: patterns in .hgignore (reported by Brad Schick)
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4609
diff changeset
    65
                    if line.startswith(rels):
4609
b43f17691ae6 dirstate: move ignore to its own file
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    66
                        pat = line
b43f17691ae6 dirstate: move ignore to its own file
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    67
                        break
5029
ac97e065cfc7 Fix re: and glob: patterns in .hgignore (reported by Brad Schick)
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4609
diff changeset
    68
                    elif line.startswith(s+':'):
ac97e065cfc7 Fix re: and glob: patterns in .hgignore (reported by Brad Schick)
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4609
diff changeset
    69
                        pat = rels + line[len(s)+1:]
ac97e065cfc7 Fix re: and glob: patterns in .hgignore (reported by Brad Schick)
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4609
diff changeset
    70
                        break
4609
b43f17691ae6 dirstate: move ignore to its own file
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    71
                pats[f].append(pat)
b43f17691ae6 dirstate: move ignore to its own file
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    72
        except IOError, inst:
b43f17691ae6 dirstate: move ignore to its own file
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    73
            if f != files[0]:
b43f17691ae6 dirstate: move ignore to its own file
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    74
                warn(_("skipping unreadable ignore file '%s': %s\n") %
b43f17691ae6 dirstate: move ignore to its own file
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    75
                     (f, inst.strerror))
b43f17691ae6 dirstate: move ignore to its own file
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    76
b43f17691ae6 dirstate: move ignore to its own file
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    77
    allpats = []
b43f17691ae6 dirstate: move ignore to its own file
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    78
    [allpats.extend(patlist) for patlist in pats.values()]
b43f17691ae6 dirstate: move ignore to its own file
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    79
    if not allpats:
b43f17691ae6 dirstate: move ignore to its own file
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    80
        return util.never
b43f17691ae6 dirstate: move ignore to its own file
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    81
b43f17691ae6 dirstate: move ignore to its own file
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    82
    try:
8567
fea40a677d43 match: add some default args
Matt Mackall <mpm@selenic.com>
parents: 8566
diff changeset
    83
        ignorefunc = match.match(root, '', [], allpats)
4609
b43f17691ae6 dirstate: move ignore to its own file
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    84
    except util.Abort:
b43f17691ae6 dirstate: move ignore to its own file
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    85
        # Re-raise an exception where the src is the right file
7622
4dd7b28003d2 use dict.iteritems() rather than dict.items()
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5640
diff changeset
    86
        for f, patlist in pats.iteritems():
8566
744d6322b05b match: change all users of util.matcher to match.match
Matt Mackall <mpm@selenic.com>
parents: 8312
diff changeset
    87
            try:
8567
fea40a677d43 match: add some default args
Matt Mackall <mpm@selenic.com>
parents: 8566
diff changeset
    88
                match.match(root, '', [], patlist)
8566
744d6322b05b match: change all users of util.matcher to match.match
Matt Mackall <mpm@selenic.com>
parents: 8312
diff changeset
    89
            except util.Abort, inst:
744d6322b05b match: change all users of util.matcher to match.match
Matt Mackall <mpm@selenic.com>
parents: 8312
diff changeset
    90
                raise util.Abort('%s: %s' % (f, inst[0]))
4609
b43f17691ae6 dirstate: move ignore to its own file
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    91
b43f17691ae6 dirstate: move ignore to its own file
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    92
    return ignorefunc