GitPython 3.1.55__tar.gz → 3.1.57__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. {gitpython-3.1.55 → gitpython-3.1.57/GitPython.egg-info}/PKG-INFO +8 -6
  2. {gitpython-3.1.55 → gitpython-3.1.57}/GitPython.egg-info/requires.txt +3 -0
  3. {gitpython-3.1.55/GitPython.egg-info → gitpython-3.1.57}/PKG-INFO +8 -6
  4. {gitpython-3.1.55 → gitpython-3.1.57}/README.md +3 -5
  5. gitpython-3.1.57/VERSION +1 -0
  6. {gitpython-3.1.55 → gitpython-3.1.57}/doc/source/changes.rst +27 -0
  7. {gitpython-3.1.55 → gitpython-3.1.57}/doc/source/intro.rst +0 -5
  8. {gitpython-3.1.55 → gitpython-3.1.57}/doc/source/reference.rst +1 -0
  9. {gitpython-3.1.55 → gitpython-3.1.57}/git/__init__.py +1 -1
  10. {gitpython-3.1.55 → gitpython-3.1.57}/git/cmd.py +28 -12
  11. {gitpython-3.1.55 → gitpython-3.1.57}/git/diff.py +4 -1
  12. {gitpython-3.1.55 → gitpython-3.1.57}/git/index/base.py +14 -0
  13. {gitpython-3.1.55 → gitpython-3.1.57}/git/objects/commit.py +14 -1
  14. {gitpython-3.1.55 → gitpython-3.1.57}/git/objects/fun.py +2 -2
  15. {gitpython-3.1.55 → gitpython-3.1.57}/git/refs/tag.py +13 -0
  16. {gitpython-3.1.55 → gitpython-3.1.57}/git/repo/base.py +12 -1
  17. {gitpython-3.1.55 → gitpython-3.1.57}/git/util.py +21 -7
  18. {gitpython-3.1.55 → gitpython-3.1.57}/pyproject.toml +13 -5
  19. {gitpython-3.1.55 → gitpython-3.1.57}/setup.py +4 -1
  20. {gitpython-3.1.55 → gitpython-3.1.57}/test-requirements.txt +1 -0
  21. gitpython-3.1.55/VERSION +0 -1
  22. {gitpython-3.1.55 → gitpython-3.1.57}/AUTHORS +0 -0
  23. {gitpython-3.1.55 → gitpython-3.1.57}/CHANGES +0 -0
  24. {gitpython-3.1.55 → gitpython-3.1.57}/CONTRIBUTING.md +0 -0
  25. {gitpython-3.1.55 → gitpython-3.1.57}/GitPython.egg-info/SOURCES.txt +0 -0
  26. {gitpython-3.1.55 → gitpython-3.1.57}/GitPython.egg-info/dependency_links.txt +0 -0
  27. {gitpython-3.1.55 → gitpython-3.1.57}/GitPython.egg-info/not-zip-safe +0 -0
  28. {gitpython-3.1.55 → gitpython-3.1.57}/GitPython.egg-info/top_level.txt +0 -0
  29. {gitpython-3.1.55 → gitpython-3.1.57}/LICENSE +0 -0
  30. {gitpython-3.1.55 → gitpython-3.1.57}/MANIFEST.in +0 -0
  31. {gitpython-3.1.55 → gitpython-3.1.57}/doc/.gitignore +0 -0
  32. {gitpython-3.1.55 → gitpython-3.1.57}/doc/Makefile +0 -0
  33. {gitpython-3.1.55 → gitpython-3.1.57}/doc/requirements.txt +0 -0
  34. {gitpython-3.1.55 → gitpython-3.1.57}/doc/source/conf.py +0 -0
  35. {gitpython-3.1.55 → gitpython-3.1.57}/doc/source/index.rst +0 -0
  36. {gitpython-3.1.55 → gitpython-3.1.57}/doc/source/quickstart.rst +0 -0
  37. {gitpython-3.1.55 → gitpython-3.1.57}/doc/source/roadmap.rst +0 -0
  38. {gitpython-3.1.55 → gitpython-3.1.57}/doc/source/tutorial.rst +0 -0
  39. {gitpython-3.1.55 → gitpython-3.1.57}/git/compat.py +0 -0
  40. {gitpython-3.1.55 → gitpython-3.1.57}/git/config.py +0 -0
  41. {gitpython-3.1.55 → gitpython-3.1.57}/git/db.py +0 -0
  42. {gitpython-3.1.55 → gitpython-3.1.57}/git/exc.py +0 -0
  43. {gitpython-3.1.55 → gitpython-3.1.57}/git/index/__init__.py +0 -0
  44. {gitpython-3.1.55 → gitpython-3.1.57}/git/index/fun.py +0 -0
  45. {gitpython-3.1.55 → gitpython-3.1.57}/git/index/typ.py +0 -0
  46. {gitpython-3.1.55 → gitpython-3.1.57}/git/index/util.py +0 -0
  47. {gitpython-3.1.55 → gitpython-3.1.57}/git/objects/__init__.py +0 -0
  48. {gitpython-3.1.55 → gitpython-3.1.57}/git/objects/base.py +0 -0
  49. {gitpython-3.1.55 → gitpython-3.1.57}/git/objects/blob.py +0 -0
  50. {gitpython-3.1.55 → gitpython-3.1.57}/git/objects/submodule/__init__.py +0 -0
  51. {gitpython-3.1.55 → gitpython-3.1.57}/git/objects/submodule/base.py +0 -0
  52. {gitpython-3.1.55 → gitpython-3.1.57}/git/objects/submodule/root.py +0 -0
  53. {gitpython-3.1.55 → gitpython-3.1.57}/git/objects/submodule/util.py +0 -0
  54. {gitpython-3.1.55 → gitpython-3.1.57}/git/objects/tag.py +0 -0
  55. {gitpython-3.1.55 → gitpython-3.1.57}/git/objects/tree.py +0 -0
  56. {gitpython-3.1.55 → gitpython-3.1.57}/git/objects/util.py +0 -0
  57. {gitpython-3.1.55 → gitpython-3.1.57}/git/py.typed +0 -0
  58. {gitpython-3.1.55 → gitpython-3.1.57}/git/refs/__init__.py +0 -0
  59. {gitpython-3.1.55 → gitpython-3.1.57}/git/refs/head.py +0 -0
  60. {gitpython-3.1.55 → gitpython-3.1.57}/git/refs/log.py +0 -0
  61. {gitpython-3.1.55 → gitpython-3.1.57}/git/refs/reference.py +0 -0
  62. {gitpython-3.1.55 → gitpython-3.1.57}/git/refs/remote.py +0 -0
  63. {gitpython-3.1.55 → gitpython-3.1.57}/git/refs/symbolic.py +0 -0
  64. {gitpython-3.1.55 → gitpython-3.1.57}/git/remote.py +0 -0
  65. {gitpython-3.1.55 → gitpython-3.1.57}/git/repo/__init__.py +0 -0
  66. {gitpython-3.1.55 → gitpython-3.1.57}/git/repo/fun.py +0 -0
  67. {gitpython-3.1.55 → gitpython-3.1.57}/git/types.py +0 -0
  68. {gitpython-3.1.55 → gitpython-3.1.57}/requirements.txt +0 -0
  69. {gitpython-3.1.55 → gitpython-3.1.57}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: GitPython
