##// END OF EJS Templates
ignore: process hgignore files in deterministic order...
Bryan O'Sullivan -
r18089:0127366d default
parent child Browse files
Show More
@@ -1,113 +1,113 b''
1 1 # ignore.py - ignored file handling for mercurial
2 2 #
3 3 # Copyright 2007 Matt Mackall <mpm@selenic.com>
4 4 #
5 5 # This software may be used and distributed according to the terms of the
6 6 # GNU General Public License version 2 or any later version.
7 7
8 8 from i18n import _
9 9 import util, match
10 10 import re
11 11
12 12 _commentre = None
13 13
14 14 def ignorepats(lines):
15 15 '''parse lines (iterable) of .hgignore text, returning a tuple of
16 16 (patterns, parse errors). These patterns should be given to compile()
17 17 to be validated and converted into a match function.'''
18 18 syntaxes = {'re': 'relre:', 'regexp': 'relre:', 'glob': 'relglob:'}
19 19 syntax = 'relre:'
20 20 patterns = []
21 21 warnings = []
22 22
23 23 for line in lines:
24 24 if "#" in line:
25 25 global _commentre
26 26 if not _commentre:
27 27 _commentre = re.compile(r'((^|[^\\])(\\\\)*)#.*')
28 28 # remove comments prefixed by an even number of escapes
29 29 line = _commentre.sub(r'\1', line)
30 30 # fixup properly escaped comments that survived the above
31 31 line = line.replace("\\#", "#")
32 32 line = line.rstrip()
33 33 if not line:
34 34 continue
35 35
36 36 if line.startswith('syntax:'):
37 37 s = line[7:].strip()
38 38 try:
39 39 syntax = syntaxes[s]
40 40 except KeyError:
41 41 warnings.append(_("ignoring invalid syntax '%s'") % s)
42 42 continue
43 43 pat = syntax + line
44 44 for s, rels in syntaxes.iteritems():
45 45 if line.startswith(rels):
46 46 pat = line
47 47 break
48 48 elif line.startswith(s+':'):
49 49 pat = rels + line[len(s) + 1:]
50 50 break
51 51 patterns.append(pat)
52 52
53 53 return patterns, warnings
54 54
55 55 def readpats(root, files, warn):
56 56 '''return a dict mapping ignore-file-name to list-of-patterns'''
57 57
58 58 pats = {}
59 59 for f in files:
60 60 if f in pats:
61 61 continue
62 62 try:
63 63 pats[f] = []
64 64 fp = open(f)
65 65 pats[f], warnings = ignorepats(fp)
66 66 fp.close()
67 67 for warning in warnings:
68 68 warn("%s: %s\n" % (f, warning))
69 69 except IOError, inst:
70 70 if f != files[0]:
71 71 warn(_("skipping unreadable ignore file '%s': %s\n") %
72 72 (f, inst.strerror))
73 return pats
73 return [(f, pats[f]) for f in files if f in pats]
74 74
75 75 def ignore(root, files, warn):
76 76 '''return matcher covering patterns in 'files'.
77 77
78 78 the files parsed for patterns include:
79 79 .hgignore in the repository root
80 80 any additional files specified in the [ui] section of ~/.hgrc
81 81
82 82 trailing white space is dropped.
83 83 the escape character is backslash.
84 84 comments start with #.
85 85 empty lines are skipped.
86 86
87 87 lines can be of the following formats:
88 88
89 89 syntax: regexp # defaults following lines to non-rooted regexps
90 90 syntax: glob # defaults following lines to non-rooted globs
91 91 re:pattern # non-rooted regular expression
92 92 glob:pattern # non-rooted glob
93 93 pattern # pattern of the current default type'''
94 94
95 95 pats = readpats(root, files, warn)
96 96
97 97 allpats = []
98 for patlist in pats.values():
98 for f, patlist in pats:
99 99 allpats.extend(patlist)
100 100 if not allpats:
101 101 return util.never
102 102
103 103 try:
104 104 ignorefunc = match.match(root, '', [], allpats)
105 105 except util.Abort:
106 106 # Re-raise an exception where the src is the right file
107 for f, patlist in pats.iteritems():
107 for f, patlist in pats:
108 108 try:
109 109 match.match(root, '', [], patlist)
110 110 except util.Abort, inst:
111 111 raise util.Abort('%s: %s' % (f, inst[0]))
112 112
113 113 return ignorefunc
General Comments 0
You need to be logged in to leave comments. Login now