GitPython 3.1.42__py3-none-any.whl → 3.1.44__py3-none-any.whl

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.
@@ -54,5 +54,6 @@ Contributors are:
54
54
  -Wenhan Zhu <wzhu.cosmos _at_ gmail.com>
55
55
  -Eliah Kagan <eliah.kagan _at_ gmail.com>
56
56
  -Ethan Lin <et.repositories _at_ gmail.com>
57
+ -Jonas Scharpf <jonas.scharpf _at_ checkmk.com>
57
58
 
58
59
  Portions derived from other open source works and are clearly marked.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: GitPython
3
- Version: 3.1.42
3
+ Version: 3.1.44
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
@@ -27,20 +27,24 @@ Requires-Python: >=3.7
27
27
  Description-Content-Type: text/markdown
28
28
  License-File: LICENSE
29
29
  License-File: AUTHORS
30
- Requires-Dist: gitdb <5,>=4.0.1
31
- Requires-Dist: typing-extensions >=3.7.4.3 ; python_version < "3.8"
30
+ Requires-Dist: gitdb<5,>=4.0.1
31
+ Requires-Dist: typing-extensions>=3.7.4.3; python_version < "3.8"
32
32
  Provides-Extra: test
33
- Requires-Dist: black ; extra == 'test'
34
- Requires-Dist: coverage[toml] ; extra == 'test'
35
- Requires-Dist: ddt !=1.4.3,>=1.1.1 ; extra == 'test'
36
- Requires-Dist: mypy ; extra == 'test'
37
- Requires-Dist: pre-commit ; extra == 'test'
38
- Requires-Dist: pytest >=7.3.1 ; extra == 'test'
39
- Requires-Dist: pytest-cov ; extra == 'test'
40
- Requires-Dist: pytest-instafail ; extra == 'test'
41
- Requires-Dist: pytest-mock ; extra == 'test'
42
- Requires-Dist: pytest-sugar ; extra == 'test'
43
- Requires-Dist: mock ; (python_version < "3.8") and extra == 'test'
33
+ Requires-Dist: coverage[toml]; extra == "test"
34
+ Requires-Dist: ddt!=1.4.3,>=1.1.1; extra == "test"
35
+ Requires-Dist: mock; python_version < "3.8" and extra == "test"
36
+ Requires-Dist: mypy; extra == "test"
37
+ Requires-Dist: pre-commit; extra == "test"
38
+ Requires-Dist: pytest>=7.3.1; extra == "test"
39
+ Requires-Dist: pytest-cov; extra == "test"
40
+ Requires-Dist: pytest-instafail; extra == "test"
41
+ Requires-Dist: pytest-mock; extra == "test"
42
+ Requires-Dist: pytest-sugar; extra == "test"
43
+ Requires-Dist: typing-extensions; python_version < "3.11" and extra == "test"
44
+ Provides-Extra: doc
45
+ Requires-Dist: sphinx<7.2,>=7.1.2; extra == "doc"
46
+ Requires-Dist: sphinx_rtd_theme; extra == "doc"
47
+ Requires-Dist: sphinx-autodoc-typehints; extra == "doc"
44
48
 