3
- Version: 3.1.55
3
+ Version: 3.1.57
4
4
  Summary: GitPython is a Python library used to interact with Git repositories
5
5
  Home-page: https://github.com/gitpython-developers/GitPython
6
6
  Author: Sebastian Thiel, Michael Trier
@@ -22,6 +22,9 @@ Classifier: Programming Language :: Python :: 3.9
22
22
  Classifier: Programming Language :: Python :: 3.10
23
23
  Classifier: Programming Language :: Python :: 3.11
24
24
  Classifier: Programming Language :: Python :: 3.12
25
+ Classifier: Programming Language :: Python :: 3.13
26
+ Classifier: Programming Language :: Python :: 3.14
27
+ Classifier: Programming Language :: Python :: 3.15
25
28
  Requires-Python: >=3.7
26
29
  Description-Content-Type: text/markdown
27
30
  License-File: LICENSE
@@ -30,6 +33,7 @@ Requires-Dist: gitdb<5,>=4.0.1
30
33
  Requires-Dist: typing-extensions>=3.10.0.2; python_version < "3.10"
31
34
  Provides-Extra: test
32
35
  Requires-Dist: coverage[toml]; extra == "test"
36
+ Requires-Dist: basedpyright==1.39.9; (python_version >= "3.9" and sys_platform != "cygwin") and extra == "test"
33
37
  Requires-Dist: ddt!=1.4.3,>=1.1.1; extra == "test"
34
38
  Requires-Dist: mock; python_version < "3.8" and extra == "test"
35
39
  Requires-Dist: mypy==1.18.2; python_version >= "3.9" and extra == "test"
@@ -160,15 +164,13 @@ In the less common case that you do not want to install test dependencies, `pip
160
164
 
161
165
  #### With editable *dependencies* (not preferred, and rarely needed)
162
166
 
163
- In rare cases, you may want to work on GitPython and one or both of its [gitdb](https://github.com/gitpython-developers/gitdb) and [smmap](https://github.com/gitpython-developers/smmap) dependencies at the same time, with changes in your local working copy of gitdb or smmap immediately reflected in the behavior of your local working copy of GitPython. This can be done by making editable installations of those dependencies in the same virtual environment where you install GitPython.
164
-
165
- If you want to do that *and* you want the versions in GitPython's git submodules to be used, then pass `-e git/ext/gitdb` and/or `-e git/ext/gitdb/gitdb/ext/smmap` to `pip install`. This can be done in any order, and in separate `pip install` commands or the same one, so long as `-e` appears before *each* path. For example, you can install GitPython, gitdb, and smmap editably in the currently active virtual environment this way:
167
+ GitPython, [gitdb](gitdb), and [smmap](smmap) live in this repository as independently packaged projects. To work on all three at once, install each one editably in the same virtual environment:
166
168
 
167
169
  ```sh
