Skip to content

Commit ca2cf10

Browse files
authored
Merge pull request #1459 from AustinScola/ascola/fix-blob-filter-types
Fix blob filter types
2 parents 275c37f + da59d74 commit ca2cf10

File tree

3 files changed

+50
-9
lines changed

3 files changed

+50
-9
lines changed

‎git/index/base.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252
from .typ import (
5353
BaseIndexEntry,
5454
IndexEntry,
55+
StageType,
5556
)
5657
from .util import TemporaryFileSwap, post_clear_cache, default_index, git_working_dir
5758

@@ -83,13 +84,12 @@
8384
from git.util import Actor
8485

8586

86-
StageType = int
8787
Treeish = Union[Tree, Commit, str, bytes]
8888

8989
# ------------------------------------------------------------------------------------
9090

9191

92-
__all__ = ("IndexFile", "CheckoutError")
92+
__all__ = ("IndexFile", "CheckoutError", "StageType")
9393

9494

9595
class IndexFile(LazyMixin, git_diff.Diffable, Serializable):

‎git/index/typ.py

+16-7
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,26 @@
11
"""Module with additional types used by the index"""
22

33
from binascii import b2a_hex
4+
from pathlib import Path
45

56
from .util import pack, unpack
67
from git.objects import Blob
78

89

910
# typing ----------------------------------------------------------------------
1011

11-
from typing import NamedTuple, Sequence, TYPE_CHECKING, Tuple, Union, cast
12+
from typing import NamedTuple, Sequence, TYPE_CHECKING, Tuple, Union, cast, List
1213

1314
from git.types import PathLike
1415

1516
if TYPE_CHECKING:
1617
from git.repo import Repo
1718

19+
StageType = int
20+
1821
# ---------------------------------------------------------------------------------
1922

20-
__all__ = ("BlobFilter", "BaseIndexEntry", "IndexEntry")
23+
__all__ = ("BlobFilter", "BaseIndexEntry", "IndexEntry", "StageType")
2124

2225
# { Invariants
2326
CE_NAMEMASK = 0x0FFF
@@ -48,12 +51,18 @@ def __init__(self, paths: Sequence[PathLike]) -> None:
4851
"""
4952
self.paths = paths
5053

51-
def __call__(self, stage_blob: Blob) -> bool:
52-
path = stage_blob[1].path
53-
for p in self.paths:
54-
if path.startswith(p):
54+
def __call__(self, stage_blob: Tuple[StageType, Blob]) -> bool:
55+
blob_pathlike: PathLike = stage_blob[1].path
56+
blob_path: Path = blob_pathlike if isinstance(blob_pathlike, Path) else Path(blob_pathlike)
57+
for pathlike in self.paths:
58+
path: Path = pathlike if isinstance(pathlike, Path) else Path(pathlike)
59+
# TODO: Change to use `PosixPath.is_relative_to` once Python 3.8 is no longer supported.
60+
filter_parts: List[str] = path.parts
61+
blob_parts: List[str] = blob_path.parts
62+
if len(filter_parts) > len(blob_parts):
63+
continue
64+
if all(i == j for i, j in zip(filter_parts, blob_parts)):
5565
return True
56-
# END for each path in filter paths
5766
return False
5867

5968

‎test/test_blob_filter.py

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
"""Test the blob filter."""
2+
from pathlib import Path
3+
from typing import Sequence, Tuple
4+
from unittest.mock import MagicMock
5+
6+
import pytest
7+
8+
from git.index.typ import BlobFilter, StageType
9+
from git.objects import Blob
10+
from git.types import PathLike
11+
12+
13+
# fmt: off
14+
@pytest.mark.parametrize('paths, path, expected_result', [
15+
((Path("foo"),), Path("foo"), True),
16+
((Path("foo"),), Path("foo/bar"), True),
17+
((Path("foo/bar"),), Path("foo"), False),
18+
((Path("foo"), Path("bar")), Path("foo"), True),
19+
])
20+
# fmt: on
21+
def test_blob_filter(paths: Sequence[PathLike], path: PathLike, expected_result: bool) -> None:
22+
"""Test the blob filter."""
23+
blob_filter = BlobFilter(paths)
24+
25+
binsha = MagicMock(__len__=lambda self: 20)
26+
stage_type: StageType = 0
27+
blob: Blob = Blob(repo=MagicMock(), binsha=binsha, path=path)
28+
stage_blob: Tuple[StageType, Blob] = (stage_type, blob)
29+
30+
result = blob_filter(stage_blob)
31+
32+
assert result == expected_result

0 commit comments

Comments
 (0)