45
49
  ![Python package](https://github.com/gitpython-developers/GitPython/workflows/Python%20package/badge.svg)
46
50
  [![Documentation Status](https://readthedocs.org/projects/gitpython/badge/?version=stable)](https://readthedocs.org/projects/gitpython/?badge=stable)
@@ -61,7 +65,7 @@ probably the skills to scratch that itch of mine: implement `git` in a way that
61
65
  If you like the idea and want to learn more, please head over to [gitoxide](https://github.com/Byron/gitoxide), an
62
66
  implementation of 'git' in [Rust](https://www.rust-lang.org).
63
67
 
64
- *(Please note that `gitoxide` is not currently available for use in Python, and that Rust is required)*
68
+ *(Please note that `gitoxide` is not currently available for use in Python, and that Rust is required.)*
65
69
 
66
70
  ## GitPython
67
71
 
@@ -83,9 +87,9 @@ The project is open to contributions of all kinds, as well as new maintainers.
83
87
 
84
88
  ### REQUIREMENTS
85
89
 
86
- GitPython needs the `git` executable to be installed on the system and available in your `PATH` for most operations.
87
- If it is not in your `PATH`, you can help GitPython find it by setting
88
- the `GIT_PYTHON_GIT_EXECUTABLE=<path/to/git>` environment variable.
90
+ GitPython needs the `git` executable to be installed on the system and available in your
91
+ `PATH` for most operations. If it is not in your `PATH`, you can help GitPython find it
92
+ by setting the `GIT_PYTHON_GIT_EXECUTABLE=<path/to/git>` environment variable.
89
93
 
90
94
  - Git (1.7.x or newer)
91
95
  - Python >= 3.7
@@ -101,7 +105,7 @@ GitPython and its required package dependencies can be installed in any of the f
101
105
 
102
106
  To obtain and install a copy [from PyPI](https://pypi.org/project/GitPython/), run:
103
107
 
104
- ```bash
108
+ ```sh
105
109
  pip install GitPython
106
110
  ```
107
111
 
@@ -111,7 +115,7 @@ pip install GitPython
111
115
 
112
116
  If you have downloaded the source code, run this from inside the unpacked `GitPython` directory:
113
117
 
114
- ```bash
118
+ ```sh
115
119
  pip install .
116
120
  ```
117
121
 
@@ -119,7 +123,7 @@ pip install .
119
123
 
120
124
  To clone the [the GitHub repository](https://github.com/gitpython-developers/GitPython) from source to work on the code, you can do it like so:
121
125
 
122
- ```bash
126
+ ```sh
123
127
  git clone https://github.com/gitpython-developers/GitPython
124
128
  cd GitPython
125
129
  ./init-tests-after-clone.sh
@@ -129,7 +133,7 @@ On Windows, `./init-tests-after-clone.sh` can be run in a Git Bash shell.
129
133
 
130
134
  If you are cloning [your own fork](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/about-forks), then replace the above `git clone` command with one that gives the URL of your fork. Or use this [`gh`](https://cli.github.com/) command (assuming you have `gh` and your fork is called `GitPython`):
131
135
 
132
- ```bash
136
+ ```sh
133
137
  gh repo clone GitPython
134
138
  ```
135
139
 
@@ -137,7 +141,7 @@ Having cloned the repo, create and activate your [virtual environment](https://d
137
141
 
138
142
  Then make an [editable install](https://pip.pypa.io/en/stable/topics/local-project-installs/#editable-installs):
139
143
 
140
- ```bash
144
+ ```sh
141
145
  pip install -e ".[test]"
142
146
  ```
143
147
 
@@ -145,11 +149,11 @@ In the less common case that you do not want to install test dependencies, `pip
145
149
 
146
150
  #### With editable *dependencies* (not preferred, and rarely needed)
147
151
 
148
- 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 immediatley 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.
152
+ 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.
149
153
 
150
154
  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:
151
155
 
152
- ```bash
156
+ ```sh
153
157
  pip install -e ".[test]" -e git/ext/gitdb -e git/ext/gitdb/gitdb/ext/smmap
154
158
  ```
155
159
 
@@ -185,42 +189,38 @@ you will encounter test failures.
185
189
 
186
190
  Ensure testing libraries are installed. This is taken care of already if you installed with:
187
191
 
188
- ```bash
192
+ ```sh
189
193
  pip install -e ".[test]"
190
194
  ```
191
195
 
192
- Otherwise, you can run:
193
-
194
- ```bash
195
- pip install -r test-requirements.txt
196
- ```
196
+ If you had installed with a command like `pip install -e .` instead, you can still run
197
+ the above command to add the testing dependencies.
197
198
 
198
199
  #### Test commands
199
200
 
200
201
  To test, run:
201
202
 
202
- ```bash
203
+ ```sh
203
204
  pytest
204
205
  ```
205
206
 
206
- To lint, and apply automatic code formatting, run:
207
+ To lint, and apply some linting fixes as well as automatic code formatting, run:
207
208
 
208
- ```bash
209
+ ```sh
209
210
  pre-commit run --all-files
210
211
  ```
211
212
 
212
- - Linting without modifying code can be done with: `make lint`
213
- - Auto-formatting without other lint checks can be done with: `black .`
213
+ This includes the linting and autoformatting done by Ruff, as well as some other checks.
214
214
 
215
215
  To typecheck, run:
216
216
 
217
- ```bash
218
- mypy -p git
217
+ ```sh
218
+ mypy
219
219
  ```
220
220
 
221
221
  #### CI (and tox)
222
222
 
223
- The same linting, and running tests on all the different supported Python versions, will be performed:
223
+ Style and formatting checks, and running tests on all the different supported Python versions, will be performed:
224
224
 
225
225
  - Upon submitting a pull request.
226
226
  - On each push, *if* you have a fork with GitHub Actions enabled.
@@ -228,10 +228,12 @@ The same linting, and running tests on all the different supported Python versio
228
228
 
229
229
  #### Configuration files
230
230
 
231
- Specific tools:
231
+ Specific tools are all configured in the `./pyproject.toml` file:
232
232
 
233
- - Configurations for `mypy`, `pytest`, `coverage.py`, and `black` are in `./pyproject.toml`.
234
- - Configuration for `flake8` is in the `./.flake8` file.
233
+ - `pytest` (test runner)
234
+ - `coverage.py` (code coverage)
235
+ - `ruff` (linter and formatter)
236
+ - `mypy` (type checker)
235
237
 
236
238
  Orchestration tools:
237
239
 
@@ -286,5 +288,8 @@ Please have a look at the [contributions file][contributing].
286
288
 
287
289
  [3-Clause BSD License](https://opensource.org/license/bsd-3-clause/), also known as the New BSD License. See the [LICENSE file][license].
288
290
 
291
+ One file exclusively used for fuzz testing is subject to [a separate license, detailed here](./fuzzing/README.md#license).
292
+ This file is not included in the wheel or sdist packages published by the maintainers of GitPython.
293
+
289
294
  [contributing]: https://github.com/gitpython-developers/GitPython/blob/main/CONTRIBUTING.md
290
295
  [license]: https://github.com/gitpython-developers/GitPython/blob/main/LICENSE
@@ -0,0 +1,44 @@
1
+ git/__init__.py,sha256=nkQImgv-bWdiZOFDjzN-gbt93FoRHD0nY6_t9LQxy4Y,8899
2
+ git/cmd.py,sha256=QwiaBy0mFbi9xjRKhRgUVK-_-K6xVdFqh9l0cxPqPSc,67724
3
+ git/compat.py,sha256=y1E6y6O2q5r8clSlr8ZNmuIWG9nmHuehQEsVsmBffs8,4526
4
+ git/config.py,sha256=vTUlK6d8ORqFqjOv4Vbq_Hm-5mp-jOAt1dkq0IdzJ3U,34933
5
+ git/db.py,sha256=vIW9uWSbqu99zbuU2ZDmOhVOv1UPTmxrnqiCtRHCfjE,2368
6
+ git/diff.py,sha256=wmpMCIdMiVOqreGVPOGYyO4gFboGOAicyrvvI7PPjEg,27095
7
+ git/exc.py,sha256=Gc7g1pHpn8OmTse30NHmJVsBJ2CYH8LxaR8y8UA3lIM,7119
8
+ git/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
9
+ git/remote.py,sha256=pYn9dAlz-QwvNMWXD1M57pMPQitthOM86qTRK_cpTqU,46786
10
+ git/types.py,sha256=MQzIDEOnoueXGsAJF_0MgUc_osH7Eu0Sw3DQofYzCVE,10272
11
+ git/util.py,sha256=2uAv34zZ_827-zJ3-D5ACrVH-4Q4EO_KLUTH23zi2AI,43770
12
+ git/index/__init__.py,sha256=i-Nqb8Lufp9aFbmxpQBORmmQnjEVVM1Pn58fsQkyGgQ,406
13
+ git/index/base.py,sha256=nDD7XVLNbgBKpJMrrTVyHBy6NVLWgDkk7oUw6ZOegPc,60808
14
+ git/index/fun.py,sha256=37cA3DBC9vpAnSVu5TGA072SnoF5XZOkOukExwlejHs,16736
15
+ git/index/typ.py,sha256=uuKNwitUw83FhVaLSwo4pY7PHDQudtZTLJrLGym4jcI,6570
16
+ git/index/util.py,sha256=fULi7GPG-MvprKrRCD5c15GNdzku_1E38We0d97WB3A,3659
17
+ git/objects/__init__.py,sha256=O6ZL_olX7e5-8iIbKviRPkVSJxN37WA-EC0q9d48U5Y,637
18
+ git/objects/base.py,sha256=0dqNkSRVH0mk0-7ZKIkGBK7iNYrzLTVxwQFUd6CagsE,10277
19
+ git/objects/blob.py,sha256=zwwq0KfOMYeP5J2tW5CQatoLyeqFRlfkxP1Vwx1h07s,1215
20
+ git/objects/commit.py,sha256=GH1_83C9t7RGTukwozTHDgvxYQPRjTHhPDkXJyBbJyo,30553
21
+ git/objects/fun.py,sha256=B4jCqhAjm6Hl79GK58FPzW1H9K6Wc7Tx0rssyWmAcEE,8935
22
+ git/objects/tag.py,sha256=jAGESnpmTEv-dLakPzheT5ILZFFArcItnXYqfxfDrgc,4441
23
+ git/objects/tree.py,sha256=jJH888SHiP4dGzE-ra1yenQOyya_0C_MkHr06c1gHpM,13849
24
+ git/objects/util.py,sha256=Nlza4zLgdPmr_Yasyvvs6c1rKtW_wMxI6wDmQpQ3ufw,23846
25
+ git/objects/submodule/__init__.py,sha256=6xySp767LVz3UylWgUalntS_nGXRuVzXxDuFAv_Wc2c,303
26
+ git/objects/submodule/base.py,sha256=MQ-2xV8JznGwy2hLQv1aeQNgAkhBhgc5tdtClFL3DmE,63901
27
+ git/objects/submodule/root.py,sha256=5eTtYNHasqdPq6q0oDCPr7IaO6uAHL3b4DxMoiO2LhE,20246
28
+ git/objects/submodule/util.py,sha256=sQqAYaiSJdFkZa9NlAuK_wTsMNiS-kkQnQjvIoJtc_o,3509
29
+ git/refs/__init__.py,sha256=DWlJNnsx-4jM_E-VycbP-FZUdn6iWhjnH_uZ_pZXBro,509
30
+ git/refs/head.py,sha256=SGa3N301HfAi79X6UR5Mcg7mO9TnCH3Bk549kHlJVaQ,10513
31
+ git/refs/log.py,sha256=kXiuAgTo1DIuM_BfbDUk9gQ0YO-mutIMVdHv1_ES90o,12493
32
+ git/refs/reference.py,sha256=l6mhF4YLSEwtjz6b9PpOQH-fkng7EYWMaJhkjn-2jXA,5630
33
+ git/refs/remote.py,sha256=WwqV9T7BbYf3F_WZNUQivu9xktIIKGklCjDpwQrhD-A,2806
34
+ git/refs/symbolic.py,sha256=c8zOwaqzcg-J-rGrpuWdvh8zwMvSUqAHghd4vJoYG_s,34552
35
+ git/refs/tag.py,sha256=kgzV2vhpL4FD2TqHb0BJuMRAHgAvJF-TcoyWlaB-djQ,5010
36
+ git/repo/__init__.py,sha256=CILSVH36fX_WxVFSjD9o1WF5LgsNedPiJvSngKZqfVU,210
37
+ git/repo/base.py,sha256=0GU6nKNdT8SYjDI5Y5DeZ1zCEX3tHeq1VW2MSpne05g,59891
38
+ git/repo/fun.py,sha256=HSGC0-rqeKKx9fDg7JyQyMZgIwUWn-FnSZR_gRGpG-E,13573
39
+ GitPython-3.1.44.dist-info/AUTHORS,sha256=tZ9LuyBks2V2HKTPK7kCmtd9Guu_LyU1oZHvU0NiAok,2334
40
+ GitPython-3.1.44.dist-info/LICENSE,sha256=hvyUwyGpr7wRUUcTURuv3tIl8lEA3MD3NQ6CvCMbi-s,1503
41
+ GitPython-3.1.44.dist-info/METADATA,sha256=0O_Fr2Y7A-DlPYhlbSxGjblBC2mWkw3USNUhyL80Ip8,13245
42
+ GitPython-3.1.44.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
43
+ GitPython-3.1.44.dist-info/top_level.txt,sha256=0hzDuIp8obv624V3GmbqsagBWkk8ohtGU-Bc1PmTT0o,4
44
+ GitPython-3.1.44.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: bdist_wheel (0.42.0)
2
+ Generator: setuptools (75.6.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
git/__init__.py CHANGED
@@ -5,39 +5,7 @@
5
5
 
6
6
  # @PydevCodeAnalysisIgnore
7
7
 
8
- __version__ = '3.1.42'
9
-
10
- from typing import List, Optional, Sequence, Tuple, Union, TYPE_CHECKING
11
-
12
- from gitdb.util import to_hex_sha
13
- from git.exc import * # noqa: F403 # @NoMove @IgnorePep8
14
- from git.types import PathLike
15
-
16
- try:
17
- from git.compat import safe_decode # @NoMove @IgnorePep8
18
- from git.config import GitConfigParser # @NoMove @IgnorePep8
19
- from git.objects import * # noqa: F403 # @NoMove @IgnorePep8
20
- from git.refs import * # noqa: F403 # @NoMove @IgnorePep8
21
- from git.diff import * # noqa: F403 # @NoMove @IgnorePep8
22
- from git.db import * # noqa: F403 # @NoMove @IgnorePep8
23
- from git.cmd import Git # @NoMove @IgnorePep8
24
- from git.repo import Repo # @NoMove @IgnorePep8
25
- from git.remote import * # noqa: F403 # @NoMove @IgnorePep8
26
- from git.index import * # noqa: F403 # @NoMove @IgnorePep8
27
- from git.util import ( # @NoMove @IgnorePep8
28
- LockFile,
29
- BlockingLockFile,
30
- Stats,
31
- Actor,
32
- remove_password_if_present,
33
- rmtree,
34
- )
35
- except GitError as _exc: # noqa: F405
36
- raise ImportError("%s: %s" % (_exc.__class__.__name__, _exc)) from _exc
37
-
38
- # __all__ must be statically defined by py.typed support
39
- # __all__ = [name for name, obj in locals().items() if not (name.startswith("_") or inspect.ismodule(obj))]
40
- __all__ = [ # noqa: F405
8
+ __all__ = [
41
9
  "Actor",
42
10
  "AmbiguousObjectName",
43
11
  "BadName",
@@ -52,6 +20,7 @@ __all__ = [ # noqa: F405
52
20
  "CommandError",
53
21
  "Commit",
54
22
  "Diff",
23
+ "DiffConstants",
55
24
  "DiffIndex",
56
25
  "Diffable",
57
26
  "FetchInfo",
@@ -65,18 +34,19 @@ __all__ = [ # noqa: F405
65
34
  "HEAD",
66
35
  "Head",
67
36
  "HookExecutionError",
37
+ "INDEX",
68
38
  "IndexEntry",
69
39
  "IndexFile",
70
40
  "IndexObject",
71
41
  "InvalidDBRoot",
72
42
  "InvalidGitRepositoryError",
73
- "List",
43
+ "List", # Deprecated - import this from `typing` instead.
74
44
  "LockFile",
75
45
  "NULL_TREE",
76
46
  "NoSuchPathError",
77
47
  "ODBError",
78
48
  "Object",
79
- "Optional",
49
+ "Optional", # Deprecated - import this from `typing` instead.
80
50
  "ParseError",
81
51
  "PathLike",
82
52
  "PushInfo",
@@ -90,54 +60,241 @@ __all__ = [ # noqa: F405
90
60
  "RepositoryDirtyError",
91
61
  "RootModule",
92
62
  "RootUpdateProgress",
93
- "Sequence",
63
+ "Sequence", # Deprecated - import from `typing`, or `collections.abc` in 3.9+.
94
64
  "StageType",
95
65
  "Stats",
96
66
  "Submodule",
97
67
  "SymbolicReference",
98
- "TYPE_CHECKING",
68
+ "TYPE_CHECKING", # Deprecated - import this from `typing` instead.
99
69
  "Tag",
100
70
  "TagObject",
101
71
  "TagReference",
102
72
  "Tree",
103
73
  "TreeModifier",
104
- "Tuple",
105
- "Union",
74
+ "Tuple", # Deprecated - import this from `typing` instead.
75
+ "Union", # Deprecated - import this from `typing` instead.
106
76
  "UnmergedEntriesError",
107
77
  "UnsafeOptionError",
108
78
  "UnsafeProtocolError",
109
79
  "UnsupportedOperation",
110
80
  "UpdateProgress",
111
81
  "WorkTreeRepositoryUnsupported",
82
+ "refresh",
112
83
  "remove_password_if_present",
113
84
  "rmtree",
114
85
  "safe_decode",
115
86
  "to_hex_sha",
116
87
  ]
117
88
 
89
+ __version__ = '3.1.44'
90
+
91
+ from typing import Any, List, Optional, Sequence, TYPE_CHECKING, Tuple, Union
92
+
93
+ if TYPE_CHECKING:
94
+ from types import ModuleType
95
+
96
+ import warnings
97
+
98
+ from gitdb.util import to_hex_sha
99
+
100
+ from git.exc import (
101
+ AmbiguousObjectName,
102
+ BadName,
103
+ BadObject,
104
+ BadObjectType,
105
+ CacheError,
106
+ CheckoutError,
107
+ CommandError,
108
+ GitCommandError,
109
+ GitCommandNotFound,
110
+ GitError,
111
+ HookExecutionError,
112
+ InvalidDBRoot,
113
+ InvalidGitRepositoryError,
114
+ NoSuchPathError,
115
+ ODBError,
116
+ ParseError,
117
+ RepositoryDirtyError,
118
+ UnmergedEntriesError,
119
+ UnsafeOptionError,
120
+ UnsafeProtocolError,
121
+ UnsupportedOperation,
122
+ WorkTreeRepositoryUnsupported,
123
+ )
124
+ from git.types import PathLike
125
+
126
+ try:
127
+ from git.compat import safe_decode # @NoMove
128
+ from git.config import GitConfigParser # @NoMove
129
+ from git.objects import ( # @NoMove
130
+ Blob,
131
+ Commit,
132
+ IndexObject,
133
+ Object,
134
+ RootModule,
135
+ RootUpdateProgress,
136
+ Submodule,
137
+ TagObject,
138
+ Tree,
139
+ TreeModifier,
140
+ UpdateProgress,
141
+ )
142
+ from git.refs import ( # @NoMove
143
+ HEAD,
144
+ Head,
145
+ RefLog,
146
+ RefLogEntry,
147
+ Reference,
148
+ RemoteReference,
149
+ SymbolicReference,
150
+ Tag,
151
+ TagReference,
152
+ )
153
+ from git.diff import ( # @NoMove
154
+ INDEX,
155
+ NULL_TREE,
156
+ Diff,
157
+ DiffConstants,
158
+ DiffIndex,
159
+ Diffable,
160
+ )
161
+ from git.db import GitCmdObjectDB, GitDB # @NoMove
162
+ from git.cmd import Git # @NoMove
163
+ from git.repo import Repo # @NoMove
164
+ from git.remote import FetchInfo, PushInfo, Remote, RemoteProgress # @NoMove
165
+ from git.index import ( # @NoMove
166
+ BaseIndexEntry,
167
+ BlobFilter,
168
+ CheckoutError,
169
+ IndexEntry,
170
+ IndexFile,
171
+ StageType,
172
+ # NOTE: This tells type checkers what util resolves to. We delete it, and it is
173
+ # really resolved by __getattr__, which warns. See below on what to use instead.
174
+ util,
175
+ )
176
+ from git.util import ( # @NoMove
177
+ Actor,
178
+ BlockingLockFile,
179
+ LockFile,
180
+ Stats,
181
+ remove_password_if_present,
182
+ rmtree,
183
+ )
184
+ except GitError as _exc:
185
+ raise ImportError("%s: %s" % (_exc.__class__.__name__, _exc)) from _exc
186
+
187
+
188
+ def _warned_import(message: str, fullname: str) -> "ModuleType":
189
+ import importlib
190
+
191
+ warnings.warn(message, DeprecationWarning, stacklevel=3)
192
+ return importlib.import_module(fullname)
193
+
194
+
195
+ def _getattr(name: str) -> Any:
196
+ # TODO: If __version__ is made dynamic and lazily fetched, put that case right here.
197
+
198
+ if name == "util":
199
+ return _warned_import(
200
+ "The expression `git.util` and the import `from git import util` actually "
201
+ "reference git.index.util, and not the git.util module accessed in "
202
+ '`from git.util import XYZ` or `sys.modules["git.util"]`. This potentially '
203
+ "confusing behavior is currently preserved for compatibility, but may be "
204
+ "changed in the future and should not be relied on.",
205
+ fullname="git.index.util",
206
+ )
207
+
208
+ for names, prefix in (
209
+ ({"head", "log", "reference", "symbolic", "tag"}, "git.refs"),
210
+ ({"base", "fun", "typ"}, "git.index"),
211
+ ):
212
+ if name not in names:
213
+ continue
214
+
215
+ fullname = f"{prefix}.{name}"
216
+
217
+ return _warned_import(
218
+ f"{__name__}.{name} is a private alias of {fullname} and subject to "
219
+ f"immediate removal. Use {fullname} instead.",
220
+ fullname=fullname,
221
+ )
222
+
223
+ raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
224
+
225
+
226
+ if not TYPE_CHECKING:
227
+ # NOTE: The expression `git.util` gives git.index.util and `from git import util`
228
+ # imports git.index.util, NOT git.util. It may not be feasible to change this until
229
+ # the next major version, to avoid breaking code inadvertently relying on it.
230
+ #
231
+ # - If git.index.util *is* what you want, use (or import from) that, to avoid
232
+ # confusion.
233
+ #
234
+ # - To use the "real" git.util module, write `from git.util import ...`, or if
235
+ # necessary access it as `sys.modules["git.util"]`.
236
+ #
237
+ # Note also that `import git.util` technically imports the "real" git.util... but
238
+ # the *expression* `git.util` after doing so is still git.index.util!
239
+ #
240
+ # (This situation differs from that of other indirect-submodule imports that are
241
+ # unambiguously non-public and subject to immediate removal. Here, the public
242
+ # git.util module, though different, makes less discoverable that the expression
243
+ # `git.util` refers to a non-public attribute of the git module.)
244
+ #
245
+ # This had originally come about by a wildcard import. Now that all intended imports
246
+ # are explicit, the intuitive but potentially incompatible binding occurs due to the
247
+ # usual rules for Python submodule bindings. So for now we replace that binding with
248
+ # git.index.util, delete that, and let __getattr__ handle it and issue a warning.
249
+ #
250
+ # For the same runtime behavior, it would be enough to forgo importing util, and
251
+ # delete util as created naturally; __getattr__ would behave the same. But type
252
+ # checkers would not know what util refers to when accessed as an attribute of git.
253
+ del util
254
+
255
+ # This is "hidden" to preserve static checking for undefined/misspelled attributes.
256
+ __getattr__ = _getattr
257
+
118
258
  # { Initialize git executable path
259
+
119
260
  GIT_OK = None
120
261
 
121
262
 
122
263
  def refresh(path: Optional[PathLike] = None) -> None:
123
- """Convenience method for setting the git executable path."""
264
+ """Convenience method for setting the git executable path.
265
+
266
+ :param path:
267
+ Optional path to the Git executable. If not absolute, it is resolved
268
+ immediately, relative to the current directory.
269
+
270
+ :note:
271
+ The `path` parameter is usually omitted and cannot be used to specify a custom
272
+ command whose location is looked up in a path search on each call. See
273
+ :meth:`Git.refresh <git.cmd.Git.refresh>` for details on how to achieve this.
274
+
275
+ :note:
276
+ This calls :meth:`Git.refresh <git.cmd.Git.refresh>` and sets other global
277
+ configuration according to the effect of doing so. As such, this function should
278
+ usually be used instead of using :meth:`Git.refresh <git.cmd.Git.refresh>` or
279
+ :meth:`FetchInfo.refresh <git.remote.FetchInfo.refresh>` directly.
280
+
281
+ :note:
282
+ This function is called automatically, with no arguments, at import time.
283
+ """
124
284
  global GIT_OK
125
285
  GIT_OK = False
126
286
 
127
287
  if not Git.refresh(path=path):
128
288
  return
129
289
  if not FetchInfo.refresh(): # noqa: F405
130
- return # type: ignore [unreachable]
290
+ return # type: ignore[unreachable]
131
291
 
132
292
  GIT_OK = True
133
293
 
134
294
 
135
- # } END initialize git executable path
136
-
137
-
138
- #################
139
295
  try:
140
296
  refresh()
141
297
  except Exception as _exc:
142
298
  raise ImportError("Failed to initialize: {0}".format(_exc)) from _exc
143
- #################
299
+
300
+ # } END initialize git executable path