GitPython 3.1.45__tar.gz → 3.1.47__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.45 → gitpython-3.1.47}/AUTHORS +1 -0
  2. {gitpython-3.1.45 → gitpython-3.1.47/GitPython.egg-info}/PKG-INFO +11 -11
  3. {gitpython-3.1.45 → gitpython-3.1.47}/GitPython.egg-info/requires.txt +4 -2
  4. {gitpython-3.1.45/GitPython.egg-info → gitpython-3.1.47}/PKG-INFO +11 -11
  5. {gitpython-3.1.45 → gitpython-3.1.47}/README.md +8 -8
  6. gitpython-3.1.47/VERSION +1 -0
  7. {gitpython-3.1.45 → gitpython-3.1.47}/doc/requirements.txt +1 -1
  8. {gitpython-3.1.45 → gitpython-3.1.47}/doc/source/changes.rst +29 -14
  9. {gitpython-3.1.45 → gitpython-3.1.47}/doc/source/tutorial.rst +6 -0
  10. {gitpython-3.1.45 → gitpython-3.1.47}/git/__init__.py +1 -1
  11. {gitpython-3.1.45 → gitpython-3.1.47}/git/cmd.py +39 -19
  12. {gitpython-3.1.45 → gitpython-3.1.47}/git/config.py +22 -10
  13. {gitpython-3.1.45 → gitpython-3.1.47}/git/diff.py +3 -2
  14. {gitpython-3.1.45 → gitpython-3.1.47}/git/index/base.py +8 -6
  15. {gitpython-3.1.45 → gitpython-3.1.47}/git/index/fun.py +12 -6
  16. {gitpython-3.1.45 → gitpython-3.1.47}/git/index/typ.py +16 -3
  17. {gitpython-3.1.45 → gitpython-3.1.47}/git/index/util.py +2 -2
  18. {gitpython-3.1.45 → gitpython-3.1.47}/git/objects/blob.py +2 -1
  19. {gitpython-3.1.45 → gitpython-3.1.47}/git/objects/commit.py +47 -9
  20. {gitpython-3.1.45 → gitpython-3.1.47}/git/objects/submodule/base.py +4 -4
  21. {gitpython-3.1.45 → gitpython-3.1.47}/git/objects/tree.py +4 -2
  22. {gitpython-3.1.45 → gitpython-3.1.47}/git/refs/head.py +1 -5
  23. {gitpython-3.1.45 → gitpython-3.1.47}/git/refs/log.py +1 -1
  24. {gitpython-3.1.45 → gitpython-3.1.47}/git/refs/reference.py +2 -1
  25. {gitpython-3.1.45 → gitpython-3.1.47}/git/refs/symbolic.py +16 -15
  26. {gitpython-3.1.45 → gitpython-3.1.47}/git/refs/tag.py +4 -4
  27. {gitpython-3.1.45 → gitpython-3.1.47}/git/repo/base.py +25 -22
  28. {gitpython-3.1.45 → gitpython-3.1.47}/git/repo/fun.py +1 -1
  29. {gitpython-3.1.45 → gitpython-3.1.47}/git/types.py +2 -2
  30. {gitpython-3.1.45 → gitpython-3.1.47}/git/util.py +16 -16
  31. {gitpython-3.1.45 → gitpython-3.1.47}/pyproject.toml +0 -1
  32. {gitpython-3.1.45 → gitpython-3.1.47}/test-requirements.txt +1 -1
  33. gitpython-3.1.45/VERSION +0 -1
  34. {gitpython-3.1.45 → gitpython-3.1.47}/CHANGES +0 -0
  35. {gitpython-3.1.45 → gitpython-3.1.47}/CONTRIBUTING.md +0 -0
  36. {gitpython-3.1.45 → gitpython-3.1.47}/GitPython.egg-info/SOURCES.txt +0 -0
  37. {gitpython-3.1.45 → gitpython-3.1.47}/GitPython.egg-info/dependency_links.txt +0 -0
  38. {gitpython-3.1.45 → gitpython-3.1.47}/GitPython.egg-info/not-zip-safe +0 -0
  39. {gitpython-3.1.45 → gitpython-3.1.47}/GitPython.egg-info/top_level.txt +0 -0
  40. {gitpython-3.1.45 → gitpython-3.1.47}/LICENSE +0 -0
  41. {gitpython-3.1.45 → gitpython-3.1.47}/MANIFEST.in +0 -0
  42. {gitpython-3.1.45 → gitpython-3.1.47}/doc/.gitignore +0 -0
  43. {gitpython-3.1.45 → gitpython-3.1.47}/doc/Makefile +0 -0
  44. {gitpython-3.1.45 → gitpython-3.1.47}/doc/source/conf.py +0 -0
  45. {gitpython-3.1.45 → gitpython-3.1.47}/doc/source/index.rst +0 -0
  46. {gitpython-3.1.45 → gitpython-3.1.47}/doc/source/intro.rst +0 -0
  47. {gitpython-3.1.45 → gitpython-3.1.47}/doc/source/quickstart.rst +0 -0
  48. {gitpython-3.1.45 → gitpython-3.1.47}/doc/source/reference.rst +0 -0
  49. {gitpython-3.1.45 → gitpython-3.1.47}/doc/source/roadmap.rst +0 -0
  50. {gitpython-3.1.45 → gitpython-3.1.47}/git/compat.py +0 -0
  51. {gitpython-3.1.45 → gitpython-3.1.47}/git/db.py +0 -0
  52. {gitpython-3.1.45 → gitpython-3.1.47}/git/exc.py +0 -0
  53. {gitpython-3.1.45 → gitpython-3.1.47}/git/index/__init__.py +0 -0
  54. {gitpython-3.1.45 → gitpython-3.1.47}/git/objects/__init__.py +0 -0
  55. {gitpython-3.1.45 → gitpython-3.1.47}/git/objects/base.py +0 -0
  56. {gitpython-3.1.45 → gitpython-3.1.47}/git/objects/fun.py +0 -0
  57. {gitpython-3.1.45 → gitpython-3.1.47}/git/objects/submodule/__init__.py +0 -0
  58. {gitpython-3.1.45 → gitpython-3.1.47}/git/objects/submodule/root.py +0 -0
  59. {gitpython-3.1.45 → gitpython-3.1.47}/git/objects/submodule/util.py +0 -0
  60. {gitpython-3.1.45 → gitpython-3.1.47}/git/objects/tag.py +0 -0
  61. {gitpython-3.1.45 → gitpython-3.1.47}/git/objects/util.py +0 -0
  62. {gitpython-3.1.45 → gitpython-3.1.47}/git/py.typed +0 -0
  63. {gitpython-3.1.45 → gitpython-3.1.47}/git/refs/__init__.py +0 -0
  64. {gitpython-3.1.45 → gitpython-3.1.47}/git/refs/remote.py +0 -0
  65. {gitpython-3.1.45 → gitpython-3.1.47}/git/remote.py +0 -0
  66. {gitpython-3.1.45 → gitpython-3.1.47}/git/repo/__init__.py +0 -0
  67. {gitpython-3.1.45 → gitpython-3.1.47}/requirements.txt +0 -0
  68. {gitpython-3.1.45 → gitpython-3.1.47}/setup.cfg +0 -0
  69. {gitpython-3.1.45 → gitpython-3.1.47}/setup.py +0 -0
