| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent f8776ee commit 0b64501
4 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -2,6 +2,15 @@ | |||
| 2 | 2 | Changelog | |
| 3 | 3 | ========= | |
| 4 | 4 | ||
| 5 | + Unreleased | ||
| 6 | + ========== | ||
| 7 | + | ||
| 8 | + * Deprecate the pure-Python ``GitDB`` object database backend due to security and | ||
| 9 | + performance issues. Selecting it or a subclass through ``odbt`` now emits a | ||
| 10 | + ``DeprecationWarning``. Remove ``odbt=GitDB`` to use ``GitCmdObjectDB``, the | ||
| 11 | + existing default, or select ``odbt=GitCmdObjectDB`` explicitly. The ``gitdb`` | ||
| 12 | + package remains a dependency for shared types and utilities. | ||
| 13 | + | ||
| 5 | 14 | 3.2.1 | |
| 6 | 15 | ===== | |
| 7 | 16 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -513,24 +513,29 @@ Object Databases | |||
| 513 | 513 | ||
| 514 | 514 | The type of the database determines certain performance characteristics, such as the quantity of objects that can be read per second, the resource usage when reading large data files, as well as the average memory footprint of your application. | |
| 515 | 515 | ||
| 516 | - GitDB | ||
| 517 | - ===== | ||
| 518 | - The GitDB is a pure-python implementation of the git object database. It is the default database to use in GitPython 0.3. It uses less memory when handling huge files, but will be 2 to 5 times slower when extracting large quantities of small objects from densely packed repositories:: | ||
| 516 | + GitCmdObjectDB | ||
| 517 | + ============== | ||
| 518 | + ``GitCmdObjectDB`` is the default and recommended backend. It reads objects and | ||
| 519 | + resolves abbreviated object IDs through persistent ``git cat-file`` processes:: | ||
| 519 | 520 | ||
| 520 | - repo = Repo("path/to/repo", odbt=GitDB) | ||
| 521 | + repo = Repo("path/to/repo") | ||
| 522 | + # Equivalent explicit selection: | ||
| 523 | + repo = Repo("path/to/repo", odbt=GitCmdObjectDB) | ||
| 521 | 524 | ||
| 525 | + GitDB | ||
| 526 | + ===== | ||
| 522 | 527 | .. warning:: | |
| 523 | - ``GitDB`` may fail or become extremely slow when traversing trees in | ||
| 524 | - repositories with very large commits (thousands of changed files in a | ||
| 525 | - single commit). If you encounter ``RecursionError`` or excessive | ||
| 526 | - slowness during tree traversal, switch to ``GitCmdObjectDB`` instead. | ||
| 528 | + The pure-Python ``GitDB`` backend is deprecated due to security and performance | ||
| 529 | + issues. Its object parsers can exhaust resources or return incorrect object | ||
| 530 | + data when processing untrusted repositories. Do not use it for untrusted data. | ||
| 527 | 531 | ||
| 532 | + Selecting ``odbt=GitDB`` (including a subclass) emits a ``DeprecationWarning``. | ||
| 533 | + To migrate, remove ``odbt=GitDB`` or replace it with ``odbt=GitCmdObjectDB`` when | ||
| 534 | + opening, initializing, or cloning a repository. The deprecated backend remains | ||
| 535 | + available for compatibility; deprecation does not fix its parsing issues. | ||
| 528 | 536 | ||
| 529 | - GitCmdObjectDB | ||
| 530 | - ============== | ||
| 531 | - The git command database uses persistent git-cat-file instances to read repository information. These operate very fast under all conditions, but will consume additional memory for the process itself. When extracting large files, memory usage will be much higher than ``GitDB``:: | ||
| 532 | - | ||
| 533 | - repo = Repo("path/to/repo", odbt=GitCmdObjectDB) | ||
| 537 | + The ``gitdb`` package remains a dependency because GitPython still uses its shared | ||
| 538 | + types and utilities. | ||
| 534 | 539 | ||
| 535 | 540 | Git Command Debugging and Customization | |
| 536 | 541 | *************************************** | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -228,7 +228,7 @@ class Repo: | |||
| 228 | 228 | def __init__( | |
| 229 | 229 | self, | |
| 230 | 230 | path: Optional[PathLike] = None, | |
| 231 | - odbt: Type[LooseObjectDB] = GitCmdObjectDB, | ||
| 231 | + odbt: Type[Union[LooseObjectDB, gitdb.GitDB]] = GitCmdObjectDB, | ||
| 232 | 232 | search_parent_directories: bool = False, | |
| 233 | 233 | expand_vars: bool = True, | |
| 234 | 234 | ) -> None: | |
@@ -255,7 +255,9 @@ def __init__( | |||
| 255 | 255 | :param odbt: | |
| 256 | 256 | Object DataBase type - a type which is constructed by providing the | |
| 257 | 257 | directory containing the database objects, i.e. ``.git/objects``. It will be | |
| 258 | - used to access all object data. | ||
| 258 | + used to access all object data. The pure-Python ``GitDB`` backend is | ||
| 259 | + deprecated due to security and performance issues. Use the default | ||
| 260 | + :class:`~git.db.GitCmdObjectDB` instead. | ||
| 259 | 261 | ||
| 260 | 262 | :param search_parent_directories: | |
| 261 | 263 | If ``True``, all parent directories will be searched for a valid repo as | |
@@ -411,6 +413,13 @@ def __init__( | |||
| 411 | 413 | if issubclass(odbt, GitCmdObjectDB): | |
| 412 | 414 | self.odb = odbt(rootpath, self.git) | |
| 413 | 415 | else: | |
| 416 | + if issubclass(odbt, gitdb.GitDB): | ||
| 417 | + warnings.warn( | ||
| 418 | + "GitDB is deprecated as a GitPython backend due to security and performance issues. " | ||
| 419 | + "Use the default GitCmdObjectDB backend instead.", | ||
| 420 | + DeprecationWarning, | ||
| 421 | + stacklevel=2, | ||
| 422 | + ) | ||
| 414 | 423 | self.odb = odbt(rootpath) | |
| 415 | 424 | ||
| 416 | 425 | def __enter__(self) -> "Repo": | |
@@ -1456,7 +1465,7 @@ def init( | |||
| 1456 | 1465 | cls, | |
| 1457 | 1466 | path: Union[PathLike, None] = None, | |
| 1458 | 1467 | mkdir: bool = True, | |
| 1459 | - odbt: Type[GitCmdObjectDB] = GitCmdObjectDB, | ||
| 1468 | + odbt: Type[Union[LooseObjectDB, gitdb.GitDB]] = GitCmdObjectDB, | ||
| 1460 | 1469 | expand_vars: bool = True, | |
| 1461 | 1470 | allow_unsafe_options: bool = False, | |
| 1462 | 1471 | **kwargs: Any, | |
@@ -1476,7 +1485,8 @@ def init( | |||
| 1476 | 1485 | :param odbt: | |
| 1477 | 1486 | Object DataBase type - a type which is constructed by providing the | |
| 1478 | 1487 | directory containing the database objects, i.e. ``.git/objects``. It will be | |
| 1479 | - used to access all object data. | ||
| 1488 | + used to access all object data. The pure-Python ``GitDB`` backend is | ||
| 1489 | + deprecated; use the default :class:`~git.db.GitCmdObjectDB` instead. | ||
| 1480 | 1490 | ||
| 1481 | 1491 | :param expand_vars: | |
| 1482 | 1492 | If specified, environment variables will not be escaped. This can lead to | |
@@ -1515,7 +1525,7 @@ def _clone( | |||
| 1515 | 1525 | git: "Git", | |
| 1516 | 1526 | url: PathLike, | |
| 1517 | 1527 | path: PathLike, | |
| 1518 | - odb_default_type: Type[LooseObjectDB], | ||
| 1528 | + odb_default_type: Type[Union[LooseObjectDB, gitdb.GitDB]], | ||
| 1519 | 1529 | progress: Union["RemoteProgress", "UpdateProgress", Callable[..., "RemoteProgress"], None] = None, | |
| 1520 | 1530 | multi_options: Optional[List[str]] = None, | |
| 1521 | 1531 | allow_unsafe_protocols: bool = False, | |
@@ -1639,7 +1649,9 @@ def clone( | |||
| 1639 | 1649 | ||
| 1640 | 1650 | :param kwargs: | |
| 1641 | 1651 | * ``odbt`` = ObjectDatabase Type, allowing to determine the object database | |
| 1642 | - implementation used by the returned :class:`Repo` instance. | ||
| 1652 | + implementation used by the returned :class:`Repo` instance. The | ||
| 1653 | + pure-Python ``GitDB`` backend is deprecated; use the default | ||
| 1654 | + :class:`~git.db.GitCmdObjectDB` instead. | ||
| 1643 | 1655 | * All remaining keyword arguments are given to the :manpage:`git-clone(1)` | |
| 1644 | 1656 | command. | |
| 1645 | 1657 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -17,6 +17,7 @@ | |||
| 17 | 17 | ||
| 18 | 18 | import pytest | |
| 19 | 19 | ||
| 20 | + from git.db import GitCmdObjectDB, GitDB | ||
| 20 | 21 | from git.diff import NULL_TREE | |
| 21 | 22 | from git.objects.util import Traversable | |
| 22 | 23 | from git.repo import Repo | |
@@ -60,6 +61,32 @@ def diffs(commit: "Commit") -> Generator["DiffIndex", None, None]: | |||
| 60 | 61 | yield commit.diff(NULL_TREE) | |
| 61 | 62 | ||
| 62 | 63 | ||
| 64 | + def test_gitdb_backend_warns(commit: "Commit") -> None: | ||
| 65 | + class DerivedGitDB(GitDB): | ||
| 66 | + pass | ||
| 67 | + | ||
| 68 | + for backend in (GitDB, DerivedGitDB): | ||
| 69 | + with pytest.deprecated_call(match="GitDB.*deprecated.*GitCmdObjectDB") as caught: | ||
| 70 | + with Repo(commit.repo.working_dir, odbt=backend) as repo: | ||
| 71 | + assert type(repo.odb) is backend | ||
| 72 | + assert repo.head.commit.message == commit.message | ||
| 73 | + assert len(caught) == 1 | ||
| 74 | + assert caught[0].filename == __file__ | ||
| 75 | + | ||
| 76 | + | ||
| 77 | + def test_gitcmdobjectdb_backend_does_not_warn(commit: "Commit") -> None: | ||
| 78 | + class DerivedGitCmdObjectDB(GitCmdObjectDB): | ||
| 79 | + pass | ||
| 80 | + | ||
| 81 | + with assert_no_deprecation_warning(): | ||
| 82 | + with Repo(commit.repo.working_dir) as repo: | ||
| 83 | + assert type(repo.odb) is GitCmdObjectDB | ||
| 84 | + for backend in (GitCmdObjectDB, DerivedGitCmdObjectDB): | ||
| 85 | + with Repo(commit.repo.working_dir, odbt=backend) as repo: | ||
| 86 | + assert type(repo.odb) is backend | ||
| 87 | + assert repo.head.commit.message == commit.message | ||
| 88 | + | ||
| 89 | + | ||
| 63 | 90 | def test_diff_renamed_warns(diff: "Diff") -> None: | |
| 64 | 91 | """The deprecated Diff.renamed property issues a deprecation warning.""" | |
| 65 | 92 | with pytest.deprecated_call(): | |
| Back | FazBrowse Home | New Git URL |
0 commit comments