Rev 4956: Change the match order. in http://bazaar.launchpad.net/~jameinel/bzr/ignore-exception

John Arbash Meinel john at arbash-meinel.com
Fri Jan 15 14:37:23 GMT 2010


At http://bazaar.launchpad.net/~jameinel/bzr/ignore-exception

------------------------------------------------------------
revno: 4956
revision-id: john at arbash-meinel.com-20100115143712-8nhsehxuz6h6n71o
parent: whitley at bangpath.org-20100111164402-9luag9p9ahpy4kmz
committer: John Arbash Meinel <john at arbash-meinel.com>
branch nick: ignore-exception
timestamp: Fri 2010-01-15 08:37:12 -0600
message:
  Change the match order.
  We lose a tiny bit of precision, but it should increase our match speed.
  Specifically, if a pattern is not ignored, we don't need to evaluate
  the exclusion pattern. Further we don't need to evaluate the always-ignore
  pattern unless the exclusion pattern matches.
  The loss of precision is that if a pattern is always-ignore but not
  excluded, then we don't add the '\!\!' back to the pattern.
  The gain is that in the 'initial add' case, we only need to check one
  match, and not 3. And in the 'ignored' case, we only need to check
  2 matches, and not 3. This should help decrease the performance hit.
-------------- next part --------------
=== modified file 'bzrlib/globbing.py'
--- a/bzrlib/globbing.py	2010-01-11 16:44:02 +0000
+++ b/bzrlib/globbing.py	2010-01-15 14:37:12 +0000
@@ -1,4 +1,4 @@
-# Copyright (C) 2006, 2008 Canonical Ltd
+# Copyright (C) 2006-2010 Canonical Ltd
 
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -215,6 +215,7 @@
                 return patterns[match.lastindex -1]
         return None
 
+
 class ExceptionGlobster(object):
     """A Globster that supports exception patterns.
     
@@ -235,6 +236,8 @@
                 ignores[1].append(p[1:])
             else:
                 ignores[0].append(p)
+        # double-exceptions are also simple ignores
+        ignores[0].extend(ignores[2])
         self._ignores = [Globster(i) for i in ignores]
         
     def match(self, filename):
@@ -242,13 +245,21 @@
 
         :return A matching pattern or None if there is no matching pattern.
         """
-        double_neg = self._ignores[2].match(filename)
-        if double_neg:
-            return "!!%s" % double_neg
-        elif self._ignores[1].match(filename):
-            return None
-        else:
-            return self._ignores[0].match(filename)
+        m = self._ignores[0].match(filename)
+        if m is None:
+            return None
+        # This matches the regular ignore patterns, see if we also have an
+        # exception for this case
+        if self._ignores[1].match(filename) is None:
+            # It didn't match, so this file is definitely ignored
+            return m
+        # This matched an ignore and an unignore, see if it matches the
+        # always-ignore
+        always_ignore = self._ignores[2].match(filename)
+        if always_ignore is None:
+            return None
+        return '!!%s' % (always_ignore,)
+
 
 class _OrderedGlobster(Globster):
     """A Globster that keeps pattern order."""

=== modified file 'bzrlib/tests/test_globbing.py'
--- a/bzrlib/tests/test_globbing.py	2010-01-11 16:44:02 +0000
+++ b/bzrlib/tests/test_globbing.py	2010-01-15 14:37:12 +0000
@@ -1,4 +1,4 @@
-# Copyright (C) 2006 Canonical Ltd
+# Copyright (C) 2006-2010 Canonical Ltd
 # -*- coding: utf-8 -*-
 #
 # This program is free software; you can redistribute it and/or modify
@@ -308,11 +308,13 @@
             self.assertEqual(patterns[x],globster.match(filename))
         self.assertEqual(None,globster.match('foobar.300'))
 
+
 class TestExceptionGlobster(TestCase):
 
     def test_exclusion_patterns(self):
         """test that exception patterns are not matched"""
-        patterns = [ u'*', u'!./local', u'!./local/**/*', u'!RE:\.z.*',u'!!./.zcompdump' ]
+        patterns = [u'*', u'!./local', u'!./local/**/*',
+                    u'!RE:\.z.*',u'!!./.zcompdump']
         globster = ExceptionGlobster(patterns)
         self.assertEqual(u'*', globster.match('tmp/foo.txt'))
         self.assertEqual(None, globster.match('local'))
@@ -323,7 +325,7 @@
 
     def test_exclusion_order(self):
         """test that ordering of exclusion patterns does not matter"""
-        patterns = [ u'static/**/*.html', u'!static/**/versionable.html']
+        patterns = [u'static/**/*.html', u'!static/**/versionable.html']
         globster = ExceptionGlobster(patterns)
         self.assertEqual(u'static/**/*.html', globster.match('static/foo.html'))
         self.assertEqual(None, globster.match('static/versionable.html'))
@@ -333,6 +335,19 @@
         self.assertEqual(None, globster.match('static/versionable.html'))
         self.assertEqual(None, globster.match('static/bar/versionable.html'))
 
+    def test_only_double_ignored(self):
+        patterns = [u'!!ignored']
+        globster = ExceptionGlobster(patterns)
+        self.assertEqual(u'ignored', globster.match('ignored'))
+        self.knownFailure('If a pattern is only double ignored then the'
+                          ' match indicates a regular pattern')
+
+    def test_excluded_and_double_ignored(self):
+        patterns = [u'!i*', u'!!ignored']
+        globster = ExceptionGlobster(patterns)
+        self.assertEqual(u'!!ignored', globster.match('ignored'))
+
+
 class TestOrderedGlobster(TestCase):
 
     def test_ordered_globs(self):



More information about the bazaar-commits mailing list