30 def getcwd(self): |
30 def getcwd(self): |
31 cwd = os.getcwd() |
31 cwd = os.getcwd() |
32 if cwd == self.root: return '' |
32 if cwd == self.root: return '' |
33 return cwd[len(self.root) + 1:] |
33 return cwd[len(self.root) + 1:] |
34 |
34 |
35 def ignore(self, f): |
35 def hgignore(self): |
|
36 '''return the contents of .hgignore as a list of patterns. |
|
37 |
|
38 trailing white space is dropped. |
|
39 the escape character is backslash. |
|
40 comments start with #. |
|
41 empty lines are skipped. |
|
42 |
|
43 lines can be of the following formats: |
|
44 |
|
45 syntax: regexp # defaults following lines to non-rooted regexps |
|
46 syntax: glob # defaults following lines to non-rooted globs |
|
47 re:pattern # non-rooted regular expression |
|
48 glob:pattern # non-rooted glob |
|
49 pattern # pattern of the current default type''' |
|
50 syntaxes = {'re': 'relre:', 'regexp': 'relre:', 'glob': 'relglob:'} |
|
51 def parselines(fp): |
|
52 for line in fp: |
|
53 escape = False |
|
54 for i in xrange(len(line)): |
|
55 if escape: escape = False |
|
56 elif line[i] == '\\': escape = True |
|
57 elif line[i] == '#': break |
|
58 line = line[:i].rstrip() |
|
59 if line: yield line |
|
60 pats = [] |
|
61 try: |
|
62 fp = open(self.wjoin('.hgignore')) |
|
63 syntax = 'relre:' |
|
64 for line in parselines(fp): |
|
65 if line.startswith('syntax:'): |
|
66 s = line[7:].strip() |
|
67 try: |
|
68 syntax = syntaxes[s] |
|
69 except KeyError: |
|
70 self.ui.warn("ignoring invalid syntax '%s'\n" % s) |
|
71 continue |
|
72 pat = syntax + line |
|
73 for s in syntaxes.values(): |
|
74 if line.startswith(s): |
|
75 pat = line |
|
76 break |
|
77 pats.append(pat) |
|
78 except IOError: pass |
|
79 return pats |
|
80 |
|
81 def ignore(self, fn): |
|
82 '''default match function used by dirstate and localrepository. |
|
83 this honours the .hgignore file, and nothing more.''' |
36 if self.blockignore: |
84 if self.blockignore: |
37 return False |
85 return False |
38 if not self.ignorefunc: |
86 if not self.ignorefunc: |
39 bigpat = [] |
87 files, self.ignorefunc, anypats = util.matcher(self.root, |
40 try: |
88 inc=self.hgignore()) |
41 l = file(self.wjoin(".hgignore")) |
89 return self.ignorefunc(fn) |
42 for pat in l: |
|
43 p = pat.rstrip() |
|
44 if p: |
|
45 try: |
|
46 re.compile(p) |
|
47 except: |
|
48 self.ui.warn("ignoring invalid ignore" |
|
49 + " regular expression '%s'\n" % p) |
|
50 else: |
|
51 bigpat.append(p) |
|
52 except IOError: pass |
|
53 |
|
54 if bigpat: |
|
55 s = "(?:%s)" % (")|(?:".join(bigpat)) |
|
56 r = re.compile(s) |
|
57 self.ignorefunc = r.search |
|
58 else: |
|
59 self.ignorefunc = util.never |
|
60 |
|
61 return self.ignorefunc(f) |
|
62 |
90 |
63 def __del__(self): |
91 def __del__(self): |
64 if self.dirty: |
92 if self.dirty: |
65 self.write() |
93 self.write() |
66 |
94 |
351 checkappend(modified, fn) |
379 checkappend(modified, fn) |
352 elif type == 'a': |
380 elif type == 'a': |
353 checkappend(added, fn) |
381 checkappend(added, fn) |
354 elif type == 'r': |
382 elif type == 'r': |
355 checkappend(unknown, fn) |
383 checkappend(unknown, fn) |
356 else: |
384 elif not self.ignore(fn) and match(fn): |
357 if not self.ignore(fn) and match(fn): |
385 unknown.append(fn) |
358 unknown.append(fn) |
|
359 # return false because we've already handled all cases above. |
386 # return false because we've already handled all cases above. |
360 # there's no need for the walking code to process the file |
387 # there's no need for the walking code to process the file |
361 # any further. |
388 # any further. |
362 return False |
389 return False |
363 |
390 |