diff --git a/pathspec/patterns/gitwildmatch.py b/pathspec/patterns/gitwildmatch.py index 3d0673f..5c00086 100644 --- a/pathspec/patterns/gitwildmatch.py +++ b/pathspec/patterns/gitwildmatch.py @@ -290,13 +290,16 @@ def _translate_segment_glob(pattern: str) -> str: # - "[]-]" matches ']' and '-'. # - "[!]a-]" matches any character except ']', 'a' and '-'. j = i - # Pass brack expression negation. - if j < end and pattern[j] == '!': + + # Pass bracket expression negation. + if j < end and (pattern[j] == '!' or pattern[j] == '^'): j += 1 + # Pass first closing bracket if it is at the beginning of the # expression. if j < end and pattern[j] == ']': j += 1 + # Find closing bracket. Stop once we reach the end or find it. while j < end and pattern[j] != ']': j += 1 diff --git a/tests/test_gitwildmatch.py b/tests/test_gitwildmatch.py index 6a51683..da176bd 100644 --- a/tests/test_gitwildmatch.py +++ b/tests/test_gitwildmatch.py @@ -774,7 +774,7 @@ def test_12_asterisk_4_descendant(self): 'anydir/file.txt', }) - def test_13_issue_77_1_regex(self): + def test_13_issue_77_regex(self): """ Test the resulting regex for regex bracket expression negation. """ @@ -786,15 +786,28 @@ def test_13_issue_77_1_regex(self): self.assertEqual(regex, equiv_regex) - def test_13_issue_77_2_results(self): + def test_13_negate_with_caret(self): """ - Test that regex bracket expression negation works. + Test negation using the caret symbol (^) """ - pattern = GitWildMatchPattern('a[^b]c') + pattern = GitWildMatchPattern("a[^gy]c") results = set(filter(pattern.match_file, [ - 'abc', - 'azc', + "agc", + "ayc", + "abc", + "adc", ])) - self.assertEqual(results, { - 'azc', - }) + self.assertEqual(results, {"abc", "adc"}) + + def test_13_negate_with_exclamation_mark(self): + """ + Test negation using the exclamation mark (!) + """ + pattern = GitWildMatchPattern("a[!gy]c") + results = set(filter(pattern.match_file, [ + "agc", + "ayc", + "abc", + "adc", + ])) + self.assertEqual(results, {"abc", "adc"})