168
- pip install -e ".[test]" -e git/ext/gitdb -e git/ext/gitdb/gitdb/ext/smmap
170
+ pip install -e smmap -e gitdb -e ".[test]"
169
171
  ```
170
172
 
171
- The submodules must have been cloned for that to work, but that will already be the case if you have run `./init-tests-after-clone.sh`. You can use `pip list` to check which packages are installed editably and which are installed normally.
173
+ You can use `pip list` to check which packages are installed editably and which are installed normally.
172
174
 
173
175
  To reiterate, this approach should only rarely be used. For most development it is preferable to allow the gitdb and smmap dependencices to be retrieved automatically from PyPI in their latest stable packaged versions.
174
176
 
@@ -26,3 +26,6 @@ mock
26
26
 
27
27
  [test:python_version >= "3.9"]
28
28
  mypy==1.18.2
29
+
30
+ [test:python_version >= "3.9" and sys_platform != "cygwin"]
31
+ basedpyright==1.39.9
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: GitPython
3
- Version: 3.1.55
3
+ Version: 3.1.57
4
4
  Summary: GitPython is a Python library used to interact with Git repositories
5
5
  Home-page: https://github.com/gitpython-developers/GitPython
6
6
  Author: Sebastian Thiel, Michael Trier
@@ -22,6 +22,9 @@ Classifier: Programming Language :: Python :: 3.9
22
22
  Classifier: Programming Language :: Python :: 3.10
23
23
  Classifier: Programming Language :: Python :: 3.11
24
24
  Classifier: Programming Language :: Python :: 3.12
25
+ Classifier: Programming Language :: Python :: 3.13
26
+ Classifier: Programming Language :: Python :: 3.14
27
+ Classifier: Programming Language :: Python :: 3.15
25
28
  Requires-Python: >=3.7
26
29
  Description-Content-Type: text/markdown
27
30
  License-File: LICENSE
@@ -30,6 +33,7 @@ Requires-Dist: gitdb<5,>=4.0.1
30
33
  Requires-Dist: typing-extensions>=3.10.0.2; python_version < "3.10"
31
34
  Provides-Extra: test
32
35
  Requires-Dist: coverage[toml]; extra == "test"
36
+ Requires-Dist: basedpyright==1.39.9; (python_version >= "3.9" and sys_platform != "cygwin") and extra == "test"
33
37
  Requires-Dist: ddt!=1.4.3,>=1.1.1; extra == "test"
34
38
  Requires-Dist: mock; python_version < "3.8" and extra == "test"
35
39
  Requires-Dist: mypy==1.18.2; python_version >= "3.9" and extra == "test"
@@ -160,15 +164,13 @@ In the less common case that you do not want to install test dependencies, `pip
160
164
 
161
165
  #### With editable *dependencies* (not preferred, and rarely needed)
162
166
 