@@ -56,5 +56,6 @@ Contributors are:
56
56
  -Ethan Lin <et.repositories _at_ gmail.com>
57
57
  -Jonas Scharpf <jonas.scharpf _at_ checkmk.com>
58
58
  -Gordon Marx
59
+ -Enji Cooper
59
60
 
60
61
  Portions derived from other open source works and are clearly marked.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: GitPython
3
- Version: 3.1.45
3
+ Version: 3.1.47
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
@@ -32,7 +32,7 @@ Provides-Extra: test
32
32
  Requires-Dist: coverage[toml]; extra == "test"
33
33
  Requires-Dist: ddt!=1.4.3,>=1.1.1; extra == "test"
34
34
  Requires-Dist: mock; python_version < "3.8" and extra == "test"
35
- Requires-Dist: mypy; extra == "test"
35
+ Requires-Dist: mypy==1.18.2; python_version >= "3.9" and extra == "test"
36
36
  Requires-Dist: pre-commit; extra == "test"
37
37
  Requires-Dist: pytest>=7.3.1; extra == "test"
38
38
  Requires-Dist: pytest-cov; extra == "test"
@@ -41,7 +41,7 @@ Requires-Dist: pytest-mock; extra == "test"
41
41
  Requires-Dist: pytest-sugar; extra == "test"
42
42
  Requires-Dist: typing-extensions; python_version < "3.11" and extra == "test"
43
43
  Provides-Extra: doc
44
- Requires-Dist: sphinx<7.2,>=7.1.2; extra == "doc"
44
+ Requires-Dist: sphinx<8,>=7.4.7; extra == "doc"
45
45
  Requires-Dist: sphinx_rtd_theme; extra == "doc"
46
46
  Requires-Dist: sphinx-autodoc-typehints; extra == "doc"
47
47
  Dynamic: author
@@ -105,7 +105,7 @@ by setting the `GIT_PYTHON_GIT_EXECUTABLE=<path/to/git>` environment variable.
105
105
  - Git (1.7.x or newer)
106
106
  - Python >= 3.7
107
107
 
