##// END OF EJS Templates
match: handle excludes using new differencematcher...
Martin von Zweigbergk -
r32465:a83a7d27 default
parent child Browse files
Show More
@@ -142,10 +142,15 b' def match(root, cwd, patterns, include=N'
142 142 kindpats.append((kind, pats, source))
143 143 return kindpats
144 144
145 return matcher(root, cwd, normalize, patterns, include=include,
146 exclude=exclude, default=default, exact=exact,
147 auditor=auditor, ctx=ctx, listsubrepos=listsubrepos,
148 warn=warn, badfn=badfn)
145 m = matcher(root, cwd, normalize, patterns, include=include, exclude=None,
146 default=default, exact=exact, auditor=auditor, ctx=ctx,
147 listsubrepos=listsubrepos, warn=warn, badfn=badfn)
148 if exclude:
149 em = matcher(root, cwd, normalize, [], include=exclude, exclude=None,
150 default=default, exact=False, auditor=auditor, ctx=ctx,
151 listsubrepos=listsubrepos, warn=warn, badfn=None)
152 m = differencematcher(m, em)
153 return m
149 154
150 155 def exact(root, cwd, files, badfn=None):
151 156 return match(root, cwd, files, exact=True, badfn=badfn)
@@ -418,6 +423,62 b' class matcher(basematcher):'
418 423 (self._files, self.patternspat, self.includepat,
419 424 self.excludepat))
420 425
426 class differencematcher(basematcher):
427 '''Composes two matchers by matching if the first matches and the second
428 does not. Well, almost... If the user provides a pattern like "-X foo foo",
429 Mercurial actually does match "foo" against that. That's because exact
430 matches are treated specially. So, since this differencematcher is used for
431 excludes, it needs to special-case exact matching.
432
433 The second matcher's non-matching-attributes (root, cwd, bad, explicitdir,
434 traversedir) are ignored.
435
436 TODO: If we want to keep the behavior described above for exact matches, we
437 should consider instead treating the above case something like this:
438 union(exact(foo), difference(pattern(foo), include(foo)))
439 '''
440 def __init__(self, m1, m2):
441 super(differencematcher, self).__init__(m1._root, m1._cwd)
442 self._m1 = m1
443 self._m2 = m2
444 self.bad = m1.bad
445 self.explicitdir = m1.explicitdir
446 self.traversedir = m1.traversedir
447
448 def matchfn(self, f):
449 return self._m1(f) and (not self._m2(f) or self._m1.exact(f))
450
451 @propertycache
452 def _files(self):
453 if self.isexact():
454 return [f for f in self._m1.files() if self(f)]
455 # If m1 is not an exact matcher, we can't easily figure out the set of
456 # files, because its files() are not always files. For example, if
457 # m1 is "path:dir" and m2 is "rootfileins:.", we don't
458 # want to remove "dir" from the set even though it would match m2,
459 # because the "dir" in m1 may not be a file.
460 return self._m1.files()
461
462 def visitdir(self, dir):
463 if self._m2.visitdir(dir) == 'all':
464 # There's a bug here: If m1 matches file 'dir/file' and m2 excludes
465 # 'dir' (recursively), we should still visit 'dir' due to the
466 # exception we have for exact matches.
467 return False
468 return bool(self._m1.visitdir(dir))
469
470 def isexact(self):
471 return self._m1.isexact()
472
473 def anypats(self):
474 return self._m1.anypats() or self._m2.anypats()
475
476 def prefix(self):
477 return not self.always() and not self.isexact() and not self.anypats()
478
479 def __repr__(self):
480 return ('<differencematcher m1=%r, m2=%r>' % (self._m1, self._m2))
481
421 482 class subdirmatcher(basematcher):
422 483 """Adapt a matcher to work on a subdirectory only.
423 484
@@ -76,7 +76,7 b''
76 76 f mammals/Procyonidae/raccoon Procyonidae/raccoon
77 77 f mammals/skunk skunk
78 78 $ hg debugwalk -X ../beans
79 matcher: <matcher files=[], patterns=None, includes=None, excludes='(?:beans(?:/|$))'>
79 matcher: <differencematcher m1=<matcher files=[], patterns=None, includes=None, excludes=None>, m2=<matcher files=[], patterns=None, includes='(?:beans(?:/|$))', excludes=None>>
80 80 f fennel ../fennel
81 81 f fenugreek ../fenugreek
82 82 f fiddlehead ../fiddlehead
@@ -146,7 +146,7 b''
146 146 f fenugreek ../fenugreek
147 147 f fiddlehead ../fiddlehead
148 148 $ hg debugwalk -X 'rootfilesin:'
149 matcher: <matcher files=[], patterns=None, includes=None, excludes='(?:^[^/]+$)'>
149 matcher: <differencematcher m1=<matcher files=[], patterns=None, includes=None, excludes=None>, m2=<matcher files=[], patterns=None, includes='(?:^[^/]+$)', excludes=None>>
150 150 f beans/black ../beans/black
151 151 f beans/borlotti ../beans/borlotti
152 152 f beans/kidney ../beans/kidney
@@ -194,7 +194,7 b''
194 194 matcher: <matcher files=[], patterns=None, includes='(?:^mammals/[^/]+$)', excludes=None>
195 195 f mammals/skunk skunk
196 196 $ hg debugwalk -X 'rootfilesin:mammals'
197 matcher: <matcher files=[], patterns=None, includes=None, excludes='(?:^mammals/[^/]+$)'>
197 matcher: <differencematcher m1=<matcher files=[], patterns=None, includes=None, excludes=None>, m2=<matcher files=[], patterns=None, includes='(?:^mammals/[^/]+$)', excludes=None>>
198 198 f beans/black ../beans/black
199 199 f beans/borlotti ../beans/borlotti
200 200 f beans/kidney ../beans/kidney
@@ -289,35 +289,35 b''
289 289 matcher: <matcher files=['beans'], patterns='(?:beans(?:/|$))', includes='(?:beans\\/black(?:/|$))', excludes=None>
290 290 f beans/black beans/black
291 291 $ hg debugwalk -Xbeans/black beans
292 matcher: <matcher files=['beans'], patterns='(?:beans(?:/|$))', includes=None, excludes='(?:beans\\/black(?:/|$))'>
292 matcher: <differencematcher m1=<matcher files=['beans'], patterns='(?:beans(?:/|$))', includes=None, excludes=None>, m2=<matcher files=[], patterns=None, includes='(?:beans\\/black(?:/|$))', excludes=None>>
293 293 f beans/borlotti beans/borlotti
294 294 f beans/kidney beans/kidney
295 295 f beans/navy beans/navy
296 296 f beans/pinto beans/pinto
297 297 f beans/turtle beans/turtle
298 298 $ hg debugwalk -Xbeans/black -Ibeans
299 matcher: <matcher files=[], patterns=None, includes='(?:beans(?:/|$))', excludes='(?:beans\\/black(?:/|$))'>
299 matcher: <differencematcher m1=<matcher files=[], patterns=None, includes='(?:beans(?:/|$))', excludes=None>, m2=<matcher files=[], patterns=None, includes='(?:beans\\/black(?:/|$))', excludes=None>>
300 300 f beans/borlotti beans/borlotti
301 301 f beans/kidney beans/kidney
302 302 f beans/navy beans/navy
303 303 f beans/pinto beans/pinto
304 304 f beans/turtle beans/turtle
305 305 $ hg debugwalk -Xbeans/black beans/black
306 matcher: <matcher files=['beans/black'], patterns='(?:beans\\/black(?:/|$))', includes=None, excludes='(?:beans\\/black(?:/|$))'>
306 matcher: <differencematcher m1=<matcher files=['beans/black'], patterns='(?:beans\\/black(?:/|$))', includes=None, excludes=None>, m2=<matcher files=[], patterns=None, includes='(?:beans\\/black(?:/|$))', excludes=None>>
307 307 f beans/black beans/black exact
308 308 $ hg debugwalk -Xbeans/black -Ibeans/black
309 matcher: <matcher files=[], patterns=None, includes='(?:beans\\/black(?:/|$))', excludes='(?:beans\\/black(?:/|$))'>
309 matcher: <differencematcher m1=<matcher files=[], patterns=None, includes='(?:beans\\/black(?:/|$))', excludes=None>, m2=<matcher files=[], patterns=None, includes='(?:beans\\/black(?:/|$))', excludes=None>>
310 310 $ hg debugwalk -Xbeans beans/black
311 matcher: <matcher files=['beans/black'], patterns='(?:beans\\/black(?:/|$))', includes=None, excludes='(?:beans(?:/|$))'>
311 matcher: <differencematcher m1=<matcher files=['beans/black'], patterns='(?:beans\\/black(?:/|$))', includes=None, excludes=None>, m2=<matcher files=[], patterns=None, includes='(?:beans(?:/|$))', excludes=None>>
312 312 f beans/black beans/black exact
313 313 $ hg debugwalk -Xbeans -Ibeans/black
314 matcher: <matcher files=[], patterns=None, includes='(?:beans\\/black(?:/|$))', excludes='(?:beans(?:/|$))'>
314 matcher: <differencematcher m1=<matcher files=[], patterns=None, includes='(?:beans\\/black(?:/|$))', excludes=None>, m2=<matcher files=[], patterns=None, includes='(?:beans(?:/|$))', excludes=None>>
315 315 $ hg debugwalk 'glob:mammals/../beans/b*'
316 316 matcher: <matcher files=['beans'], patterns='(?:beans\\/b[^/]*$)', includes=None, excludes=None>
317 317 f beans/black beans/black
318 318 f beans/borlotti beans/borlotti
319 319 $ hg debugwalk '-X*/Procyonidae' mammals
320 matcher: <matcher files=['mammals'], patterns='(?:mammals(?:/|$))', includes=None, excludes='(?:[^/]*\\/Procyonidae(?:/|$))'>
320 matcher: <differencematcher m1=<matcher files=['mammals'], patterns='(?:mammals(?:/|$))', includes=None, excludes=None>, m2=<matcher files=[], patterns=None, includes='(?:[^/]*\\/Procyonidae(?:/|$))', excludes=None>>
321 321 f mammals/skunk mammals/skunk
322 322 $ hg debugwalk path:mammals
323 323 matcher: <matcher files=['mammals'], patterns='(?:^mammals(?:/|$))', includes=None, excludes=None>
General Comments 0
You need to be logged in to leave comments. Login now