bitranox: @inverse, pulled in Your changes on version 1.0.2 of igittigitt : https://github.com/bitranox/igittigitt

mherrmann: Thank you @inverse. Could you resolve the conflicts so I can merge? Then I can release a new version with those improvements to PyPI.
inverse: @mherrmann resolved conflicts :+1: 

diff --git a/gitignore_parser.py b/gitignore_parser.py
index c8a7771..5ce75f8 100644
--- a/gitignore_parser.py
+++ b/gitignore_parser.py
@@ -102,7 +102,7 @@ def rule_from_pattern(pattern, base_path=None, source=None):
 			if striptrailingspaces:
 				pattern = pattern[:i]
 		i = i - 1
-	regex = fnmatch_pathname_to_regex(pattern)
+	regex = fnmatch_pathname_to_regex(pattern, directory_only)
 	if anchored:
 		regex = ''.join(['^', regex])
 	return IgnoreRule(
@@ -147,7 +147,7 @@ class IgnoreRule(collections.namedtuple('IgnoreRule_', IGNORE_RULE_FIELDS)):
 
 # Frustratingly, python's fnmatch doesn't provide the FNM_PATHNAME
 # option that .gitignore's behavior depends on.
-def fnmatch_pathname_to_regex(pattern):
+def fnmatch_pathname_to_regex(pattern, directory_only: bool):
 	"""
 	Implements fnmatch style-behavior, as though with FNM_PATHNAME flagged;
 	the path separator will not match shell-style '*' and '.' wildcards.
@@ -201,5 +201,6 @@ def fnmatch_pathname_to_regex(pattern):
 		else:
 			res.append(re.escape(c))
 	res.insert(0, '(?ms)')
-	res.append('$')
-	return ''.join(res)
\ No newline at end of file
+	if not directory_only:
+		res.append('$')
+	return ''.join(res)

Bug with matching paths within .gitignore directory
Is this correct? It feels like a bug to me since it works when you specify the rule in `.gitignore`.


Imagine `.gitignore` contents including

```
.venv/
```


And a script evaluating this

```
gitignore_matcher('/path/to/repo/.venv/')
True
gitignore_matcher('/path/to/repo/.venv/bin')
False
```

To me the second one should return `True`
diff --git a/tests.py b/tests.py
index 6b28b64..c1b6aad 100644
--- a/tests.py
+++ b/tests.py
@@ -74,6 +74,18 @@ class Test(TestCase):
 		self.assertTrue(matches('/home/michael/othermatch'))
 		self.assertTrue(matches('/home/michael/#imnocomment'))
 
+	def test_ignore_directory(self):
+		matches = _parse_gitignore_string('.venv/', fake_base_dir='/home/michael')
+		self.assertTrue(matches('/home/michael/.venv'))
+		self.assertTrue(matches('/home/michael/.venv/folder'))
+		self.assertTrue(matches('/home/michael/.venv/file.txt'))
+
+	def test_ignore_directory_astrix(self):
+		matches = _parse_gitignore_string('.venv/*', fake_base_dir='/home/michael')
+		self.assertFalse(matches('/home/michael/.venv'))
+		self.assertTrue(matches('/home/michael/.venv/folder'))
+		self.assertTrue(matches('/home/michael/.venv/file.txt'))
+
 	def test_negation(self):
 		matches = _parse_gitignore_string(
 			'''

pip install -e .
parse_log_pytest
pytest
pytest
3.9
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
exceptiongroup @ file:///croot/exceptiongroup_1706031385326/work
-e git+https://github.com/mherrmann/gitignore_parser.git@43b39d04366038924239f7057ab5d8fcb0e24b42#egg=gitignore_parser
iniconfig @ file:///home/linux1/recipes/ci/iniconfig_1610983019677/work
packaging @ file:///croot/packaging_1734472117206/work
pluggy @ file:///croot/pluggy_1733169602837/work
pytest @ file:///croot/pytest_1738938843180/work
tomli @ file:///opt/conda/conda-bld/tomli_1657175507142/work

name: gitignore_parser
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - ca-certificates=2025.2.25=h06a4308_0
  - exceptiongroup=1.2.0=py39h06a4308_0
  - iniconfig=1.1.1=pyhd3eb1b0_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.4.4=h6a678d5_1
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=3.0.16=h5eee18b_0
  - packaging=24.2=py39h06a4308_0
  - pip=25.0=py39h06a4308_0
  - pluggy=1.5.0=py39h06a4308_0
  - pytest=8.3.4=py39h06a4308_0
  - python=3.9.21=he870216_1
  - readline=8.2=h5eee18b_0
  - setuptools=75.8.0=py39h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - tomli=2.0.1=py39h06a4308_0
  - tzdata=2025a=h04d1e81_0
  - wheel=0.45.1=py39h06a4308_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
prefix: /opt/conda/envs/gitignore_parser

tests.py::Test::test_ignore_directory
tests.py::Test::test_anchored_wildcard tests.py::Test::test_comment tests.py::Test::test_ignore_directory_astrix tests.py::Test::test_negation tests.py::Test::test_simple tests.py::Test::test_trailingspaces tests.py::Test::test_wildcard
gitignore_parser.py
gitignore_parser.py