108
- The list of dependencies are listed in `./requirements.txt` and `./test-requirements.txt`.
108
+ The list of dependencies are listed in [`./requirements.txt`](https://github.com/gitpython-developers/GitPython/blob/main/requirements.txt) and [`./test-requirements.txt`](https://github.com/gitpython-developers/GitPython/blob/main/test-requirements.txt).
109
109
  The installer takes care of installing them for you.
110
110
 
111
111
  ### INSTALL
@@ -239,7 +239,7 @@ Style and formatting checks, and running tests on all the different supported Py
239
239
 
240
240
  #### Configuration files
241
241
 
242
- Specific tools are all configured in the `./pyproject.toml` file:
242
+ Specific tools are all configured in the [`./pyproject.toml`](https://github.com/gitpython-developers/GitPython/blob/main/pyproject.toml) file:
243
243
 
244
244
  - `pytest` (test runner)
245
245
  - `coverage.py` (code coverage)
@@ -248,9 +248,9 @@ Specific tools are all configured in the `./pyproject.toml` file:
248
248
 
249
249
  Orchestration tools:
250
250
 
251
- - Configuration for `pre-commit` is in the `./.pre-commit-config.yaml` file.
252
- - Configuration for `tox` is in `./tox.ini`.
253
- - Configuration for GitHub Actions (CI) is in files inside `./.github/workflows/`.
251
+ - Configuration for `pre-commit` is in the [`./.pre-commit-config.yaml`](https://github.com/gitpython-developers/GitPython/blob/main/.pre-commit-config.yaml) file.
252
+ - Configuration for `tox` is in [`./tox.ini`](https://github.com/gitpython-developers/GitPython/blob/main/tox.ini).
253
+ - Configuration for GitHub Actions (CI) is in files inside [`./.github/workflows/`](https://github.com/gitpython-developers/GitPython/tree/main/.github/workflows).
254
254
 
255
255
  ### Contributions
256
256
 
@@ -271,8 +271,8 @@ Please have a look at the [contributions file][contributing].
271
271
 
272
272
  ### How to make a new release
273
273
 
274
- 1. Update/verify the **version** in the `VERSION` file.
275
- 2. Update/verify that the `doc/source/changes.rst` changelog file was updated. It should include a link to the forthcoming release page: `https://github.com/gitpython-developers/GitPython/releases/tag/<version>`
274
+ 1. Update/verify the **version** in the [`VERSION`](https://github.com/gitpython-developers/GitPython/blob/main/VERSION) file.
275
+ 2. Update/verify that the [`doc/source/changes.rst`](https://github.com/gitpython-developers/GitPython/blob/main/doc/source/changes.rst) changelog file was updated. It should include a link to the forthcoming release page: `https://github.com/gitpython-developers/GitPython/releases/tag/<version>`
276
276
  3. Commit everything.
277
277
  4. Run `git tag -s <version>` to tag the version in Git.
278
278
  5. _Optionally_ create and activate a [virtual environment](https://packaging.python.org/en/latest/guides/installing-using-pip-and-virtual-environments/#creating-a-virtual-environment). (Then the next step can install `build` and `twine`.)
@@ -299,7 +299,7 @@ Please have a look at the [contributions file][contributing].
299
299
 
300
300
  [3-Clause BSD License](https://opensource.org/license/bsd-3-clause/), also known as the New BSD License. See the [LICENSE file][license].
301
301
 
302
- One file exclusively used for fuzz testing is subject to [a separate license, detailed here](./fuzzing/README.md#license).
302
+ One file exclusively used for fuzz testing is subject to [a separate license, detailed here](https://github.com/gitpython-developers/GitPython/blob/main/fuzzing/README.md#license).
303
303
  This file is not included in the wheel or sdist packages published by the maintainers of GitPython.
304
304
 
305
305
  [contributing]: https://github.com/gitpython-developers/GitPython/blob/main/CONTRIBUTING.md
@@ -4,14 +4,13 @@ gitdb<5,>=4.0.1
4
4
  typing-extensions>=3.10.0.2
5
5
 
6
6
  [doc]
7
- sphinx<7.2,>=7.1.2
7
+ sphinx<8,>=7.4.7
8
8
  sphinx_rtd_theme
9
9
  sphinx-autodoc-typehints
10
10
 
11
11
  [test]
12
12
  coverage[toml]
13
13
  ddt!=1.4.3,>=1.1.1
14
- mypy
15
14
  pre-commit
16
15
  pytest>=7.3.1
17
16
  pytest-cov
@@ -24,3 +23,6 @@ typing-extensions
24
23
 
25
24
  [test:python_version < "3.8"]
26
25
  mock
26
+
27
+ [test:python_version >= "3.9"]
28
+ mypy==1.18.2
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: GitPython
3
- Version: 3.1.45
3
+ Version: 3.1.47
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
@@ -32,7 +32,7 @@ Provides-Extra: test
32
32
  Requires-Dist: coverage[toml]; extra == "test"
33
33
  Requires-Dist: ddt!=1.4.3,>=1.1.1; extra == "test"
34
34
  Requires-Dist: mock; python_version < "3.8" and extra == "test"
35
- Requires-Dist: mypy; extra == "test"
35
+ Requires-Dist: mypy==1.18.2; python_version >= "3.9" and extra == "test"
36
36
  Requires-Dist: pre-commit; extra == "test"
37
37
  Requires-Dist: pytest>=7.3.1; extra == "test"
38
38
  Requires-Dist: pytest-cov; extra == "test"
@@ -41,7 +41,7 @@ Requires-Dist: pytest-mock; extra == "test"
41
41
  Requires-Dist: pytest-sugar; extra == "test"
42
42
  Requires-Dist: typing-extensions; python_version < "3.11" and extra == "test"
43
43
  Provides-Extra: doc
44
- Requires-Dist: sphinx<7.2,>=7.1.2; extra == "doc"
44
+ Requires-Dist: sphinx<8,>=7.4.7; extra == "doc"
45
45
  Requires-Dist: sphinx_rtd_theme; extra == "doc"
46
46
  Requires-Dist: sphinx-autodoc-typehints; extra == "doc"
47
47
  Dynamic: author
@@ -105,7 +105,7 @@ by setting the `GIT_PYTHON_GIT_EXECUTABLE=<path/to/git>` environment variable.
105
105
  - Git (1.7.x or newer)
106
106
  - Python >= 3.7
107
107
 
108
- The list of dependencies are listed in `./requirements.txt` and `./test-requirements.txt`.
108
+ The list of dependencies are listed in [`./requirements.txt`](https://github.com/gitpython-developers/GitPython/blob/main/requirements.txt) and [`./test-requirements.txt`](https://github.com/gitpython-developers/GitPython/blob/main/test-requirements.txt).
109
109
  The installer takes care of installing them for you.
110
110
 
111
111
  ### INSTALL
@@ -239,7 +239,7 @@ Style and formatting checks, and running tests on all the different supported Py
239
239
 
240
240
  #### Configuration files
241
241
 
242
- Specific tools are all configured in the `./pyproject.toml` file:
242
+ Specific tools are all configured in the [`./pyproject.toml`](https://github.com/gitpython-developers/GitPython/blob/main/pyproject.toml) file:
243
243
 
244
244
  - `pytest` (test runner)
245
245
  - `coverage.py` (code coverage)
@@ -248,9 +248,9 @@ Specific tools are all configured in the `./pyproject.toml` file:
248
248
 
249
249
  Orchestration tools:
250
250
 
251
- - Configuration for `pre-commit` is in the `./.pre-commit-config.yaml` file.
252
- - Configuration for `tox` is in `./tox.ini`.
253
- - Configuration for GitHub Actions (CI) is in files inside `./.github/workflows/`.
251
+ - Configuration for `pre-commit` is in the [`./.pre-commit-config.yaml`](https://github.com/gitpython-developers/GitPython/blob/main/.pre-commit-config.yaml) file.
252
+ - Configuration for `tox` is in [`./tox.ini`](https://github.com/gitpython-developers/GitPython/blob/main/tox.ini).
253
+ - Configuration for GitHub Actions (CI) is in files inside [`./.github/workflows/`](https://github.com/gitpython-developers/GitPython/tree/main/.github/workflows).
254
254
 
255
255
  ### Contributions
256
256
 
@@ -271,8 +271,8 @@ Please have a look at the [contributions file][contributing].
271
271
 
272
272
  ### How to make a new release
273
273
 
274
- 1. Update/verify the **version** in the `VERSION` file.
275
- 2. Update/verify that the `doc/source/changes.rst` changelog file was updated. It should include a link to the forthcoming release page: `https://github.com/gitpython-developers/GitPython/releases/tag/<version>`
274
+ 1. Update/verify the **version** in the [`VERSION`](https://github.com/gitpython-developers/GitPython/blob/main/VERSION) file.
275
+ 2. Update/verify that the [`doc/source/changes.rst`](https://github.com/gitpython-developers/GitPython/blob/main/doc/source/changes.rst) changelog file was updated. It should include a link to the forthcoming release page: `https://github.com/gitpython-developers/GitPython/releases/tag/<version>`
276
276
  3. Commit everything.
277
277
  4. Run `git tag -s <version>` to tag the version in Git.
278
278
  5. _Optionally_ create and activate a [virtual environment](https://packaging.python.org/en/latest/guides/installing-using-pip-and-virtual-environments/#creating-a-virtual-environment). (Then the next step can install `build` and `twine`.)
@@ -299,7 +299,7 @@ Please have a look at the [contributions file][contributing].
299
299
 
300
300
  [3-Clause BSD License](https://opensource.org/license/bsd-3-clause/), also known as the New BSD License. See the [LICENSE file][license].
301
301
 
302
- One file exclusively used for fuzz testing is subject to [a separate license, detailed here](./fuzzing/README.md#license).
302
+ One file exclusively used for fuzz testing is subject to [a separate license, detailed here](https://github.com/gitpython-developers/GitPython/blob/main/fuzzing/README.md#license).
303
303
  This file is not included in the wheel or sdist packages published by the maintainers of GitPython.
304
304
 
305
305
  [contributing]: https://github.com/gitpython-developers/GitPython/blob/main/CONTRIBUTING.md
@@ -46,7 +46,7 @@ by setting the `GIT_PYTHON_GIT_EXECUTABLE=<path/to/git>` environment variable.
46
46
  - Git (1.7.x or newer)
47
47
  - Python >= 3.7
48
48
 
49
- The list of dependencies are listed in `./requirements.txt` and `./test-requirements.txt`.
49
+ The list of dependencies are listed in [`./requirements.txt`](https://github.com/gitpython-developers/GitPython/blob/main/requirements.txt) and [`./test-requirements.txt`](https://github.com/gitpython-developers/GitPython/blob/main/test-requirements.txt).
50
50
  The installer takes care of installing them for you.
51
51
 
52
52
  ### INSTALL
@@ -180,7 +180,7 @@ Style and formatting checks, and running tests on all the different supported Py
180
180
 
181
181
  #### Configuration files
182
182
 
183
- Specific tools are all configured in the `./pyproject.toml` file:
183
+ Specific tools are all configured in the [`./pyproject.toml`](https://github.com/gitpython-developers/GitPython/blob/main/pyproject.toml) file:
184
184
 
185
185
  - `pytest` (test runner)
186
186
  - `coverage.py` (code coverage)
@@ -189,9 +189,9 @@ Specific tools are all configured in the `./pyproject.toml` file:
189
189
 
190
190
  Orchestration tools:
191
191
 
192
- - Configuration for `pre-commit` is in the `./.pre-commit-config.yaml` file.
193
- - Configuration for `tox` is in `./tox.ini`.
194
- - Configuration for GitHub Actions (CI) is in files inside `./.github/workflows/`.
192
+ - Configuration for `pre-commit` is in the [`./.pre-commit-config.yaml`](https://github.com/gitpython-developers/GitPython/blob/main/.pre-commit-config.yaml) file.
193
+ - Configuration for `tox` is in [`./tox.ini`](https://github.com/gitpython-developers/GitPython/blob/main/tox.ini).
194
+ - Configuration for GitHub Actions (CI) is in files inside [`./.github/workflows/`](https://github.com/gitpython-developers/GitPython/tree/main/.github/workflows).
195
195
 
196
196
  ### Contributions
197
197
 
@@ -212,8 +212,8 @@ Please have a look at the [contributions file][contributing].
212
212
 
213
213
  ### How to make a new release
214
214
 
215
- 1. Update/verify the **version** in the `VERSION` file.
216
- 2. Update/verify that the `doc/source/changes.rst` changelog file was updated. It should include a link to the forthcoming release page: `https://github.com/gitpython-developers/GitPython/releases/tag/<version>`
215
+ 1. Update/verify the **version** in the [`VERSION`](https://github.com/gitpython-developers/GitPython/blob/main/VERSION) file.
216
+ 2. Update/verify that the [`doc/source/changes.rst`](https://github.com/gitpython-developers/GitPython/blob/main/doc/source/changes.rst) changelog file was updated. It should include a link to the forthcoming release page: `https://github.com/gitpython-developers/GitPython/releases/tag/<version>`
217
217
  3. Commit everything.
218
218
  4. Run `git tag -s <version>` to tag the version in Git.
219
219
  5. _Optionally_ create and activate a [virtual environment](https://packaging.python.org/en/latest/guides/installing-using-pip-and-virtual-environments/#creating-a-virtual-environment). (Then the next step can install `build` and `twine`.)
@@ -240,7 +240,7 @@ Please have a look at the [contributions file][contributing].
240
240
 
241
241
  [3-Clause BSD License](https://opensource.org/license/bsd-3-clause/), also known as the New BSD License. See the [LICENSE file][license].
242
242
 
243
- One file exclusively used for fuzz testing is subject to [a separate license, detailed here](./fuzzing/README.md#license).
243
+ One file exclusively used for fuzz testing is subject to [a separate license, detailed here](https://github.com/gitpython-developers/GitPython/blob/main/fuzzing/README.md#license).
244
244
  This file is not included in the wheel or sdist packages published by the maintainers of GitPython.
245
245
 
246
246
  [contributing]: https://github.com/gitpython-developers/GitPython/blob/main/CONTRIBUTING.md
@@ -0,0 +1 @@
1
+ 3.1.47
@@ -1,3 +1,3 @@
1
- sphinx >= 7.1.2, < 7.2
1
+ sphinx >= 7.4.7, < 8
2
2
  sphinx_rtd_theme
3
3
  sphinx-autodoc-typehints
@@ -2,6 +2,21 @@
2
2
  Changelog
3
3
  =========
4
4
 
5
+ 3.1.47
6
+ ======
7
+
8
+ Address various security issues related to bypassing injection-protection
9
+ of unsafe Git flags.
10
+
11
+ See the following for all changes.
12
+ https://github.com/gitpython-developers/GitPython/releases/tag/3.1.47
13
+
14
+ 3.1.46
15
+ ======
16
+
17
+ See the following for all changes.
18
+ https://github.com/gitpython-developers/GitPython/releases/tag/3.1.46
19
+
5
20
  3.1.45
6
21
  ======
7
22
 
@@ -111,7 +126,7 @@ https://github.com/gitpython-developers/gitpython/milestone/61?closed=1
111
126
  but a necessary fix for https://github.com/gitpython-developers/GitPython/issues/1515.
112
127
  Please take a look at the PR for more information and how to bypass these protections
113
128
  in case they cause breakage: https://github.com/gitpython-developers/GitPython/pull/1521.
114
-
129
+
115
130
 
116
131
  See the following for all changes.
117
132
  https://github.com/gitpython-developers/gitpython/milestone/60?closed=1
@@ -176,38 +191,38 @@ https://github.com/gitpython-developers/gitpython/milestone/53?closed=1
176
191
  * General:
177
192
 
178
193
  - Remove python 3.6 support
179
-
194
+
180
195
  - Remove distutils ahead of deprecation in standard library.
181
-
196
+
182
197
  - Update sphinx to 4.1.12 and use autodoc-typehints.
183
-
198
+
184
199
  - Include README as long_description on PyPI
185
-
200
+
186
201
  - Test against earliest and latest minor version available on Github Actions (e.g. 3.9.0 and 3.9.7)
187
-
202
+
188
203
 
189
204
  * Typing:
190
205
 
191
206
  - Add types to ALL functions.
192
-
207
+
193
208
  - Ensure py.typed is collected.
194
-
209
+
195
210
  - Increase mypy strictness with disallow_untyped_defs, warn_redundant_casts, warn_unreachable.
196
-
211
+
197
212
  - Use typing.NamedTuple and typing.OrderedDict now 3.6 dropped.
198
-
213
+
199
214
  - Make Protocol classes ABCs at runtime due to new behaviour/bug in 3.9.7 & 3.10.0-rc1
200
-
215
+
201
216
  - Remove use of typing.TypeGuard until later release, to allow dependent libs time to update.
202
-
217
+
203
218
  - Tracking issue: https://github.com/gitpython-developers/GitPython/issues/1095
204
219
 
205
220
  * Runtime improvements:
206
221
 
207
222
  - Add clone_multi_options support to submodule.add()
208
-
223
+
209
224
  - Delay calling get_user_id() unless essential, to support sand-boxed environments.
210
-
225
+
211
226
  - Add timeout to handle_process_output(), in case thread.join() hangs.
212
227
 
213
228
  See the following for details:
@@ -513,6 +513,12 @@ The GitDB is a pure-python implementation of the git object database. It is the
513
513
 
514
514
  repo = Repo("path/to/repo", odbt=GitDB)
515
515
 
516
+ .. warning::
517
+ ``GitDB`` may fail or become extremely slow when traversing trees in
518
+ repositories with very large commits (thousands of changed files in a
519
+ single commit). If you encounter ``RecursionError`` or excessive
520
+ slowness during tree traversal, switch to ``GitCmdObjectDB`` instead.
521
+
516
522
 
517
523
  GitCmdObjectDB
518
524
  ==============
@@ -86,7 +86,7 @@ __all__ = [
86
86
  "to_hex_sha",
87
87
  ]
88
88
 
89
- __version__ = '3.1.45'
89
+ __version__ = '3.1.47'
90
90
 
91
91
  from typing import Any, List, Optional, Sequence, TYPE_CHECKING, Tuple, Union
92
92
 
@@ -368,8 +368,12 @@ class _AutoInterrupt:
368
368
  status = proc.wait() # Ensure the process goes away.
369
369
 
370
370
  self.status = self._status_code_if_terminate or status
371
- except OSError as ex:
372
- _logger.info("Ignored error after process had died: %r", ex)
371
+ except (OSError, AttributeError) as ex:
372
+ # On interpreter shutdown (notably on Windows), parts of the stdlib used by
373
+ # subprocess can already be torn down (e.g. `subprocess._winapi` becomes None),
374
+ # which can cause AttributeError during terminate(). In that case, we prefer
375
+ # to silently ignore to avoid noisy "Exception ignored in: __del__" messages.
376
+ _logger.info("Ignored error while terminating process: %r", ex)
373
377
  # END exception handling
374
378
 
375
379
  def __del__(self) -> None:
@@ -940,6 +944,21 @@ class Git(metaclass=_GitMeta):
940
944
  f"The `{protocol}::` protocol looks suspicious, use `allow_unsafe_protocols=True` to allow it."
941
945
  )
942
946
 
947
+ @classmethod
948
+ def _canonicalize_option_name(cls, option: str) -> str:
949
+ """Return the option name used for unsafe-option checks.
950
+
951
+ Examples:
952
+ ``"--upload-pack=/tmp/helper"`` -> ``"upload-pack"``
953
+ ``"upload_pack"`` -> ``"upload-pack"``
954
+ ``"--config core.filemode=false"`` -> ``"config"``
955
+ """
956
+ option_name = option.lstrip("-").split("=", 1)[0]
957
+ option_tokens = option_name.split(None, 1)
958
+ if not option_tokens:
959
+ return ""
960
+ return dashify(option_tokens[0])
961
+
943
962
  @classmethod
944
963
  def check_unsafe_options(cls, options: List[str], unsafe_options: List[str]) -> None:
945
964
  """Check for unsafe options.
@@ -947,15 +966,12 @@ class Git(metaclass=_GitMeta):
947
966
  Some options that are passed to ``git <command>`` can be used to execute
948
967
  arbitrary commands. These are blocked by default.
949
968
  """
950
- # Options can be of the form `foo`, `--foo bar`, or `--foo=bar`, so we need to
951
- # check if they start with "--foo" or if they are equal to "foo".
952
- bare_unsafe_options = [option.lstrip("-") for option in unsafe_options]
969
+ # Options can be of the form `foo`, `--foo`, `--foo bar`, or `--foo=bar`.
970
+ canonical_unsafe_options = {cls._canonicalize_option_name(option): option for option in unsafe_options}
953
971
  for option in options:
954
- for unsafe_option, bare_option in zip(unsafe_options, bare_unsafe_options):
955
- if option.startswith(unsafe_option) or option == bare_option:
956
- raise UnsafeOptionError(
957
- f"{unsafe_option} is not allowed, use `allow_unsafe_options=True` to allow it."
958
- )
972
+ unsafe_option = canonical_unsafe_options.get(cls._canonicalize_option_name(option))
973
+ if unsafe_option is not None:
974
+ raise UnsafeOptionError(f"{unsafe_option} is not allowed, use `allow_unsafe_options=True` to allow it.")
959
975
 
960
976
  AutoInterrupt: TypeAlias = _AutoInterrupt
961
977
 
@@ -1360,25 +1376,29 @@ class Git(metaclass=_GitMeta):
1360
1376
  if output_stream is None:
1361
1377
  stdout_value, stderr_value = communicate()
1362
1378
  # Strip trailing "\n".
1363
- if stdout_value.endswith(newline) and strip_newline_in_stdout: # type: ignore[arg-type]
1379
+ if stdout_value is not None and stdout_value.endswith(newline) and strip_newline_in_stdout: # type: ignore[arg-type]
1364
1380
  stdout_value = stdout_value[:-1]
1365
- if stderr_value.endswith(newline): # type: ignore[arg-type]
1381
+ if stderr_value is not None and stderr_value.endswith(newline): # type: ignore[arg-type]
1366
1382
  stderr_value = stderr_value[:-1]
1367
1383
 
1368
1384
  status = proc.returncode
1369
1385
  else:
1370
1386
  max_chunk_size = max_chunk_size if max_chunk_size and max_chunk_size > 0 else io.DEFAULT_BUFFER_SIZE
1371
- stream_copy(proc.stdout, output_stream, max_chunk_size)
1372
- stdout_value = proc.stdout.read()
1373
- stderr_value = proc.stderr.read()
1387
+ if proc.stdout is not None:
1388
+ stream_copy(proc.stdout, output_stream, max_chunk_size)
1389
+ stdout_value = proc.stdout.read()
1390
+ if proc.stderr is not None:
1391
+ stderr_value = proc.stderr.read()
1374
1392
  # Strip trailing "\n".
1375
- if stderr_value.endswith(newline): # type: ignore[arg-type]
1393
+ if stderr_value is not None and stderr_value.endswith(newline): # type: ignore[arg-type]
1376
1394
  stderr_value = stderr_value[:-1]
1377
1395
  status = proc.wait()
1378
1396
  # END stdout handling
1379
1397
  finally:
1380
- proc.stdout.close()
1381
- proc.stderr.close()
1398
+ if proc.stdout is not None:
1399
+ proc.stdout.close()
1400
+ if proc.stderr is not None:
1401
+ proc.stderr.close()
1382
1402
 
1383
1403
  if self.GIT_PYTHON_TRACE == "full":
1384
1404
  cmdstr = " ".join(redacted_command)
@@ -1568,7 +1588,7 @@ class Git(metaclass=_GitMeta):
1568
1588
 
1569
1589
  turns into::
1570
1590
 
1571
- git rev-list max-count 10 --header master
1591
+ git rev-list --max-count=10 --header=master
1572
1592
 
1573
1593
  :return:
1574
1594
  Same as :meth:`execute`. If no args are given, used :meth:`execute`'s
@@ -66,7 +66,7 @@ _logger = logging.getLogger(__name__)
66
66
  CONFIG_LEVELS: ConfigLevels_Tup = ("system", "user", "global", "repository")
67
67
  """The configuration level of a configuration file."""
68
68
 
69
- CONDITIONAL_INCLUDE_REGEXP = re.compile(r"(?<=includeIf )\"(gitdir|gitdir/i|onbranch):(.+)\"")
69
+ CONDITIONAL_INCLUDE_REGEXP = re.compile(r"(?<=includeIf )\"(gitdir|gitdir/i|onbranch|hasconfig:remote\.\*\.url):(.+)\"")
70
70
  """Section pattern to detect conditional includes.
71
71
 
72
72
  See: https://git-scm.com/docs/git-config#_conditional_includes
@@ -549,11 +549,21 @@ class GitConfigParser(cp.RawConfigParser, metaclass=MetaParserBuilder):
549
549
  :return:
550
550
  The list of paths, where each path is a tuple of (option, value).
551
551
  """
552
+
553
+ def _all_items(section: str) -> List[Tuple[str, str]]:
554
+ """Return all (key, value) pairs for a section, including duplicate keys."""
555
+ return [
556
+ (key, value)
557
+ for key, values in self._sections[section].items_all()
558
+ if key != "__name__"
559
+ for value in values
560
+ ]
561
+
552
562
  paths = []
553
563
 
554
564
  for section in self.sections():
555
565
  if section == "include":
556
- paths += self.items(section)
566
+ paths += _all_items(section)
557
567
 
558
568
  match = CONDITIONAL_INCLUDE_REGEXP.search(section)
559
569
  if match is None or self._repo is None:
@@ -574,12 +584,12 @@ class GitConfigParser(cp.RawConfigParser, metaclass=MetaParserBuilder):
574
584
  if keyword.endswith("/i"):
575
585
  value = re.sub(
576
586
  r"[a-zA-Z]",
577
- lambda m: "[{}{}]".format(m.group().lower(), m.group().upper()),
587
+ lambda m: f"[{m.group().lower()!r}{m.group().upper()!r}]",
578
588
  value,
579
589
  )
580
590
  if self._repo.git_dir:
581
- if fnmatch.fnmatchcase(str(self._repo.git_dir), value):
582
- paths += self.items(section)
591
+ if fnmatch.fnmatchcase(os.fspath(self._repo.git_dir), value):
592
+ paths += _all_items(section)
583
593
 
584
594
  elif keyword == "onbranch":
585
595
  try:
@@ -589,8 +599,12 @@ class GitConfigParser(cp.RawConfigParser, metaclass=MetaParserBuilder):
589
599
  continue
590
600
 
591
601
  if fnmatch.fnmatchcase(branch_name, value):
592
- paths += self.items(section)
593
-
602
+ paths += _all_items(section)
603
+ elif keyword == "hasconfig:remote.*.url":
604
+ for remote in self._repo.remotes:
605
+ if fnmatch.fnmatchcase(remote.url, value):
606
+ paths += _all_items(section)
607
+ break
594
608
  return paths
595
609
 
596
610
  def read(self) -> None: # type: ignore[override]
@@ -629,8 +643,6 @@ class GitConfigParser(cp.RawConfigParser, metaclass=MetaParserBuilder):
629
643
  file_path = cast(IO[bytes], file_path)
630
644
  self._read(file_path, file_path.name)
631
645
  else:
632
- # Assume a path if it is not a file-object.
633
- file_path = cast(PathLike, file_path)
634
646
  try:
635
647
  with open(file_path, "rb") as fp:
636
648
  file_ok = True
@@ -764,7 +776,7 @@ class GitConfigParser(cp.RawConfigParser, metaclass=MetaParserBuilder):
764
776
  if self.read_only:
765
777
  raise IOError("Cannot execute non-constant method %s.%s" % (self, method_name))
766
778
 
767
- def add_section(self, section: str) -> None:
779
+ def add_section(self, section: "cp._SectionName") -> None:
768
780
  """Assures added options will stay in order."""
769
781
  return super().add_section(section)
770
782
 
@@ -23,13 +23,14 @@ from typing import (
23
23
  List,
24
24
  Match,
25
25
  Optional,
26
+ Sequence,
26
27
  Tuple,
27
28
  TYPE_CHECKING,
28
29
  TypeVar,
29
30
  Union,
30
31
  cast,
31
32
  )
32
- from git.types import Literal, PathLike
33
+ from git.types import PathLike, Literal
33
34
 
34
35
  if TYPE_CHECKING:
35
36
  from subprocess import Popen
@@ -289,7 +290,7 @@ class DiffIndex(List[T_Diff]):
289
290
  The class improves the diff handling convenience.
290
291
  """
291
292
 
292
- change_type = ("A", "C", "D", "R", "M", "T")
293
+ change_type: Sequence[Literal["A", "C", "D", "R", "M", "T"]] = ("A", "C", "D", "R", "M", "T") # noqa: F821
293
294
  """Change type invariant identifying possible ways a blob can have changed:
294
295
 
295
296
  * ``A`` = Added
@@ -407,7 +407,7 @@ class IndexFile(LazyMixin, git_diff.Diffable, Serializable):
407
407
  r = str(self.repo.working_tree_dir)
408
408
  rs = r + os.sep
409
409
  for path in paths:
410
- abs_path = str(path)
410
+ abs_path = os.fspath(path)
411
411
  if not osp.isabs(abs_path):
412
412
  abs_path = osp.join(r, path)
413
413
  # END make absolute path
@@ -656,10 +656,10 @@ class IndexFile(LazyMixin, git_diff.Diffable, Serializable):
656
656
  return path
657
657
  if self.repo.bare:
658
658
  raise InvalidGitRepositoryError("require non-bare repository")
659
- if not osp.normpath(str(path)).startswith(str(self.repo.working_tree_dir)):
659
+ if not osp.normpath(path).startswith(str(self.repo.working_tree_dir)):
660
660
  raise ValueError("Absolute path %r is not in git repository at %r" % (path, self.repo.working_tree_dir))
661
661
  result = os.path.relpath(path, self.repo.working_tree_dir)
662
- if str(path).endswith(os.sep) and not result.endswith(os.sep):
662
+ if os.fspath(path).endswith(os.sep) and not result.endswith(os.sep):
663
663
  result += os.sep
664
664
  return result
665
665
 
@@ -1036,7 +1036,7 @@ class IndexFile(LazyMixin, git_diff.Diffable, Serializable):
1036
1036
  args.append("--")
1037
1037
 
1038
1038
  # Preprocess paths.
1039
- paths = self._items_to_rela_paths(items)
1039
+ paths = list(map(os.fspath, self._items_to_rela_paths(items))) # type: ignore[arg-type]
1040
1040
  removed_paths = self.repo.git.rm(args, paths, **kwargs).splitlines()
1041
1041
 
1042
1042
  # Process output to gain proper paths.
@@ -1133,6 +1133,7 @@ class IndexFile(LazyMixin, git_diff.Diffable, Serializable):
1133
1133
  author_date: Union[datetime.datetime, str, None] = None,
1134
1134
  commit_date: Union[datetime.datetime, str, None] = None,
1135
1135
  skip_hooks: bool = False,
1136
+ trailers: Union[None, "Dict[str, str]", "List[Tuple[str, str]]"] = None,
1136
1137
  ) -> Commit:
1137
1138
  """Commit the current default index file, creating a
1138
1139
  :class:`~git.objects.commit.Commit` object.
@@ -1169,6 +1170,7 @@ class IndexFile(LazyMixin, git_diff.Diffable, Serializable):
1169
1170
  committer=committer,
1170
1171
  author_date=author_date,
1171
1172
  commit_date=commit_date,
1173
+ trailers=trailers,
1172
1174
  )
1173
1175
  if not skip_hooks:
1174
1176
  run_commit_hook("post-commit", self)
@@ -1359,11 +1361,11 @@ class IndexFile(LazyMixin, git_diff.Diffable, Serializable):
1359
1361
  try:
1360
1362
  self.entries[(co_path, 0)]
1361
1363
  except KeyError:
1362
- folder = str(co_path)
1364
+ folder = co_path
1363
1365
  if not folder.endswith("/"):
1364
1366
  folder += "/"
1365
1367
  for entry in self.entries.values():
1366
- if str(entry.path).startswith(folder):
1368
+ if os.fspath(entry.path).startswith(folder):
1367
1369
  p = entry.path
1368
1370
  self._write_path_to_stdin(proc, p, p, make_exc, fprogress, read_from_stdout=False)
1369
1371
  checked_out_files.append(p)