163
- In rare cases, you may want to work on GitPython and one or both of its [gitdb](https://github.com/gitpython-developers/gitdb) and [smmap](https://github.com/gitpython-developers/smmap) dependencies at the same time, with changes in your local working copy of gitdb or smmap immediately reflected in the behavior of your local working copy of GitPython. This can be done by making editable installations of those dependencies in the same virtual environment where you install GitPython.
164
-
165
- If you want to do that *and* you want the versions in GitPython's git submodules to be used, then pass `-e git/ext/gitdb` and/or `-e git/ext/gitdb/gitdb/ext/smmap` to `pip install`. This can be done in any order, and in separate `pip install` commands or the same one, so long as `-e` appears before *each* path. For example, you can install GitPython, gitdb, and smmap editably in the currently active virtual environment this way:
167
+ GitPython, [gitdb](gitdb), and [smmap](smmap) live in this repository as independently packaged projects. To work on all three at once, install each one editably in the same virtual environment:
166
168
 
167
169
  ```sh
168
- pip install -e ".[test]" -e git/ext/gitdb -e git/ext/gitdb/gitdb/ext/smmap
170
+ pip install -e smmap -e gitdb -e ".[test]"
169
171
  ```
170
172
 
171
- The submodules must have been cloned for that to work, but that will already be the case if you have run `./init-tests-after-clone.sh`. You can use `pip list` to check which packages are installed editably and which are installed normally.
173
+ You can use `pip list` to check which packages are installed editably and which are installed normally.
172
174
 
173
175
  To reiterate, this approach should only rarely be used. For most development it is preferable to allow the gitdb and smmap dependencices to be retrieved automatically from PyPI in their latest stable packaged versions.
174
176
 
@@ -101,15 +101,13 @@ In the less common case that you do not want to install test dependencies, `pip
101
101
 
102
102
  #### With editable *dependencies* (not preferred, and rarely needed)
103
103
 
104
- In rare cases, you may want to work on GitPython and one or both of its [gitdb](https://github.com/gitpython-developers/gitdb) and [smmap](https://github.com/gitpython-developers/smmap) dependencies at the same time, with changes in your local working copy of gitdb or smmap immediately reflected in the behavior of your local working copy of GitPython. This can be done by making editable installations of those dependencies in the same virtual environment where you install GitPython.
105
-
106
- If you want to do that *and* you want the versions in GitPython's git submodules to be used, then pass `-e git/ext/gitdb` and/or `-e git/ext/gitdb/gitdb/ext/smmap` to `pip install`. This can be done in any order, and in separate `pip install` commands or the same one, so long as `-e` appears before *each* path. For example, you can install GitPython, gitdb, and smmap editably in the currently active virtual environment this way:
104
+ GitPython, [gitdb](gitdb), and [smmap](smmap) live in this repository as independently packaged projects. To work on all three at once, install each one editably in the same virtual environment:
107
105
 
108
106
  ```sh
109
- pip install -e ".[test]" -e git/ext/gitdb -e git/ext/gitdb/gitdb/ext/smmap
107
+ pip install -e smmap -e gitdb -e ".[test]"
110
108
  ```
111
109
 
112
- The submodules must have been cloned for that to work, but that will already be the case if you have run `./init-tests-after-clone.sh`. You can use `pip list` to check which packages are installed editably and which are installed normally.
110
+ You can use `pip list` to check which packages are installed editably and which are installed normally.
113
111
 
114
112
  To reiterate, this approach should only rarely be used. For most development it is preferable to allow the gitdb and smmap dependencices to be retrieved automatically from PyPI in their latest stable packaged versions.
115
113
 
@@ -0,0 +1 @@
1
+ 3.1.57
@@ -2,6 +2,33 @@
2
2
  Changelog
3
3
  =========
4
4
 
5
+ 3.1.57
6
+ ======
7
+
8
+ A security fix for
9
+
10
+ * https://github.com/gitpython-developers/GitPython/security/advisories/GHSA-3f7w-8rr8-f37f
11
+ * https://github.com/gitpython-developers/GitPython/security/advisories/GHSA-539m-9xh6-q6rr
12
+
13
+ If you can, also try and provide feedback on the upcoming v4 branch
14
+ https://github.com/gitpython-developers/GitPython/pull/2177 - patches welcome.
15
+
16
+ See the following for all changes.
17
+ https://github.com/gitpython-developers/GitPython/releases/tag/3.1.55
18
+
19
+ 3.1.56
20
+ ======
21
+
22
+ A security fix for
23
+
24
+ * https://github.com/gitpython-developers/GitPython/security/advisories/GHSA-p538-c434-8v24
25
+
26
+ If you can, also try and provide feedback on the upcoming v4 branch
27
+ https://github.com/gitpython-developers/GitPython/pull/2177 - patches welcome.
28
+
29
+ See the following for all changes.
30
+ https://github.com/gitpython-developers/GitPython/releases/tag/3.1.55
31
+
5
32
  3.1.55
6
33
  ======
7
34
 
@@ -97,11 +97,6 @@ and cloned using::
97
97
 
98
98
  $ git clone https://github.com/gitpython-developers/GitPython git-python
99
99
 
100
- Initialize all submodules to obtain the required dependencies with::
101
-
102
- $ cd git-python
103
- $ git submodule update --init --recursive
104
-
105
100
  Finally verify the installation by running unit tests::
106
101
 
107
102
  $ python -m unittest
@@ -91,6 +91,7 @@ Objects.Util
91
91
  .. automodule:: git.objects.util
92
92
  :members:
93
93
  :undoc-members:
94
+ :private-members: _get_intermediate_items, _list_traverse, _traverse
94
95
  :special-members:
95
96
 
96
97
  Index.Base
@@ -86,7 +86,7 @@ __all__ = [
86
86
  "to_hex_sha",
87
87
  ]
88
88
 
89
- __version__ = '3.1.55'
89
+ __version__ = '3.1.57'
90
90
 
91
91
  from typing import Any, List, Optional, Sequence, TYPE_CHECKING, Tuple, Union
92
92
 
@@ -1435,6 +1435,10 @@ class Git(metaclass=_GitMeta):
1435
1435
  if as_process:
1436
1436
  return self.AutoInterrupt(proc, command)
1437
1437
 
1438
+ watchdog: Optional[threading.Timer] = None
1439
+ kill_check: Optional[threading.Event] = None
1440
+ timeout_error: Optional[Callable[[], Union[str, bytes]]] = None
1441
+
1438
1442
  if sys.platform != "win32" and kill_after_timeout is not None:
1439
1443
  # Help mypy figure out this is not None even when used inside communicate().
1440
1444
  timeout = kill_after_timeout
@@ -1460,6 +1464,7 @@ class Git(metaclass=_GitMeta):
1460
1464
  except OSError:
1461
1465
  pass
1462
1466
  # Tell the main routine that the process was killed.
1467
+ assert kill_check is not None
1463
1468
  kill_check.set()
1464
1469
  except OSError:
1465
1470
  # It is possible that the process gets completed in the duration
@@ -1467,23 +1472,25 @@ class Git(metaclass=_GitMeta):
1467
1472
  pass
1468
1473
  return
1469
1474
 
1475
+ def make_timeout_error() -> Union[str, bytes]:
1476
+ err = f'Timeout: the command "{" ".join(redacted_command)}" did not complete in {timeout:g} secs.'
1477
+ return err if universal_newlines else err.encode(defenc)
1478
+
1470
1479
  def communicate() -> Tuple[AnyStr, AnyStr]:
1480
+ assert watchdog is not None
1481
+ assert kill_check is not None
1471
1482
  watchdog.start()
1472
1483
  out, err = proc.communicate()
1473
1484
  watchdog.cancel()
1474
1485
  if kill_check.is_set():
1475
- err = 'Timeout: the command "%s" did not complete in %d secs.' % (
1476
- " ".join(redacted_command),
1477
- timeout,
1478
- )
1479
- if not universal_newlines:
1480
- err = err.encode(defenc)
1486
+ err = make_timeout_error()
1481
1487
  return out, err
1482
1488
 
1483
1489
  # END helpers
1484
1490
 
1485
1491
  kill_check = threading.Event()
1486
1492
  watchdog = threading.Timer(timeout, kill_process, args=(proc.pid,))
1493
+ timeout_error = make_timeout_error
1487
1494
  else:
1488
1495
  communicate = proc.communicate
1489
1496
 
@@ -1504,15 +1511,24 @@ class Git(metaclass=_GitMeta):
1504
1511
  status = proc.returncode
1505
1512
  else:
1506
1513
  max_chunk_size = max_chunk_size if max_chunk_size and max_chunk_size > 0 else io.DEFAULT_BUFFER_SIZE
1507
- if proc.stdout is not None:
1508
- stream_copy(proc.stdout, output_stream, max_chunk_size)
1509
- stdout_value = proc.stdout.read()
1510
- if proc.stderr is not None:
1511
- stderr_value = proc.stderr.read()
1514
+ if watchdog is not None:
1515
+ watchdog.start()
1516
+ try:
1517
+ if proc.stdout is not None:
1518
+ stream_copy(proc.stdout, output_stream, max_chunk_size)
1519
+ stdout_value = proc.stdout.read()
1520
+ if proc.stderr is not None:
1521
+ stderr_value = proc.stderr.read()
1522
+ status = proc.wait()
1523
+ finally:
1524
+ if watchdog is not None:
1525
+ watchdog.cancel()
1512
1526
  # Strip trailing "\n".
1513
1527
  if stderr_value is not None and stderr_value.endswith(newline): # type: ignore[arg-type]
1514
1528
  stderr_value = stderr_value[:-1]
1515
- status = proc.wait()
1529
+ if kill_check is not None and kill_check.is_set():
1530
+ assert timeout_error is not None
1531
+ stderr_value = timeout_error()
1516
1532
  # END stdout handling
1517
1533
  finally:
1518
1534
  if proc.stdout is not None:
@@ -284,7 +284,10 @@ class Diffable:
284
284
  # END paths handling
285
285
 
286
286
  kwargs["as_process"] = True
287
- proc = diff_cmd(*self._process_diff_args(args), **kwargs)
287
+ args = self._process_diff_args(args)
288
+ if create_patch:
289
+ self.repo.git(c="diff.mnemonicPrefix=false")
290
+ proc = diff_cmd(*args, **kwargs)
288
291
 
289
292
  diff_method = Diff._index_from_patch_format if create_patch else Diff._index_from_raw_format
290
293
  index = diff_method(self.repo, proc)
@@ -130,6 +130,8 @@ class IndexFile(LazyMixin, git_diff.Diffable, Serializable):
130
130
  index directly before operating on it using the git command.
131
131
  """
132
132
 
133
+ unsafe_git_checkout_index_options = ["--prefix"]
134
+
133
135
  __slots__ = ("repo", "version", "entries", "_extension_data", "_file_path")
134
136
 
135
137
  _VERSION = 2
@@ -1212,6 +1214,7 @@ class IndexFile(LazyMixin, git_diff.Diffable, Serializable):
1212
1214
  paths: Union[None, Iterable[PathLike]] = None,
1213
1215
  force: bool = False,
1214
1216
  fprogress: Callable = lambda *args: None,
1217
+ allow_unsafe_options: bool = False,
1215
1218
  **kwargs: Any,
1216
1219
  ) -> Union[None, Iterator[PathLike], Sequence[PathLike]]:
1217
1220
  """Check out the given paths or all files from the version known to the index
@@ -1238,6 +1241,9 @@ class IndexFile(LazyMixin, git_diff.Diffable, Serializable):
1238
1241
  no explicit paths are given. Otherwise progress information will be send
1239
1242
  prior and after a file has been checked out.
1240
1243
 
1244
+ :param allow_unsafe_options:
1245
+ Allow unsafe options, such as ``--prefix``.
1246
+
1241
1247
  :param kwargs:
1242
1248
  Additional arguments to be passed to :manpage:`git-checkout-index(1)`.
1243
1249
 
@@ -1261,6 +1267,12 @@ class IndexFile(LazyMixin, git_diff.Diffable, Serializable):
1261
1267
  i.e. if you want :manpage:`git-checkout(1)`-like behaviour, use
1262
1268
  ``head.checkout`` instead of ``index.checkout``.
1263
1269
  """
1270
+ if not allow_unsafe_options:
1271
+ Git.check_unsafe_options(
1272
+ options=Git._option_candidates([], kwargs),
1273
+ unsafe_options=self.unsafe_git_checkout_index_options,
1274
+ )
1275
+
1264
1276
  args = ["--index"]
1265
1277
  if force:
1266
1278
  args.append("--force")
@@ -1547,6 +1559,8 @@ class IndexFile(LazyMixin, git_diff.Diffable, Serializable):
1547
1559
  args.extend(paths)
1548
1560
 
1549
1561
  kwargs["as_process"] = True
1562
+ if create_patch:
1563
+ self.repo.git(c="diff.mnemonicPrefix=false")
1550
1564
  proc = self.repo.git.diff(*args, **kwargs)
1551
1565
 
1552
1566
  diff_method = (
@@ -269,13 +269,21 @@ class Commit(base.Object, TraversableIterableObj, Diffable, Serializable):
269
269
  else:
270
270
  return self.message.split(b"\n", 1)[0]
271
271
 
272
- def count(self, paths: Union[PathLike, Sequence[PathLike]] = "", **kwargs: Any) -> int:
272
+ def count(
273
+ self,
274
+ paths: Union[PathLike, Sequence[PathLike]] = "",
275
+ allow_unsafe_options: bool = False,
276
+ **kwargs: Any,
277
+ ) -> int:
273
278
  """Count the number of commits reachable from this commit.
274
279
 
275
280
  :param paths:
276
281
  An optional path or a list of paths restricting the return value to commits
277
282
  actually containing the paths.
278
283
 
284
+ :param allow_unsafe_options:
285
+ Allow unsafe options, like ``--output``.
286
+
279
287
  :param kwargs:
280
288
  Additional options to be passed to :manpage:`git-rev-list(1)`. They must not
281
289
  alter the output style of the command, or parsing will yield incorrect
@@ -284,6 +292,11 @@ class Commit(base.Object, TraversableIterableObj, Diffable, Serializable):
284
292
  :return:
285
293
  An int defining the number of reachable commits
286
294
  """
295
+ if not allow_unsafe_options:
296
+ Git.check_unsafe_options(
297
+ options=Git._option_candidates([], kwargs), unsafe_options=self.unsafe_git_rev_options
298
+ )
299
+
287
300
  # Yes, it makes a difference whether empty paths are given or not in our case as
288
301
  # the empty paths version will ignore merge commits for some reason.
289
302
  if paths:
@@ -115,11 +115,11 @@ def tree_entries_from_data(data: bytes) -> List[EntryTup]:
115
115
  # Default encoding for strings in git is UTF-8.
116
116
  # Only use the respective unicode object if the byte stream was encoded.
117
117
  name_bytes = data[ns:i]
118
- name = safe_decode(name_bytes)
118
+ name = safe_decode(bytes(name_bytes))
119
119
 
120
120
  # Byte is NULL, get next 20.
121
121
  i += 1
122
- sha = data[i : i + 20]
122
+ sha = bytes(data[i : i + 20])
123
123
  i = i + 20
124
124
  out.append((sha, mode, name))
125
125
  # END for each byte in data stream
@@ -16,6 +16,7 @@ from .reference import Reference
16
16
 
17
17
  from typing import Any, TYPE_CHECKING, Type, Union
18
18
 
19
+ from git.cmd import Git
19
20
  from git.types import AnyGitObject, PathLike
20
21
 
21
22
  if TYPE_CHECKING:
@@ -42,6 +43,8 @@ class TagReference(Reference):
42
43
 
43
44
  __slots__ = ()
44
45
 
46
+ unsafe_git_tag_options = ["--file", "-F"]
47
+
45
48
  _common_default = "tags"
46
49
  _common_path_default = Reference._common_path_default + "/" + _common_default
47
50
 
@@ -92,6 +95,7 @@ class TagReference(Reference):
92
95
  reference: Union[str, "SymbolicReference"] = "HEAD",
93
96
  logmsg: Union[str, None] = None,
94
97
  force: bool = False,
98
+ allow_unsafe_options: bool = False,
95
99
  **kwargs: Any,
96
100
  ) -> "TagReference":
97
101
  """Create a new tag reference.
@@ -121,12 +125,21 @@ class TagReference(Reference):
121
125
  :param force:
122
126
  If ``True``, force creation of a tag even though that tag already exists.
123
127
 
128
+ :param allow_unsafe_options:
129
+ Allow unsafe options, such as ``--file``.
130
+
124
131
  :param kwargs:
125
132
  Additional keyword arguments to be passed to :manpage:`git-tag(1)`.
126
133
 
127
134
  :return:
128
135
  A new :class:`TagReference`.
129
136
  """
137
+ if not allow_unsafe_options:
138
+ Git.check_unsafe_options(
139
+ options=Git._option_candidates([], kwargs),
140
+ unsafe_options=cls.unsafe_git_tag_options,
141
+ )
142
+
130
143
  if "ref" in kwargs and kwargs["ref"]:
131
144
  reference = kwargs["ref"]
132
145
 
@@ -151,8 +151,10 @@ class Repo:
151
151
  "-c",
152
152
  # Can install hooks that execute during clone:
153
153
  "--template",
154
+ # Fetches from an additional caller-controlled URI:
155
+ "--bundle-uri",
154
156
  ]
155
- """Options to :manpage:`git-clone(1)` that allow arbitrary commands to be executed.
157
+ """Options to :manpage:`git-clone(1)` that permit unsafe command execution or I/O.
156
158
 
157
159
  The ``--upload-pack``/``-u`` option allows users to execute arbitrary commands
158
160
  directly:
@@ -164,6 +166,11 @@ class Repo:
164
166
 
165
167
  The ``--template`` option can install hooks that execute during clone:
166
168
  https://git-scm.com/docs/git-clone#Documentation/git-clone.txt---templatetemplate-directory
169
+
170
+ The ``--bundle-uri`` option fetches from an additional URI before fetching from the
171
+ clone URL. An untrusted value can therefore make Git access local files or
172
+ unintended network resources:
173
+ https://git-scm.com/docs/git-clone#Documentation/git-clone.txt---bundle-uriuri
167
174
  """
168
175
 
169
176
  unsafe_git_archive_options = [
@@ -172,6 +179,10 @@ class Repo:
172
179
  # Writes output to a caller-controlled filesystem path.
173
180
  "--output",
174
181
  "-o",
182
+ # Reads from a caller-controlled filesystem path:
183
+ "--add-file",
184
+ # Injects a caller-controlled path and contents:
185
+ "--add-virtual-file",
175
186
  ]
176
187
 
177
188
  unsafe_git_revision_options = [
@@ -540,8 +540,7 @@ def expand_path(p: Union[None, PathLike], expand_vars: bool = True) -> Optional[
540
540
 
541
541
 
542
542
  def remove_password_if_present(cmdline: Sequence[str]) -> List[str]:
543
- """Parse any command line argument and if one of the elements is an URL with a
544
- username and/or password, replace them by stars (in-place).
543
+ """Redact credentials in URLs and HTTP Authorization extra headers in a command line.
545
544
 
546
545
  If nothing is found, this just returns the command line as-is.
547
546
 
@@ -551,6 +550,16 @@ def remove_password_if_present(cmdline: Sequence[str]) -> List[str]:
551
550
  new_cmdline = []
552
551
  for index, to_parse in enumerate(cmdline):
553
552
  new_cmdline.append(to_parse)
553
+ config_key, separator, header = to_parse.partition("=")
554
+ header_name, colon, _ = header.partition(":")
555
+ if (
556
+ separator
557
+ and colon
558
+ and config_key.lower().endswith(".extraheader")
559
+ and header_name.strip().lower() == "authorization"
560
+ ):
561
+ new_cmdline[index] = "%s%s%s%s *****" % (config_key, separator, header_name, colon)
562
+ continue
554
563
  try:
555
564
  url = urlsplit(to_parse)
556
565
  # Remove password from the URL if present.
@@ -611,13 +620,17 @@ class RemoteProgress:
611
620
  self.error_lines: List[str] = []
612
621
  self.other_lines: List[str] = []
613
622
 
614
- def _parse_progress_line(self, line: AnyStr) -> None:
623
+ def _parse_progress_line(self, line: AnyStr) -> Optional[object]:
615
624
  """Parse progress information from the given line as retrieved by
616
625
  :manpage:`git-push(1)` or :manpage:`git-fetch(1)`.
617
626
 
618
627
  - Lines that do not contain progress info are stored in :attr:`other_lines`.
619
628
  - Lines that seem to contain an error (i.e. start with ``error:`` or ``fatal:``)
620
629
  are stored in :attr:`error_lines`.
630
+
631
+ The base implementation returns ``None``. Subclasses may return another
632
+ value for compatibility with existing overrides, but callers should treat
633
+ the return value as unspecified.
621
634
  """
622
635
  # handle
623
636
  # Counting objects: 4, done.
@@ -632,7 +645,7 @@ class RemoteProgress:
632
645
 
633
646
  if self._cur_line.startswith(("error:", "fatal:")):
634
647
  self.error_lines.append(self._cur_line)
635
- return
648
+ return None
636
649
 
637
650
  cur_count, max_count = None, None
638
651
  match = self.re_op_relative.match(line_str)
@@ -642,7 +655,7 @@ class RemoteProgress:
642
655
  if not match:
643
656
  self.line_dropped(line_str)
644
657
  self.other_lines.append(line_str)
645
- return
658
+ return None
646
659
  # END could not get match
647
660
 
648
661
  op_code = 0
@@ -673,7 +686,7 @@ class RemoteProgress:
673
686
  self.line_dropped(line_str)
674
687
  # Note: Don't add this line to the other lines, as we have to silently
675
688
  # drop it.
676
- return
689
+ return None
677
690
  # END handle op code
678
691
 
679
692
  # Figure out stage.
@@ -699,6 +712,7 @@ class RemoteProgress:
699
712
  max_count and float(max_count),
700
713
  message,
701
714
  )
715
+ return None
702
716
 
703
717
  def new_message_handler(self) -> Callable[[str], None]:
704
718
  """
@@ -708,7 +722,7 @@ class RemoteProgress:
708
722
  """
709
723
 
710
724
  def handler(line: AnyStr) -> None:
711
- return self._parse_progress_line(line.rstrip())
725
+ self._parse_progress_line(line.rstrip())
712
726
 
713
727
  # END handler
714
728
 
@@ -28,20 +28,26 @@ warn_unreachable = true
28
28
  implicit_reexport = true
29
29
  # strict = true
30
30
  # TODO: Remove when 'gitdb' is fully annotated.
31
- exclude = ["^git/ext/gitdb"]
31
+ exclude = ["^(gitdb|smmap)/"]
32
32
  [[tool.mypy.overrides]]
33
- module = "gitdb.*"
33
+ module = ["gitdb", "gitdb.*"]
34
+ follow_imports = "skip"
34
35
  ignore_missing_imports = true
35
36
 
36
37
  [tool.basedpyright]
37
38
  typeCheckingMode = "standard"
38
39
  pythonVersion = "3.7"
40
+ include = [
41
+ "git",
42
+ "test/deprecation",
43
+ ]
39
44
  extraPaths = [
40
- "git/ext/gitdb",
41
- "git/ext/gitdb/gitdb/ext/smmap",
45
+ "gitdb",
46
+ "smmap",
42
47
  ]
43
48
  exclude = [
44
- "git/ext/gitdb",
49
+ "gitdb",
50
+ "smmap",
45
51
  ]
46
52
 
47
53
  [tool.coverage.run]
@@ -57,6 +63,8 @@ line-length = 120
57
63
  # Exclude a variety of commonly ignored directories.
58
64
  exclude = [
59
65
  "git/ext/",
66
+ "gitdb/",
67
+ "smmap/",
60
68
  "build",
61
69
  "dist",
62
70
  ]
@@ -71,7 +71,7 @@ setup(
71
71
  author_email="byronimo@gmail.com, mtrier@gmail.com",
72
72
  license="BSD-3-Clause",
73
73
  url="https://github.com/gitpython-developers/GitPython",
74
- packages=find_packages(exclude=["test", "test.*"]),
74
+ packages=find_packages(include=["git", "git.*"]),
75
75
  include_package_data=True,
76
76
  package_dir={"git": "git"},
77
77
  python_requires=">=3.7",
@@ -108,5 +108,8 @@ setup(
108
108
  "Programming Language :: Python :: 3.10",
109
109
  "Programming Language :: Python :: 3.11",
110
110
  "Programming Language :: Python :: 3.12",
111
+ "Programming Language :: Python :: 3.13",
112
+ "Programming Language :: Python :: 3.14",
113
+ "Programming Language :: Python :: 3.15",
111
114
  ],
112
115
  )
@@ -1,4 +1,5 @@
1
1
  coverage[toml]
2
+ basedpyright==1.39.9 ; python_version >= "3.9" and sys_platform != "cygwin"
2
3
  ddt >= 1.1.1, != 1.4.3
3
4
  mock ; python_version < "3.8"
4
5
  mypy==1.18.2 ; python_version >= "3.9" # pin mypy version to avoid new errors
gitpython-3.1.55/VERSION DELETED
@@ -1 +0,0 @@
1
- 3.1.55
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes