One function
rule_from_pattern in mherrmann/gitignore_parser
The author described this change as “Fix multi-asterisks that fall outside of the special cases”. It counts as a record because the check below fails on the code as it stood at cdf80b7b1 and passes on a872df78d, with nothing else changed between the two runs.
Projectmherrmann/gitignore_parser
Fix saved2023-10-04
Sharing licenceMIT · LICENSE
Change size+4 −11
What the code was meant to do, written into the code itself as a docstring
Take a .gitignore match pattern, such as "*.py[cod]" or "**/*.bak", and return an IgnoreRule suitable for matching against files and directories. Patterns which do not match files, such as comments and blank lines, will return None. Because git allows for nested .gitignore files, a base_path value is required for correct behavior. The base path should be absolute.
The change
| 15 | 15 | # Discard comments and separators | |
| 16 | 16 | if pattern.strip() == '' or pattern[0] == '#': | |
| 17 | 17 | return | |
| 18 | - | # Discard anything with more than two consecutive asterisks | |
| 19 | - | if pattern.find('***') > -1: | |
| 20 | - | return | |
| 21 | 18 | # Strip leading bang before examining double asterisks | |
| 22 | 19 | if pattern[0] == '!': | |
| 23 | 20 | negation = True | |
| 24 | 21 | pattern = pattern[1:] | |
| 25 | 22 | else: | |
| 26 | 23 | negation = False | |
| 27 | - | # Discard anything with invalid double-asterisks -- they can appear | |
| 28 | - | # at the start or the end, or be surrounded by slashes | |
| 29 | - | for m in re.finditer(r'\*\*', pattern): | |
| 30 | - | start_index = m.start() | |
| 31 | - | if (start_index != 0 and start_index != len(pattern) - 2 and | |
| 32 | - | (pattern[start_index - 1] != '/' or | |
| 33 | - | pattern[start_index + 2] != '/')): | |
| 34 | - | return | |
| 24 | + | # Multi-asterisks not surrounded by slashes (or at the start/end) should | |
| 25 | + | # be treated like single-asterisks. | |
| 26 | + | pattern = re.sub(r'([^/])\*{2,}', r'\1*', pattern) | |
| 27 | + | pattern = re.sub(r'\*{2,}([^/])', r'*\1', pattern) | |
| 35 | 28 | ||
| 36 | 29 | # Special-casing '/', which doesn't match any files or directories | |
| 37 | 30 | if pattern.rstrip() == '/': |
The check that tells the two apart
fail→pass·tests.py::Test::test_double_asterisk_without_slashes_handled_like_single_asterisk
Check file tests.py, taken without changes from the fix and copied onto the older code, so the exact same check runs against both versions.
Origin and history
The code before itcdf80b7b1e2efc15db3cbd2feb3a28775a76208e
Broken version dated2023-10-04
Modulegitignore_parser
Units changedrule_from_pattern
Fingerprint33c1bb996a1f4fa2
Checked2026-08-18 by goldset/0.1
Every field above is generated by our program. None of it is written by hand.
Other bugs found in mherrmann/gitignore_parser
- 2024-01-19Fix ValueError for some symlinks
- 2023-10-05Fix: do not resolve symlinks
- 2023-10-04fnmatch_pathname_to_regex
- 2023-10-03rule_from_pattern
- 2023-10-03fnmatch_pathname_to_regex
- 2023-06-30fnmatch_pathname_to_regex