##// END OF EJS Templates
match: handle includes using new intersectionmatcher
Martin von Zweigbergk -
r32497:9eccd559 default
parent child Browse files
Show More
@@ -142,9 +142,14 b' def match(root, cwd, patterns, include=N'
142 142 kindpats.append((kind, pats, source))
143 143 return kindpats
144 144
145 m = matcher(root, cwd, normalize, patterns, include=include,
145 m = matcher(root, cwd, normalize, patterns, include=None,
146 146 default=default, exact=exact, auditor=auditor, ctx=ctx,
147 147 listsubrepos=listsubrepos, warn=warn, badfn=badfn)
148 if include:
149 im = matcher(root, cwd, normalize, [], include=include, default=default,
150 exact=False, auditor=auditor, ctx=ctx,
151 listsubrepos=listsubrepos, warn=warn, badfn=None)
152 m = intersectmatchers(m, im)
148 153 if exclude:
149 154 em = matcher(root, cwd, normalize, [], include=exclude, default=default,
150 155 exact=False, auditor=auditor, ctx=ctx,
@@ -457,6 +462,75 b' class differencematcher(basematcher):'
457 462 def __repr__(self):
458 463 return ('<differencematcher m1=%r, m2=%r>' % (self._m1, self._m2))
459 464
465 def intersectmatchers(m1, m2):
466 '''Composes two matchers by matching if both of them match.
467
468 The second matcher's non-matching-attributes (root, cwd, bad, explicitdir,
469 traversedir) are ignored.
470 '''
471 if m1 is None or m2 is None:
472 return m1 or m2
473 if m1.always():
474 m = copy.copy(m2)
475 # TODO: Consider encapsulating these things in a class so there's only
476 # one thing to copy from m1.
477 m.bad = m1.bad
478 m.explicitdir = m1.explicitdir
479 m.traversedir = m1.traversedir
480 m.abs = m1.abs
481 m.rel = m1.rel
482 m._relativeuipath |= m1._relativeuipath
483 return m
484 if m2.always():
485 m = copy.copy(m1)
486 m._relativeuipath |= m2._relativeuipath
487 return m
488 return intersectionmatcher(m1, m2)
489
490 class intersectionmatcher(basematcher):
491 def __init__(self, m1, m2):
492 super(intersectionmatcher, self).__init__(m1._root, m1._cwd)
493 self._m1 = m1
494 self._m2 = m2
495 self.bad = m1.bad
496 self.explicitdir = m1.explicitdir
497 self.traversedir = m1.traversedir
498
499 @propertycache
500 def _files(self):
501 if self.isexact():
502 m1, m2 = self._m1, self._m2
503 if not m1.isexact():
504 m1, m2 = m2, m1
505 return [f for f in m1.files() if m2(f)]
506 # It neither m1 nor m2 is an exact matcher, we can't easily intersect
507 # the set of files, because their files() are not always files. For
508 # example, if intersecting a matcher "-I glob:foo.txt" with matcher of
509 # "path:dir2", we don't want to remove "dir2" from the set.
510 return self._m1.files() + self._m2.files()
511
512 def matchfn(self, f):
513 return self._m1(f) and self._m2(f)
514
515 def visitdir(self, dir):
516 visit1 = self._m1.visitdir(dir)
517 if visit1 == 'all':
518 return self._m2.visitdir(dir)
519 # bool() because visit1=True + visit2='all' should not be 'all'
520 return bool(visit1 and self._m2.visitdir(dir))
521
522 def always(self):
523 return self._m1.always() and self._m2.always()
524
525 def isexact(self):
526 return self._m1.isexact() or self._m2.isexact()
527
528 def anypats(self):
529 return self._m1.anypats() or self._m2.anypats()
530
531 def __repr__(self):
532 return ('<intersectionmatcher m1=%r, m2=%r>' % (self._m1, self._m2))
533
460 534 class subdirmatcher(basematcher):
461 535 """Adapt a matcher to work on a subdirectory only.
462 536
@@ -96,7 +96,7 b''
96 96 f fenugreek ../fenugreek
97 97 f mammals/skunk skunk
98 98 $ hg debugwalk -I 'relglob:*k' .
99 matcher: <matcher files=['mammals'], patterns='(?:mammals(?:/|$))', includes='(?:(?:|.*/)[^/]*k(?:/|$))'>
99 matcher: <intersectionmatcher m1=<matcher files=['mammals'], patterns='(?:mammals(?:/|$))', includes=None>, m2=<matcher files=[], patterns=None, includes='(?:(?:|.*/)[^/]*k(?:/|$))'>>
100 100 f mammals/skunk skunk
101 101 $ hg debugwalk -I 're:.*k$'
102 102 matcher: <matcher files=[], patterns=None, includes='(?:.*k$)'>
@@ -276,17 +276,17 b''
276 276 f fenugreek fenugreek
277 277 f mammals/skunk mammals/skunk
278 278 $ hg debugwalk -Ibeans mammals
279 matcher: <matcher files=['mammals'], patterns='(?:mammals(?:/|$))', includes='(?:beans(?:/|$))'>
279 matcher: <intersectionmatcher m1=<matcher files=['mammals'], patterns='(?:mammals(?:/|$))', includes=None>, m2=<matcher files=[], patterns=None, includes='(?:beans(?:/|$))'>>
280 280 $ hg debugwalk -Inon-existent
281 281 matcher: <matcher files=[], patterns=None, includes='(?:non\\-existent(?:/|$))'>
282 282 $ hg debugwalk -Inon-existent -Ibeans/black
283 283 matcher: <matcher files=[], patterns=None, includes='(?:non\\-existent(?:/|$)|beans\\/black(?:/|$))'>
284 284 f beans/black beans/black
285 285 $ hg debugwalk -Ibeans beans/black
286 matcher: <matcher files=['beans/black'], patterns='(?:beans\\/black(?:/|$))', includes='(?:beans(?:/|$))'>
286 matcher: <intersectionmatcher m1=<matcher files=['beans/black'], patterns='(?:beans\\/black(?:/|$))', includes=None>, m2=<matcher files=[], patterns=None, includes='(?:beans(?:/|$))'>>
287 287 f beans/black beans/black exact
288 288 $ hg debugwalk -Ibeans/black beans
289 matcher: <matcher files=['beans'], patterns='(?:beans(?:/|$))', includes='(?:beans\\/black(?:/|$))'>
289 matcher: <intersectionmatcher m1=<matcher files=['beans'], patterns='(?:beans(?:/|$))', includes=None>, m2=<matcher files=[], patterns=None, includes='(?:beans\\/black(?:/|$))'>>
290 290 f beans/black beans/black
291 291 $ hg debugwalk -Xbeans/black beans
292 292 matcher: <differencematcher m1=<matcher files=['beans'], patterns='(?:beans(?:/|$))', includes=None>, m2=<matcher files=[], patterns=None, includes='(?:beans\\/black(?:/|$))'>>
General Comments 0
You need to be logged in to leave comments. Login now