##// 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 kindpats.append((kind, pats, source))
142 kindpats.append((kind, pats, source))
143 return kindpats
143 return kindpats
144
144
145 return matcher(root, cwd, normalize, patterns, include=include,
145 m = matcher(root, cwd, normalize, patterns, include=include, exclude=None,
146 exclude=exclude, default=default, exact=exact,
146 default=default, exact=exact, auditor=auditor, ctx=ctx,
147 auditor=auditor, ctx=ctx, listsubrepos=listsubrepos,
147 listsubrepos=listsubrepos, warn=warn, badfn=badfn)
148 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 def exact(root, cwd, files, badfn=None):
155 def exact(root, cwd, files, badfn=None):
151 return match(root, cwd, files, exact=True, badfn=badfn)
156 return match(root, cwd, files, exact=True, badfn=badfn)
@@ -418,6 +423,62 b' class matcher(basematcher):'
418 (self._files, self.patternspat, self.includepat,
423 (self._files, self.patternspat, self.includepat,
419 self.excludepat))
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 class subdirmatcher(basematcher):
482 class subdirmatcher(basematcher):
422 """Adapt a matcher to work on a subdirectory only.
483 """Adapt a matcher to work on a subdirectory only.
423
484
@@ -76,7 +76,7 b''
76 f mammals/Procyonidae/raccoon Procyonidae/raccoon
76 f mammals/Procyonidae/raccoon Procyonidae/raccoon
77 f mammals/skunk skunk
77 f mammals/skunk skunk
78 $ hg debugwalk -X ../beans
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 f fennel ../fennel
80 f fennel ../fennel
81 f fenugreek ../fenugreek
81 f fenugreek ../fenugreek
82 f fiddlehead ../fiddlehead
82 f fiddlehead ../fiddlehead
@@ -146,7 +146,7 b''
146 f fenugreek ../fenugreek
146 f fenugreek ../fenugreek
147 f fiddlehead ../fiddlehead
147 f fiddlehead ../fiddlehead
148 $ hg debugwalk -X 'rootfilesin:'
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 f beans/black ../beans/black
150 f beans/black ../beans/black
151 f beans/borlotti ../beans/borlotti
151 f beans/borlotti ../beans/borlotti
152 f beans/kidney ../beans/kidney
152 f beans/kidney ../beans/kidney
@@ -194,7 +194,7 b''
194 matcher: <matcher files=[], patterns=None, includes='(?:^mammals/[^/]+$)', excludes=None>
194 matcher: <matcher files=[], patterns=None, includes='(?:^mammals/[^/]+$)', excludes=None>
195 f mammals/skunk skunk
195 f mammals/skunk skunk
196 $ hg debugwalk -X 'rootfilesin:mammals'
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 f beans/black ../beans/black
198 f beans/black ../beans/black
199 f beans/borlotti ../beans/borlotti
199 f beans/borlotti ../beans/borlotti
200 f beans/kidney ../beans/kidney
200 f beans/kidney ../beans/kidney
@@ -289,35 +289,35 b''
289 matcher: <matcher files=['beans'], patterns='(?:beans(?:/|$))', includes='(?:beans\\/black(?:/|$))', excludes=None>
289 matcher: <matcher files=['beans'], patterns='(?:beans(?:/|$))', includes='(?:beans\\/black(?:/|$))', excludes=None>
290 f beans/black beans/black
290 f beans/black beans/black
291 $ hg debugwalk -Xbeans/black beans
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 f beans/borlotti beans/borlotti
293 f beans/borlotti beans/borlotti
294 f beans/kidney beans/kidney
294 f beans/kidney beans/kidney
295 f beans/navy beans/navy
295 f beans/navy beans/navy
296 f beans/pinto beans/pinto
296 f beans/pinto beans/pinto
297 f beans/turtle beans/turtle
297 f beans/turtle beans/turtle
298 $ hg debugwalk -Xbeans/black -Ibeans
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 f beans/borlotti beans/borlotti
300 f beans/borlotti beans/borlotti
301 f beans/kidney beans/kidney
301 f beans/kidney beans/kidney
302 f beans/navy beans/navy
302 f beans/navy beans/navy
303 f beans/pinto beans/pinto
303 f beans/pinto beans/pinto
304 f beans/turtle beans/turtle
304 f beans/turtle beans/turtle
305 $ hg debugwalk -Xbeans/black beans/black
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 f beans/black beans/black exact
307 f beans/black beans/black exact
308 $ hg debugwalk -Xbeans/black -Ibeans/black
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 $ hg debugwalk -Xbeans beans/black
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 f beans/black beans/black exact
312 f beans/black beans/black exact
313 $ hg debugwalk -Xbeans -Ibeans/black
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 $ hg debugwalk 'glob:mammals/../beans/b*'
315 $ hg debugwalk 'glob:mammals/../beans/b*'
316 matcher: <matcher files=['beans'], patterns='(?:beans\\/b[^/]*$)', includes=None, excludes=None>
316 matcher: <matcher files=['beans'], patterns='(?:beans\\/b[^/]*$)', includes=None, excludes=None>
317 f beans/black beans/black
317 f beans/black beans/black
318 f beans/borlotti beans/borlotti
318 f beans/borlotti beans/borlotti
319 $ hg debugwalk '-X*/Procyonidae' mammals
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 f mammals/skunk mammals/skunk
321 f mammals/skunk mammals/skunk
322 $ hg debugwalk path:mammals
322 $ hg debugwalk path:mammals
323 matcher: <matcher files=['mammals'], patterns='(?:^mammals(?:/|$))', includes=None, excludes=None>
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