GitPython 3.1.45__tar.gz → 3.1.46__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.
- {gitpython-3.1.45 → gitpython-3.1.46/GitPython.egg-info}/PKG-INFO +2 -2
- {gitpython-3.1.45 → gitpython-3.1.46}/GitPython.egg-info/requires.txt +3 -1
- {gitpython-3.1.45/GitPython.egg-info → gitpython-3.1.46}/PKG-INFO +2 -2
- gitpython-3.1.46/VERSION +1 -0
- {gitpython-3.1.45 → gitpython-3.1.46}/doc/source/changes.rst +20 -14
- {gitpython-3.1.45 → gitpython-3.1.46}/git/__init__.py +1 -1
- {gitpython-3.1.45 → gitpython-3.1.46}/git/config.py +9 -7
- {gitpython-3.1.45 → gitpython-3.1.46}/git/diff.py +3 -2
- {gitpython-3.1.45 → gitpython-3.1.46}/git/index/base.py +6 -6
- {gitpython-3.1.45 → gitpython-3.1.46}/git/index/fun.py +12 -6
- {gitpython-3.1.45 → gitpython-3.1.46}/git/index/typ.py +16 -3
- {gitpython-3.1.45 → gitpython-3.1.46}/git/index/util.py +2 -2
- {gitpython-3.1.45 → gitpython-3.1.46}/git/objects/blob.py +2 -1
- {gitpython-3.1.45 → gitpython-3.1.46}/git/objects/commit.py +1 -1
- {gitpython-3.1.45 → gitpython-3.1.46}/git/objects/submodule/base.py +4 -4
- {gitpython-3.1.45 → gitpython-3.1.46}/git/objects/tree.py +4 -2
- {gitpython-3.1.45 → gitpython-3.1.46}/git/refs/head.py +1 -5
- {gitpython-3.1.45 → gitpython-3.1.46}/git/refs/log.py +1 -1
- {gitpython-3.1.45 → gitpython-3.1.46}/git/refs/reference.py +2 -1
- {gitpython-3.1.45 → gitpython-3.1.46}/git/refs/symbolic.py +16 -15
- {gitpython-3.1.45 → gitpython-3.1.46}/git/refs/tag.py +4 -4
- {gitpython-3.1.45 → gitpython-3.1.46}/git/repo/base.py +13 -18
- {gitpython-3.1.45 → gitpython-3.1.46}/git/repo/fun.py +1 -1
- {gitpython-3.1.45 → gitpython-3.1.46}/git/types.py +2 -2
- {gitpython-3.1.45 → gitpython-3.1.46}/git/util.py +16 -16
- {gitpython-3.1.45 → gitpython-3.1.46}/pyproject.toml +0 -1
- {gitpython-3.1.45 → gitpython-3.1.46}/test-requirements.txt +1 -1
- gitpython-3.1.45/VERSION +0 -1
- {gitpython-3.1.45 → gitpython-3.1.46}/AUTHORS +0 -0
- {gitpython-3.1.45 → gitpython-3.1.46}/CHANGES +0 -0
- {gitpython-3.1.45 → gitpython-3.1.46}/CONTRIBUTING.md +0 -0
- {gitpython-3.1.45 → gitpython-3.1.46}/GitPython.egg-info/SOURCES.txt +0 -0
- {gitpython-3.1.45 → gitpython-3.1.46}/GitPython.egg-info/dependency_links.txt +0 -0
- {gitpython-3.1.45 → gitpython-3.1.46}/GitPython.egg-info/not-zip-safe +0 -0
- {gitpython-3.1.45 → gitpython-3.1.46}/GitPython.egg-info/top_level.txt +0 -0
- {gitpython-3.1.45 → gitpython-3.1.46}/LICENSE +0 -0
- {gitpython-3.1.45 → gitpython-3.1.46}/MANIFEST.in +0 -0
- {gitpython-3.1.45 → gitpython-3.1.46}/README.md +0 -0
- {gitpython-3.1.45 → gitpython-3.1.46}/doc/.gitignore +0 -0
- {gitpython-3.1.45 → gitpython-3.1.46}/doc/Makefile +0 -0
- {gitpython-3.1.45 → gitpython-3.1.46}/doc/requirements.txt +0 -0
- {gitpython-3.1.45 → gitpython-3.1.46}/doc/source/conf.py +0 -0
- {gitpython-3.1.45 → gitpython-3.1.46}/doc/source/index.rst +0 -0
- {gitpython-3.1.45 → gitpython-3.1.46}/doc/source/intro.rst +0 -0
- {gitpython-3.1.45 → gitpython-3.1.46}/doc/source/quickstart.rst +0 -0
- {gitpython-3.1.45 → gitpython-3.1.46}/doc/source/reference.rst +0 -0
- {gitpython-3.1.45 → gitpython-3.1.46}/doc/source/roadmap.rst +0 -0
- {gitpython-3.1.45 → gitpython-3.1.46}/doc/source/tutorial.rst +0 -0
- {gitpython-3.1.45 → gitpython-3.1.46}/git/cmd.py +0 -0
- {gitpython-3.1.45 → gitpython-3.1.46}/git/compat.py +0 -0
- {gitpython-3.1.45 → gitpython-3.1.46}/git/db.py +0 -0
- {gitpython-3.1.45 → gitpython-3.1.46}/git/exc.py +0 -0
- {gitpython-3.1.45 → gitpython-3.1.46}/git/index/__init__.py +0 -0
- {gitpython-3.1.45 → gitpython-3.1.46}/git/objects/__init__.py +0 -0
- {gitpython-3.1.45 → gitpython-3.1.46}/git/objects/base.py +0 -0
- {gitpython-3.1.45 → gitpython-3.1.46}/git/objects/fun.py +0 -0
- {gitpython-3.1.45 → gitpython-3.1.46}/git/objects/submodule/__init__.py +0 -0
- {gitpython-3.1.45 → gitpython-3.1.46}/git/objects/submodule/root.py +0 -0
- {gitpython-3.1.45 → gitpython-3.1.46}/git/objects/submodule/util.py +0 -0
- {gitpython-3.1.45 → gitpython-3.1.46}/git/objects/tag.py +0 -0
- {gitpython-3.1.45 → gitpython-3.1.46}/git/objects/util.py +0 -0
- {gitpython-3.1.45 → gitpython-3.1.46}/git/py.typed +0 -0
- {gitpython-3.1.45 → gitpython-3.1.46}/git/refs/__init__.py +0 -0
- {gitpython-3.1.45 → gitpython-3.1.46}/git/refs/remote.py +0 -0
- {gitpython-3.1.45 → gitpython-3.1.46}/git/remote.py +0 -0
- {gitpython-3.1.45 → gitpython-3.1.46}/git/repo/__init__.py +0 -0
- {gitpython-3.1.45 → gitpython-3.1.46}/requirements.txt +0 -0
- {gitpython-3.1.45 → gitpython-3.1.46}/setup.cfg +0 -0
- {gitpython-3.1.45 → gitpython-3.1.46}/setup.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: GitPython
|
|
3
|
-
Version: 3.1.
|
|
3
|
+
Version: 3.1.46
|
|
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"
|
|
@@ -11,7 +11,6 @@ sphinx-autodoc-typehints
|
|
|
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.
|
|
3
|
+
Version: 3.1.46
|
|
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"
|
gitpython-3.1.46/VERSION
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.1.46
|
|
@@ -2,6 +2,12 @@
|
|
|
2
2
|
Changelog
|
|
3
3
|
=========
|
|
4
4
|
|
|
5
|
+
3.1.46
|
|
6
|
+
======
|
|
7
|
+
|
|
8
|
+
See the following for all changes.
|
|
9
|
+
https://github.com/gitpython-developers/GitPython/releases/tag/3.1.46
|
|
10
|
+
|
|
5
11
|
3.1.45
|
|
6
12
|
======
|
|
7
13
|
|
|
@@ -111,7 +117,7 @@ https://github.com/gitpython-developers/gitpython/milestone/61?closed=1
|
|
|
111
117
|
but a necessary fix for https://github.com/gitpython-developers/GitPython/issues/1515.
|
|
112
118
|
Please take a look at the PR for more information and how to bypass these protections
|
|
113
119
|
in case they cause breakage: https://github.com/gitpython-developers/GitPython/pull/1521.
|
|
114
|
-
|
|
120
|
+
|
|
115
121
|
|
|
116
122
|
See the following for all changes.
|
|
117
123
|
https://github.com/gitpython-developers/gitpython/milestone/60?closed=1
|
|
@@ -176,38 +182,38 @@ https://github.com/gitpython-developers/gitpython/milestone/53?closed=1
|
|
|
176
182
|
* General:
|
|
177
183
|
|
|
178
184
|
- Remove python 3.6 support
|
|
179
|
-
|
|
185
|
+
|
|
180
186
|
- Remove distutils ahead of deprecation in standard library.
|
|
181
|
-
|
|
187
|
+
|
|
182
188
|
- Update sphinx to 4.1.12 and use autodoc-typehints.
|
|
183
|
-
|
|
189
|
+
|
|
184
190
|
- Include README as long_description on PyPI
|
|
185
|
-
|
|
191
|
+
|
|
186
192
|
- Test against earliest and latest minor version available on Github Actions (e.g. 3.9.0 and 3.9.7)
|
|
187
|
-
|
|
193
|
+
|
|
188
194
|
|
|
189
195
|
* Typing:
|
|
190
196
|
|
|
191
197
|
- Add types to ALL functions.
|
|
192
|
-
|
|
198
|
+
|
|
193
199
|
- Ensure py.typed is collected.
|
|
194
|
-
|
|
200
|
+
|
|
195
201
|
- Increase mypy strictness with disallow_untyped_defs, warn_redundant_casts, warn_unreachable.
|
|
196
|
-
|
|
202
|
+
|
|
197
203
|
- Use typing.NamedTuple and typing.OrderedDict now 3.6 dropped.
|
|
198
|
-
|
|
204
|
+
|
|
199
205
|
- Make Protocol classes ABCs at runtime due to new behaviour/bug in 3.9.7 & 3.10.0-rc1
|
|
200
|
-
|
|
206
|
+
|
|
201
207
|
- Remove use of typing.TypeGuard until later release, to allow dependent libs time to update.
|
|
202
|
-
|
|
208
|
+
|
|
203
209
|
- Tracking issue: https://github.com/gitpython-developers/GitPython/issues/1095
|
|
204
210
|
|
|
205
211
|
* Runtime improvements:
|
|
206
212
|
|
|
207
213
|
- Add clone_multi_options support to submodule.add()
|
|
208
|
-
|
|
214
|
+
|
|
209
215
|
- Delay calling get_user_id() unless essential, to support sand-boxed environments.
|
|
210
|
-
|
|
216
|
+
|
|
211
217
|
- Add timeout to handle_process_output(), in case thread.join() hangs.
|
|
212
218
|
|
|
213
219
|
See the following for details:
|
|
@@ -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
|
|
@@ -574,11 +574,11 @@ class GitConfigParser(cp.RawConfigParser, metaclass=MetaParserBuilder):
|
|
|
574
574
|
if keyword.endswith("/i"):
|
|
575
575
|
value = re.sub(
|
|
576
576
|
r"[a-zA-Z]",
|
|
577
|
-
lambda m: "[{
|
|
577
|
+
lambda m: f"[{m.group().lower()!r}{m.group().upper()!r}]",
|
|
578
578
|
value,
|
|
579
579
|
)
|
|
580
580
|
if self._repo.git_dir:
|
|
581
|
-
if fnmatch.fnmatchcase(
|
|
581
|
+
if fnmatch.fnmatchcase(os.fspath(self._repo.git_dir), value):
|
|
582
582
|
paths += self.items(section)
|
|
583
583
|
|
|
584
584
|
elif keyword == "onbranch":
|
|
@@ -590,7 +590,11 @@ class GitConfigParser(cp.RawConfigParser, metaclass=MetaParserBuilder):
|
|
|
590
590
|
|
|
591
591
|
if fnmatch.fnmatchcase(branch_name, value):
|
|
592
592
|
paths += self.items(section)
|
|
593
|
-
|
|
593
|
+
elif keyword == "hasconfig:remote.*.url":
|
|
594
|
+
for remote in self._repo.remotes:
|
|
595
|
+
if fnmatch.fnmatchcase(remote.url, value):
|
|
596
|
+
paths += self.items(section)
|
|
597
|
+
break
|
|
594
598
|
return paths
|
|
595
599
|
|
|
596
600
|
def read(self) -> None: # type: ignore[override]
|
|
@@ -629,8 +633,6 @@ class GitConfigParser(cp.RawConfigParser, metaclass=MetaParserBuilder):
|
|
|
629
633
|
file_path = cast(IO[bytes], file_path)
|
|
630
634
|
self._read(file_path, file_path.name)
|
|
631
635
|
else:
|
|
632
|
-
# Assume a path if it is not a file-object.
|
|
633
|
-
file_path = cast(PathLike, file_path)
|
|
634
636
|
try:
|
|
635
637
|
with open(file_path, "rb") as fp:
|
|
636
638
|
file_ok = True
|
|
@@ -764,7 +766,7 @@ class GitConfigParser(cp.RawConfigParser, metaclass=MetaParserBuilder):
|
|
|
764
766
|
if self.read_only:
|
|
765
767
|
raise IOError("Cannot execute non-constant method %s.%s" % (self, method_name))
|
|
766
768
|
|
|
767
|
-
def add_section(self, section:
|
|
769
|
+
def add_section(self, section: "cp._SectionName") -> None:
|
|
768
770
|
"""Assures added options will stay in order."""
|
|
769
771
|
return super().add_section(section)
|
|
770
772
|
|
|
@@ -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
|
|
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 =
|
|
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(
|
|
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
|
|
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.
|
|
@@ -1359,11 +1359,11 @@ class IndexFile(LazyMixin, git_diff.Diffable, Serializable):
|
|
|
1359
1359
|
try:
|
|
1360
1360
|
self.entries[(co_path, 0)]
|
|
1361
1361
|
except KeyError:
|
|
1362
|
-
folder =
|
|
1362
|
+
folder = co_path
|
|
1363
1363
|
if not folder.endswith("/"):
|
|
1364
1364
|
folder += "/"
|
|
1365
1365
|
for entry in self.entries.values():
|
|
1366
|
-
if
|
|
1366
|
+
if os.fspath(entry.path).startswith(folder):
|
|
1367
1367
|
p = entry.path
|
|
1368
1368
|
self._write_path_to_stdin(proc, p, p, make_exc, fprogress, read_from_stdout=False)
|
|
1369
1369
|
checked_out_files.append(p)
|
|
@@ -36,7 +36,7 @@ from git.objects.fun import (
|
|
|
36
36
|
)
|
|
37
37
|
from git.util import IndexFileSHA1Writer, finalize_process
|
|
38
38
|
|
|
39
|
-
from .typ import BaseIndexEntry, IndexEntry, CE_NAMEMASK, CE_STAGESHIFT
|
|
39
|
+
from .typ import CE_EXTENDED, BaseIndexEntry, IndexEntry, CE_NAMEMASK, CE_STAGESHIFT
|
|
40
40
|
from .util import pack, unpack
|
|
41
41
|
|
|
42
42
|
# typing -----------------------------------------------------------------------------
|
|
@@ -87,7 +87,7 @@ def run_commit_hook(name: str, index: "IndexFile", *args: str) -> None:
|
|
|
87
87
|
return
|
|
88
88
|
|
|
89
89
|
env = os.environ.copy()
|
|
90
|
-
env["GIT_INDEX_FILE"] = safe_decode(
|
|
90
|
+
env["GIT_INDEX_FILE"] = safe_decode(os.fspath(index.path))
|
|
91
91
|
env["GIT_EDITOR"] = ":"
|
|
92
92
|
cmd = [hp]
|
|
93
93
|
try:
|
|
@@ -158,7 +158,7 @@ def write_cache(
|
|
|
158
158
|
write = stream_sha.write
|
|
159
159
|
|
|
160
160
|
# Header
|
|
161
|
-
version = 2
|
|
161
|
+
version = 3 if any(entry.extended_flags for entry in entries) else 2
|
|
162
162
|
write(b"DIRC")
|
|
163
163
|
write(pack(">LL", version, len(entries)))
|
|
164
164
|
|
|
@@ -172,6 +172,8 @@ def write_cache(
|
|
|
172
172
|
plen = len(path) & CE_NAMEMASK # Path length
|
|
173
173
|
assert plen == len(path), "Path %s too long to fit into index" % entry.path
|
|
174
174
|
flags = plen | (entry.flags & CE_NAMEMASK_INV) # Clear possible previous values.
|
|
175
|
+
if entry.extended_flags:
|
|
176
|
+
flags |= CE_EXTENDED
|
|
175
177
|
write(
|
|
176
178
|
pack(
|
|
177
179
|
">LLLLLL20sH",
|
|
@@ -185,6 +187,8 @@ def write_cache(
|
|
|
185
187
|
flags,
|
|
186
188
|
)
|
|
187
189
|
)
|
|
190
|
+
if entry.extended_flags:
|
|
191
|
+
write(pack(">H", entry.extended_flags))
|
|
188
192
|
write(path)
|
|
189
193
|
real_size = (tell() - beginoffset + 8) & ~7
|
|
190
194
|
write(b"\0" * ((beginoffset + real_size) - tell()))
|
|
@@ -206,8 +210,7 @@ def read_header(stream: IO[bytes]) -> Tuple[int, int]:
|
|
|
206
210
|
unpacked = cast(Tuple[int, int], unpack(">LL", stream.read(4 * 2)))
|
|
207
211
|
version, num_entries = unpacked
|
|
208
212
|
|
|
209
|
-
|
|
210
|
-
assert version in (1, 2), "Unsupported git index version %i, only 1 and 2 are supported" % version
|
|
213
|
+
assert version in (1, 2, 3), "Unsupported git index version %i, only 1, 2, and 3 are supported" % version
|
|
211
214
|
return version, num_entries
|
|
212
215
|
|
|
213
216
|
|
|
@@ -260,12 +263,15 @@ def read_cache(
|
|
|
260
263
|
ctime = unpack(">8s", read(8))[0]
|
|
261
264
|
mtime = unpack(">8s", read(8))[0]
|
|
262
265
|
(dev, ino, mode, uid, gid, size, sha, flags) = unpack(">LLLLLL20sH", read(20 + 4 * 6 + 2))
|
|
266
|
+
extended_flags = 0
|
|
267
|
+
if flags & CE_EXTENDED:
|
|
268
|
+
extended_flags = unpack(">H", read(2))[0]
|
|
263
269
|
path_size = flags & CE_NAMEMASK
|
|
264
270
|
path = read(path_size).decode(defenc)
|
|
265
271
|
|
|
266
272
|
real_size = (tell() - beginoffset + 8) & ~7
|
|
267
273
|
read((beginoffset + real_size) - tell())
|
|
268
|
-
entry = IndexEntry((mode, sha, flags, path, ctime, mtime, dev, ino, uid, gid, size))
|
|
274
|
+
entry = IndexEntry((mode, sha, flags, path, ctime, mtime, dev, ino, uid, gid, size, extended_flags))
|
|
269
275
|
# entry_key would be the method to use, but we save the effort.
|
|
270
276
|
entries[(path, entry.stage)] = entry
|
|
271
277
|
count += 1
|
|
@@ -32,6 +32,9 @@ CE_EXTENDED = 0x4000
|
|
|
32
32
|
CE_VALID = 0x8000
|
|
33
33
|
CE_STAGESHIFT = 12
|
|
34
34
|
|
|
35
|
+
CE_EXT_SKIP_WORKTREE = 0x4000
|
|
36
|
+
CE_EXT_INTENT_TO_ADD = 0x2000
|
|
37
|
+
|
|
35
38
|
# } END invariants
|
|
36
39
|
|
|
37
40
|
|
|
@@ -87,6 +90,8 @@ class BaseIndexEntryHelper(NamedTuple):
|
|
|
87
90
|
uid: int = 0
|
|
88
91
|
gid: int = 0
|
|
89
92
|
size: int = 0
|
|
93
|
+
# version 3 extended flags, only when (flags & CE_EXTENDED) is set
|
|
94
|
+
extended_flags: int = 0
|
|
90
95
|
|
|
91
96
|
|
|
92
97
|
class BaseIndexEntry(BaseIndexEntryHelper):
|
|
@@ -102,7 +107,7 @@ class BaseIndexEntry(BaseIndexEntryHelper):
|
|
|
102
107
|
cls,
|
|
103
108
|
inp_tuple: Union[
|
|
104
109
|
Tuple[int, bytes, int, PathLike],
|
|
105
|
-
Tuple[int, bytes, int, PathLike, bytes, bytes, int, int, int, int, int],
|
|
110
|
+
Tuple[int, bytes, int, PathLike, bytes, bytes, int, int, int, int, int, int],
|
|
106
111
|
],
|
|
107
112
|
) -> "BaseIndexEntry":
|
|
108
113
|
"""Override ``__new__`` to allow construction from a tuple for backwards
|
|
@@ -134,6 +139,14 @@ class BaseIndexEntry(BaseIndexEntryHelper):
|
|
|
134
139
|
"""
|
|
135
140
|
return (self.flags & CE_STAGEMASK) >> CE_STAGESHIFT
|
|
136
141
|
|
|
142
|
+
@property
|
|
143
|
+
def skip_worktree(self) -> bool:
|
|
144
|
+
return (self.extended_flags & CE_EXT_SKIP_WORKTREE) > 0
|
|
145
|
+
|
|
146
|
+
@property
|
|
147
|
+
def intent_to_add(self) -> bool:
|
|
148
|
+
return (self.extended_flags & CE_EXT_INTENT_TO_ADD) > 0
|
|
149
|
+
|
|
137
150
|
@classmethod
|
|
138
151
|
def from_blob(cls, blob: Blob, stage: int = 0) -> "BaseIndexEntry":
|
|
139
152
|
""":return: Fully equipped BaseIndexEntry at the given stage"""
|
|
@@ -179,7 +192,7 @@ class IndexEntry(BaseIndexEntry):
|
|
|
179
192
|
Instance of type :class:`BaseIndexEntry`.
|
|
180
193
|
"""
|
|
181
194
|
time = pack(">LL", 0, 0)
|
|
182
|
-
return IndexEntry((base.mode, base.binsha, base.flags, base.path, time, time, 0, 0, 0, 0, 0))
|
|
195
|
+
return IndexEntry((base.mode, base.binsha, base.flags, base.path, time, time, 0, 0, 0, 0, 0)) # type: ignore[arg-type]
|
|
183
196
|
|
|
184
197
|
@classmethod
|
|
185
198
|
def from_blob(cls, blob: Blob, stage: int = 0) -> "IndexEntry":
|
|
@@ -198,5 +211,5 @@ class IndexEntry(BaseIndexEntry):
|
|
|
198
211
|
0,
|
|
199
212
|
0,
|
|
200
213
|
blob.size,
|
|
201
|
-
)
|
|
214
|
+
) # type: ignore[arg-type]
|
|
202
215
|
)
|
|
@@ -15,7 +15,7 @@ from types import TracebackType
|
|
|
15
15
|
|
|
16
16
|
# typing ----------------------------------------------------------------------
|
|
17
17
|
|
|
18
|
-
from typing import Any, Callable, TYPE_CHECKING, Optional, Type
|
|
18
|
+
from typing import Any, Callable, TYPE_CHECKING, Optional, Type, cast
|
|
19
19
|
|
|
20
20
|
from git.types import Literal, PathLike, _T
|
|
21
21
|
|
|
@@ -106,7 +106,7 @@ def git_working_dir(func: Callable[..., _T]) -> Callable[..., _T]:
|
|
|
106
106
|
@wraps(func)
|
|
107
107
|
def set_git_working_dir(self: "IndexFile", *args: Any, **kwargs: Any) -> _T:
|
|
108
108
|
cur_wd = os.getcwd()
|
|
109
|
-
os.chdir(
|
|
109
|
+
os.chdir(cast(PathLike, self.repo.working_tree_dir))
|
|
110
110
|
try:
|
|
111
111
|
return func(self, *args, **kwargs)
|
|
112
112
|
finally:
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
__all__ = ["Blob"]
|
|
7
7
|
|
|
8
8
|
from mimetypes import guess_type
|
|
9
|
+
import os
|
|
9
10
|
import sys
|
|
10
11
|
|
|
11
12
|
if sys.version_info >= (3, 8):
|
|
@@ -44,5 +45,5 @@ class Blob(base.IndexObject):
|
|
|
44
45
|
"""
|
|
45
46
|
guesses = None
|
|
46
47
|
if self.path:
|
|
47
|
-
guesses = guess_type(
|
|
48
|
+
guesses = guess_type(os.fspath(self.path))
|
|
48
49
|
return guesses and guesses[0] or self.DEFAULT_MIME_TYPE
|
|
@@ -900,7 +900,7 @@ class Commit(base.Object, TraversableIterableObj, Diffable, Serializable):
|
|
|
900
900
|
if self.message:
|
|
901
901
|
results = re.findall(
|
|
902
902
|
r"^Co-authored-by: (.*) <(.*?)>$",
|
|
903
|
-
self.message,
|
|
903
|
+
str(self.message),
|
|
904
904
|
re.MULTILINE,
|
|
905
905
|
)
|
|
906
906
|
for author in results:
|
|
@@ -66,7 +66,7 @@ from git.types import Commit_ish, PathLike, TBD
|
|
|
66
66
|
if TYPE_CHECKING:
|
|
67
67
|
from git.index import IndexFile
|
|
68
68
|
from git.objects.commit import Commit
|
|
69
|
-
from git.refs import Head
|
|
69
|
+
from git.refs import Head, RemoteReference
|
|
70
70
|
from git.repo import Repo
|
|
71
71
|
|
|
72
72
|
# -----------------------------------------------------------------------------
|
|
@@ -352,10 +352,10 @@ class Submodule(IndexObject, TraversableIterableObj):
|
|
|
352
352
|
module_abspath_dir = osp.dirname(module_abspath)
|
|
353
353
|
if not osp.isdir(module_abspath_dir):
|
|
354
354
|
os.makedirs(module_abspath_dir)
|
|
355
|
-
module_checkout_path = osp.join(
|
|
355
|
+
module_checkout_path = osp.join(repo.working_tree_dir, path) # type: ignore[arg-type]
|
|
356
356
|
|
|
357
357
|
if url.startswith("../"):
|
|
358
|
-
remote_name = repo.active_branch.tracking_branch().remote_name
|
|
358
|
+
remote_name = cast("RemoteReference", repo.active_branch.tracking_branch()).remote_name
|
|
359
359
|
repo_remote_url = repo.remote(remote_name).url
|
|
360
360
|
url = os.path.join(repo_remote_url, url)
|
|
361
361
|
|
|
@@ -541,7 +541,7 @@ class Submodule(IndexObject, TraversableIterableObj):
|
|
|
541
541
|
if sm.exists():
|
|
542
542
|
# Reretrieve submodule from tree.
|
|
543
543
|
try:
|
|
544
|
-
sm = repo.head.commit.tree[
|
|
544
|
+
sm = repo.head.commit.tree[os.fspath(path)]
|
|
545
545
|
sm._name = name
|
|
546
546
|
return sm
|
|
547
547
|
except KeyError:
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
__all__ = ["TreeModifier", "Tree"]
|
|
7
7
|
|
|
8
|
+
import os
|
|
8
9
|
import sys
|
|
9
10
|
|
|
10
11
|
import git.diff as git_diff
|
|
@@ -230,7 +231,7 @@ class Tree(IndexObject, git_diff.Diffable, util.Traversable, util.Serializable):
|
|
|
230
231
|
raise TypeError("Unknown mode %o found in tree data for path '%s'" % (mode, path)) from e
|
|
231
232
|
# END for each item
|
|
232
233
|
|
|
233
|
-
def join(self, file:
|
|
234
|
+
def join(self, file: PathLike) -> IndexObjUnion:
|
|
234
235
|
"""Find the named object in this tree's contents.
|
|
235
236
|
|
|
236
237
|
:return:
|
|
@@ -241,6 +242,7 @@ class Tree(IndexObject, git_diff.Diffable, util.Traversable, util.Serializable):
|
|
|
241
242
|
If the given file or tree does not exist in this tree.
|
|
242
243
|
"""
|
|
243
244
|
msg = "Blob or Tree named %r not found"
|
|
245
|
+
file = os.fspath(file)
|
|
244
246
|
if "/" in file:
|
|
245
247
|
tree = self
|
|
246
248
|
item = self
|
|
@@ -269,7 +271,7 @@ class Tree(IndexObject, git_diff.Diffable, util.Traversable, util.Serializable):
|
|
|
269
271
|
raise KeyError(msg % file)
|
|
270
272
|
# END handle long paths
|
|
271
273
|
|
|
272
|
-
def __truediv__(self, file:
|
|
274
|
+
def __truediv__(self, file: PathLike) -> IndexObjUnion:
|
|
273
275
|
"""The ``/`` operator is another syntax for joining.
|
|
274
276
|
|
|
275
277
|
See :meth:`join` for details.
|
|
@@ -22,7 +22,6 @@ from typing import Any, Sequence, TYPE_CHECKING, Union
|
|
|
22
22
|
from git.types import Commit_ish, PathLike
|
|
23
23
|
|
|
24
24
|
if TYPE_CHECKING:
|
|
25
|
-
from git.objects import Commit
|
|
26
25
|
from git.refs import RemoteReference
|
|
27
26
|
from git.repo import Repo
|
|
28
27
|
|
|
@@ -44,9 +43,6 @@ class HEAD(SymbolicReference):
|
|
|
44
43
|
|
|
45
44
|
__slots__ = ()
|
|
46
45
|
|
|
47
|
-
# TODO: This can be removed once SymbolicReference.commit has static type hints.
|
|
48
|
-
commit: "Commit"
|
|
49
|
-
|
|
50
46
|
def __init__(self, repo: "Repo", path: PathLike = _HEAD_NAME) -> None:
|
|
51
47
|
if path != self._HEAD_NAME:
|
|
52
48
|
raise ValueError("HEAD instance must point to %r, got %r" % (self._HEAD_NAME, path))
|
|
@@ -149,7 +145,7 @@ class Head(Reference):
|
|
|
149
145
|
k_config_remote_ref = "merge" # Branch to merge from remote.
|
|
150
146
|
|
|
151
147
|
@classmethod
|
|
152
|
-
def delete(cls, repo: "Repo", *heads: "Union[Head, str]", force: bool = False, **kwargs: Any) -> None:
|
|
148
|
+
def delete(cls, repo: "Repo", *heads: "Union[Head, str]", force: bool = False, **kwargs: Any) -> None: # type: ignore[override]
|
|
153
149
|
"""Delete the given heads.
|
|
154
150
|
|
|
155
151
|
:param force:
|
|
@@ -145,7 +145,7 @@ class RefLogEntry(Tuple[str, str, Actor, Tuple[int, int], str]):
|
|
|
145
145
|
actor = Actor._from_string(info[82 : email_end + 1])
|
|
146
146
|
time, tz_offset = parse_date(info[email_end + 2 :]) # skipcq: PYL-W0621
|
|
147
147
|
|
|
148
|
-
return RefLogEntry((oldhexsha, newhexsha, actor, (time, tz_offset), msg))
|
|
148
|
+
return RefLogEntry((oldhexsha, newhexsha, actor, (time, tz_offset), msg)) # type: ignore [arg-type]
|
|
149
149
|
|
|
150
150
|
|
|
151
151
|
class RefLog(List[RefLogEntry], Serializable):
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
__all__ = ["Reference"]
|
|
5
5
|
|
|
6
|
+
import os
|
|
6
7
|
from git.util import IterableObj, LazyMixin
|
|
7
8
|
|
|
8
9
|
from .symbolic import SymbolicReference, T_References
|
|
@@ -65,7 +66,7 @@ class Reference(SymbolicReference, LazyMixin, IterableObj):
|
|
|
65
66
|
If ``False``, you can provide any path.
|
|
66
67
|
Otherwise the path must start with the default path prefix of this type.
|
|
67
68
|
"""
|
|
68
|
-
if check_path and not
|
|
69
|
+
if check_path and not os.fspath(path).startswith(self._common_path_default + "/"):
|
|
69
70
|
raise ValueError(f"Cannot instantiate {self.__class__.__name__!r} from path {path}")
|
|
70
71
|
self.path: str # SymbolicReference converts to string at the moment.
|
|
71
72
|
super().__init__(repo, path)
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
__all__ = ["SymbolicReference"]
|
|
5
5
|
|
|
6
6
|
import os
|
|
7
|
+
from pathlib import Path
|
|
7
8
|
|
|
8
9
|
from gitdb.exc import BadName, BadObject
|
|
9
10
|
|
|
@@ -40,6 +41,7 @@ if TYPE_CHECKING:
|
|
|
40
41
|
from git.config import GitConfigParser
|
|
41
42
|
from git.objects.commit import Actor
|
|
42
43
|
from git.refs.log import RefLogEntry
|
|
44
|
+
from git.refs.reference import Reference
|
|
43
45
|
from git.repo import Repo
|
|
44
46
|
|
|
45
47
|
|
|
@@ -75,10 +77,10 @@ class SymbolicReference:
|
|
|
75
77
|
|
|
76
78
|
def __init__(self, repo: "Repo", path: PathLike, check_path: bool = False) -> None:
|
|
77
79
|
self.repo = repo
|
|
78
|
-
self.path = path
|
|
80
|
+
self.path: PathLike = path
|
|
79
81
|
|
|
80
82
|
def __str__(self) -> str:
|
|
81
|
-
return
|
|
83
|
+
return os.fspath(self.path)
|
|
82
84
|
|
|
83
85
|
def __repr__(self) -> str:
|
|
84
86
|
return '<git.%s "%s">' % (self.__class__.__name__, self.path)
|
|
@@ -102,7 +104,7 @@ class SymbolicReference:
|
|
|
102
104
|
In case of symbolic references, the shortest assumable name is the path
|
|
103
105
|
itself.
|
|
104
106
|
"""
|
|
105
|
-
return
|
|
107
|
+
return os.fspath(self.path)
|
|
106
108
|
|
|
107
109
|
@property
|
|
108
110
|
def abspath(self) -> PathLike:
|
|
@@ -177,7 +179,7 @@ class SymbolicReference:
|
|
|
177
179
|
"""
|
|
178
180
|
previous: Union[str, None] = None
|
|
179
181
|
one_before_previous: Union[str, None] = None
|
|
180
|
-
for c in
|
|
182
|
+
for c in os.fspath(ref_path):
|
|
181
183
|
if c in " ~^:?*[\\":
|
|
182
184
|
raise ValueError(
|
|
183
185
|
f"Invalid reference '{ref_path}': references cannot contain spaces, tildes (~), carets (^),"
|
|
@@ -211,7 +213,7 @@ class SymbolicReference:
|
|
|
211
213
|
raise ValueError(f"Invalid reference '{ref_path}': references cannot end with a forward slash (/)")
|
|
212
214
|
elif previous == "@" and one_before_previous is None:
|
|
213
215
|
raise ValueError(f"Invalid reference '{ref_path}': references cannot be '@'")
|
|
214
|
-
elif any(component.endswith(".lock") for component in
|
|
216
|
+
elif any(component.endswith(".lock") for component in Path(ref_path).parts):
|
|
215
217
|
raise ValueError(
|
|
216
218
|
f"Invalid reference '{ref_path}': references cannot have slash-separated components that end with"
|
|
217
219
|
" '.lock'"
|
|
@@ -234,7 +236,7 @@ class SymbolicReference:
|
|
|
234
236
|
tokens: Union[None, List[str], Tuple[str, str]] = None
|
|
235
237
|
repodir = _git_dir(repo, ref_path)
|
|
236
238
|
try:
|
|
237
|
-
with open(os.path.join(repodir,
|
|
239
|
+
with open(os.path.join(repodir, ref_path), "rt", encoding="UTF-8") as fp: # type: ignore[arg-type]
|
|
238
240
|
value = fp.read().rstrip()
|
|
239
241
|
# Don't only split on spaces, but on whitespace, which allows to parse lines like:
|
|
240
242
|
# 60b64ef992065e2600bfef6187a97f92398a9144 branch 'master' of git-server:/path/to/repo
|
|
@@ -404,7 +406,7 @@ class SymbolicReference:
|
|
|
404
406
|
def object(self, object: Union[AnyGitObject, "SymbolicReference", str]) -> "SymbolicReference":
|
|
405
407
|
return self.set_object(object)
|
|
406
408
|
|
|
407
|
-
def _get_reference(self) -> "
|
|
409
|
+
def _get_reference(self) -> "Reference":
|
|
408
410
|
"""
|
|
409
411
|
:return:
|
|
410
412
|
:class:`~git.refs.reference.Reference` object we point to
|
|
@@ -416,7 +418,7 @@ class SymbolicReference:
|
|
|
416
418
|
sha, target_ref_path = self._get_ref_info(self.repo, self.path)
|
|
417
419
|
if target_ref_path is None:
|
|
418
420
|
raise TypeError("%s is a detached symbolic reference as it points to %r" % (self, sha))
|
|
419
|
-
return self.from_path(self.repo, target_ref_path)
|
|
421
|
+
return cast("Reference", self.from_path(self.repo, target_ref_path))
|
|
420
422
|
|
|
421
423
|
def set_reference(
|
|
422
424
|
self,
|
|
@@ -502,7 +504,7 @@ class SymbolicReference:
|
|
|
502
504
|
|
|
503
505
|
# Aliased reference
|
|
504
506
|
@property
|
|
505
|
-
def reference(self) -> "
|
|
507
|
+
def reference(self) -> "Reference":
|
|
506
508
|
return self._get_reference()
|
|
507
509
|
|
|
508
510
|
@reference.setter
|
|
@@ -613,7 +615,7 @@ class SymbolicReference:
|
|
|
613
615
|
full_ref_path = path
|
|
614
616
|
if not cls._common_path_default:
|
|
615
617
|
return full_ref_path
|
|
616
|
-
if not
|
|
618
|
+
if not os.fspath(path).startswith(cls._common_path_default + "/"):
|
|
617
619
|
full_ref_path = "%s/%s" % (cls._common_path_default, path)
|
|
618
620
|
return full_ref_path
|
|
619
621
|
|
|
@@ -705,7 +707,7 @@ class SymbolicReference:
|
|
|
705
707
|
if not force and os.path.isfile(abs_ref_path):
|
|
706
708
|
target_data = str(target)
|
|
707
709
|
if isinstance(target, SymbolicReference):
|
|
708
|
-
target_data =
|
|
710
|
+
target_data = os.fspath(target.path)
|
|
709
711
|
if not resolve:
|
|
710
712
|
target_data = "ref: " + target_data
|
|
711
713
|
with open(abs_ref_path, "rb") as fd:
|
|
@@ -841,7 +843,7 @@ class SymbolicReference:
|
|
|
841
843
|
|
|
842
844
|
# Read packed refs.
|
|
843
845
|
for _sha, rela_path in cls._iter_packed_refs(repo):
|
|
844
|
-
if rela_path.startswith(
|
|
846
|
+
if rela_path.startswith(os.fspath(common_path)):
|
|
845
847
|
rela_paths.add(rela_path)
|
|
846
848
|
# END relative path matches common path
|
|
847
849
|
# END packed refs reading
|
|
@@ -915,8 +917,7 @@ class SymbolicReference:
|
|
|
915
917
|
SymbolicReference,
|
|
916
918
|
):
|
|
917
919
|
try:
|
|
918
|
-
instance
|
|
919
|
-
instance = ref_type(repo, path)
|
|
920
|
+
instance = cast(T_References, ref_type(repo, path))
|
|
920
921
|
if instance.__class__ is SymbolicReference and instance.is_detached:
|
|
921
922
|
raise ValueError("SymbolicRef was detached, we drop it")
|
|
922
923
|
else:
|
|
@@ -930,4 +931,4 @@ class SymbolicReference:
|
|
|
930
931
|
|
|
931
932
|
def is_remote(self) -> bool:
|
|
932
933
|
""":return: True if this symbolic reference points to a remote branch"""
|
|
933
|
-
return
|
|
934
|
+
return os.fspath(self.path).startswith(self._remote_common_path_default + "/")
|
|
@@ -45,8 +45,8 @@ class TagReference(Reference):
|
|
|
45
45
|
_common_default = "tags"
|
|
46
46
|
_common_path_default = Reference._common_path_default + "/" + _common_default
|
|
47
47
|
|
|
48
|
-
@property
|
|
49
|
-
def commit(self) -> "Commit": #
|
|
48
|
+
@property # type: ignore[misc]
|
|
49
|
+
def commit(self) -> "Commit": # LazyMixin has unrelated commit method
|
|
50
50
|
""":return: Commit object the tag ref points to
|
|
51
51
|
|
|
52
52
|
:raise ValueError:
|
|
@@ -80,8 +80,8 @@ class TagReference(Reference):
|
|
|
80
80
|
return None
|
|
81
81
|
|
|
82
82
|
# Make object read-only. It should be reasonably hard to adjust an existing tag.
|
|
83
|
-
@property
|
|
84
|
-
def object(self) -> AnyGitObject:
|
|
83
|
+
@property # type: ignore[misc]
|
|
84
|
+
def object(self) -> AnyGitObject:
|
|
85
85
|
return Reference._get_object(self)
|
|
86
86
|
|
|
87
87
|
@classmethod
|
|
@@ -126,6 +126,7 @@ class Repo:
|
|
|
126
126
|
working_dir: PathLike
|
|
127
127
|
"""The working directory of the git command."""
|
|
128
128
|
|
|
129
|
+
# stored as string for easier processing, but annotated as path for clearer intention
|
|
129
130
|
_working_tree_dir: Optional[PathLike] = None
|
|
130
131
|
|
|
131
132
|
git_dir: PathLike
|
|
@@ -215,15 +216,13 @@ class Repo:
|
|
|
215
216
|
epath = path or os.getenv("GIT_DIR")
|
|
216
217
|
if not epath:
|
|
217
218
|
epath = os.getcwd()
|
|
219
|
+
epath = os.fspath(epath)
|
|
218
220
|
if Git.is_cygwin():
|
|
219
221
|
# Given how the tests are written, this seems more likely to catch Cygwin
|
|
220
222
|
# git used from Windows than Windows git used from Cygwin. Therefore
|
|
221
223
|
# changing to Cygwin-style paths is the relevant operation.
|
|
222
|
-
epath = cygpath(
|
|
224
|
+
epath = cygpath(epath)
|
|
223
225
|
|
|
224
|
-
epath = epath or path or os.getcwd()
|
|
225
|
-
if not isinstance(epath, str):
|
|
226
|
-
epath = str(epath)
|
|
227
226
|
if expand_vars and re.search(self.re_envvars, epath):
|
|
228
227
|
warnings.warn(
|
|
229
228
|
"The use of environment variables in paths is deprecated"
|
|
@@ -520,7 +519,7 @@ class Repo:
|
|
|
520
519
|
"""
|
|
521
520
|
return RootModule(self).traverse(*args, **kwargs)
|
|
522
521
|
|
|
523
|
-
def submodule_update(self, *args: Any, **kwargs: Any) ->
|
|
522
|
+
def submodule_update(self, *args: Any, **kwargs: Any) -> RootModule:
|
|
524
523
|
"""Update the submodules, keeping the repository consistent as it will
|
|
525
524
|
take the previous state into consideration.
|
|
526
525
|
|
|
@@ -684,11 +683,7 @@ class Repo:
|
|
|
684
683
|
git_dir: Optional[PathLike] = None,
|
|
685
684
|
) -> GitConfigParser:
|
|
686
685
|
if config_level is None:
|
|
687
|
-
files = [
|
|
688
|
-
self._get_config_path(cast(Lit_config_levels, f), git_dir)
|
|
689
|
-
for f in self.config_level
|
|
690
|
-
if cast(Lit_config_levels, f)
|
|
691
|
-
]
|
|
686
|
+
files = [self._get_config_path(f, git_dir) for f in self.config_level if f]
|
|
692
687
|
else:
|
|
693
688
|
files = [self._get_config_path(config_level, git_dir)]
|
|
694
689
|
return GitConfigParser(files, read_only=True, repo=self)
|
|
@@ -961,7 +956,7 @@ class Repo:
|
|
|
961
956
|
if not submodules:
|
|
962
957
|
default_args.append("--ignore-submodules")
|
|
963
958
|
if path:
|
|
964
|
-
default_args.extend(["--",
|
|
959
|
+
default_args.extend(["--", os.fspath(path)])
|
|
965
960
|
if index:
|
|
966
961
|
# diff index against HEAD.
|
|
967
962
|
if osp.isfile(self.index.path) and len(self.git.diff("--cached", *default_args)):
|
|
@@ -1361,9 +1356,9 @@ class Repo:
|
|
|
1361
1356
|
) -> "Repo":
|
|
1362
1357
|
odbt = kwargs.pop("odbt", odb_default_type)
|
|
1363
1358
|
|
|
1364
|
-
#
|
|
1365
|
-
|
|
1366
|
-
|
|
1359
|
+
# url may be a path and this has no effect if it is a string
|
|
1360
|
+
url = os.fspath(url)
|
|
1361
|
+
path = os.fspath(path)
|
|
1367
1362
|
|
|
1368
1363
|
## A bug win cygwin's Git, when `--bare` or `--separate-git-dir`
|
|
1369
1364
|
# it prepends the cwd or(?) the `url` into the `path, so::
|
|
@@ -1380,7 +1375,7 @@ class Repo:
|
|
|
1380
1375
|
multi = shlex.split(" ".join(multi_options))
|
|
1381
1376
|
|
|
1382
1377
|
if not allow_unsafe_protocols:
|
|
1383
|
-
Git.check_unsafe_protocols(
|
|
1378
|
+
Git.check_unsafe_protocols(url)
|
|
1384
1379
|
if not allow_unsafe_options:
|
|
1385
1380
|
Git.check_unsafe_options(options=list(kwargs.keys()), unsafe_options=cls.unsafe_git_clone_options)
|
|
1386
1381
|
if not allow_unsafe_options and multi_options:
|
|
@@ -1389,7 +1384,7 @@ class Repo:
|
|
|
1389
1384
|
proc = git.clone(
|
|
1390
1385
|
multi,
|
|
1391
1386
|
"--",
|
|
1392
|
-
Git.polish_url(
|
|
1387
|
+
Git.polish_url(url),
|
|
1393
1388
|
clone_path,
|
|
1394
1389
|
with_extended_output=True,
|
|
1395
1390
|
as_process=True,
|
|
@@ -1484,7 +1479,7 @@ class Repo:
|
|
|
1484
1479
|
self.common_dir,
|
|
1485
1480
|
path,
|
|
1486
1481
|
type(self.odb),
|
|
1487
|
-
progress,
|
|
1482
|
+
progress, # type: ignore[arg-type]
|
|
1488
1483
|
multi_options,
|
|
1489
1484
|
allow_unsafe_protocols=allow_unsafe_protocols,
|
|
1490
1485
|
allow_unsafe_options=allow_unsafe_options,
|
|
@@ -1545,7 +1540,7 @@ class Repo:
|
|
|
1545
1540
|
url,
|
|
1546
1541
|
to_path,
|
|
1547
1542
|
GitCmdObjectDB,
|
|
1548
|
-
progress,
|
|
1543
|
+
progress, # type: ignore[arg-type]
|
|
1549
1544
|
multi_options,
|
|
1550
1545
|
allow_unsafe_protocols=allow_unsafe_protocols,
|
|
1551
1546
|
allow_unsafe_options=allow_unsafe_options,
|
|
@@ -13,7 +13,6 @@ from typing import (
|
|
|
13
13
|
Sequence as Sequence,
|
|
14
14
|
Tuple,
|
|
15
15
|
TYPE_CHECKING,
|
|
16
|
-
Type,
|
|
17
16
|
TypeVar,
|
|
18
17
|
Union,
|
|
19
18
|
)
|
|
@@ -130,7 +129,8 @@ See :manpage:`gitglossary(7)` on "object type":
|
|
|
130
129
|
https://git-scm.com/docs/gitglossary#def_object_type
|
|
131
130
|
"""
|
|
132
131
|
|
|
133
|
-
|
|
132
|
+
if TYPE_CHECKING:
|
|
133
|
+
Lit_commit_ish = Literal["commit", "tag"]
|
|
134
134
|
"""Deprecated. Type of literal strings identifying typically-commitish git object types.
|
|
135
135
|
|
|
136
136
|
Prior to a bugfix, this type had been defined more broadly. Any usage is in practice
|
|
@@ -36,7 +36,7 @@ import getpass
|
|
|
36
36
|
import logging
|
|
37
37
|
import os
|
|
38
38
|
import os.path as osp
|
|
39
|
-
import
|
|
39
|
+
from pathlib import Path
|
|
40
40
|
import platform
|
|
41
41
|
import re
|
|
42
42
|
import shutil
|
|
@@ -272,9 +272,9 @@ def stream_copy(source: BinaryIO, destination: BinaryIO, chunk_size: int = 512 *
|
|
|
272
272
|
def join_path(a: PathLike, *p: PathLike) -> PathLike:
|
|
273
273
|
R"""Join path tokens together similar to osp.join, but always use ``/`` instead of
|
|
274
274
|
possibly ``\`` on Windows."""
|
|
275
|
-
path =
|
|
275
|
+
path = os.fspath(a)
|
|
276
276
|
for b in p:
|
|
277
|
-
b =
|
|
277
|
+
b = os.fspath(b)
|
|
278
278
|
if not b:
|
|
279
279
|
continue
|
|
280
280
|
if b.startswith("/"):
|
|
@@ -290,18 +290,18 @@ def join_path(a: PathLike, *p: PathLike) -> PathLike:
|
|
|
290
290
|
if sys.platform == "win32":
|
|
291
291
|
|
|
292
292
|
def to_native_path_windows(path: PathLike) -> PathLike:
|
|
293
|
-
path =
|
|
293
|
+
path = os.fspath(path)
|
|
294
294
|
return path.replace("/", "\\")
|
|
295
295
|
|
|
296
296
|
def to_native_path_linux(path: PathLike) -> str:
|
|
297
|
-
path =
|
|
297
|
+
path = os.fspath(path)
|
|
298
298
|
return path.replace("\\", "/")
|
|
299
299
|
|
|
300
300
|
to_native_path = to_native_path_windows
|
|
301
301
|
else:
|
|
302
302
|
# No need for any work on Linux.
|
|
303
303
|
def to_native_path_linux(path: PathLike) -> str:
|
|
304
|
-
return
|
|
304
|
+
return os.fspath(path)
|
|
305
305
|
|
|
306
306
|
to_native_path = to_native_path_linux
|
|
307
307
|
|
|
@@ -372,7 +372,7 @@ def py_where(program: str, path: Optional[PathLike] = None) -> List[str]:
|
|
|
372
372
|
progs = []
|
|
373
373
|
if not path:
|
|
374
374
|
path = os.environ["PATH"]
|
|
375
|
-
for folder in
|
|
375
|
+
for folder in os.fspath(path).split(os.pathsep):
|
|
376
376
|
folder = folder.strip('"')
|
|
377
377
|
if folder:
|
|
378
378
|
exe_path = osp.join(folder, program)
|
|
@@ -397,7 +397,7 @@ def _cygexpath(drive: Optional[str], path: str) -> str:
|
|
|
397
397
|
p = cygpath(p)
|
|
398
398
|
elif drive:
|
|
399
399
|
p = "/proc/cygdrive/%s/%s" % (drive.lower(), p)
|
|
400
|
-
p_str =
|
|
400
|
+
p_str = os.fspath(p) # ensure it is a str and not AnyPath
|
|
401
401
|
return p_str.replace("\\", "/")
|
|
402
402
|
|
|
403
403
|
|
|
@@ -418,7 +418,7 @@ _cygpath_parsers: Tuple[Tuple[Pattern[str], Callable, bool], ...] = (
|
|
|
418
418
|
|
|
419
419
|
def cygpath(path: str) -> str:
|
|
420
420
|
"""Use :meth:`git.cmd.Git.polish_url` instead, that works on any environment."""
|
|
421
|
-
path =
|
|
421
|
+
path = os.fspath(path) # Ensure is str and not AnyPath.
|
|
422
422
|
# Fix to use Paths when 3.5 dropped. Or to be just str if only for URLs?
|
|
423
423
|
if not path.startswith(("/cygdrive", "//", "/proc/cygdrive")):
|
|
424
424
|
for regex, parser, recurse in _cygpath_parsers:
|
|
@@ -438,7 +438,7 @@ _decygpath_regex = re.compile(r"(?:/proc)?/cygdrive/(\w)(/.*)?")
|
|
|
438
438
|
|
|
439
439
|
|
|
440
440
|
def decygpath(path: PathLike) -> str:
|
|
441
|
-
path =
|
|
441
|
+
path = os.fspath(path)
|
|
442
442
|
m = _decygpath_regex.match(path)
|
|
443
443
|
if m:
|
|
444
444
|
drive, rest_path = m.groups()
|
|
@@ -465,7 +465,7 @@ def _is_cygwin_git(git_executable: str) -> bool:
|
|
|
465
465
|
# Just a name given, not a real path.
|
|
466
466
|
uname_cmd = osp.join(git_dir, "uname")
|
|
467
467
|
|
|
468
|
-
if not (
|
|
468
|
+
if not (Path(uname_cmd).is_file() and os.access(uname_cmd, os.X_OK)):
|
|
469
469
|
_logger.debug(f"Failed checking if running in CYGWIN: {uname_cmd} is not an executable")
|
|
470
470
|
_is_cygwin_cache[git_executable] = is_cygwin
|
|
471
471
|
return is_cygwin
|
|
@@ -523,7 +523,7 @@ def expand_path(p: PathLike, expand_vars: bool = ...) -> str:
|
|
|
523
523
|
|
|
524
524
|
|
|
525
525
|
def expand_path(p: Union[None, PathLike], expand_vars: bool = True) -> Optional[PathLike]:
|
|
526
|
-
if isinstance(p,
|
|
526
|
+
if isinstance(p, Path):
|
|
527
527
|
return p.resolve()
|
|
528
528
|
try:
|
|
529
529
|
p = osp.expanduser(p) # type: ignore[arg-type]
|
|
@@ -1143,7 +1143,7 @@ class BlockingLockFile(LockFile):
|
|
|
1143
1143
|
# END endless loop
|
|
1144
1144
|
|
|
1145
1145
|
|
|
1146
|
-
class IterableList(List[T_IterableObj]):
|
|
1146
|
+
class IterableList(List[T_IterableObj]): # type: ignore[type-var]
|
|
1147
1147
|
"""List of iterable objects allowing to query an object by id or by named index::
|
|
1148
1148
|
|
|
1149
1149
|
heads = repo.heads
|
|
@@ -1214,14 +1214,14 @@ class IterableList(List[T_IterableObj]):
|
|
|
1214
1214
|
raise ValueError("Index should be an int or str")
|
|
1215
1215
|
else:
|
|
1216
1216
|
try:
|
|
1217
|
-
return getattr(self, index)
|
|
1217
|
+
return getattr(self, cast(str, index))
|
|
1218
1218
|
except AttributeError as e:
|
|
1219
|
-
raise IndexError("No item found with id
|
|
1219
|
+
raise IndexError(f"No item found with id {self._prefix}{index}") from e
|
|
1220
1220
|
# END handle getattr
|
|
1221
1221
|
|
|
1222
1222
|
def __delitem__(self, index: Union[SupportsIndex, int, slice, str]) -> None:
|
|
1223
1223
|
delindex = cast(int, index)
|
|
1224
|
-
if
|
|
1224
|
+
if isinstance(index, str):
|
|
1225
1225
|
delindex = -1
|
|
1226
1226
|
name = self._prefix + index
|
|
1227
1227
|
for i, item in enumerate(self):
|
|
@@ -19,7 +19,6 @@ testpaths = "test" # Space separated list of paths from root e.g test tests doc
|
|
|
19
19
|
# filterwarnings ignore::WarningType # ignores those warnings
|
|
20
20
|
|
|
21
21
|
[tool.mypy]
|
|
22
|
-
python_version = "3.8"
|
|
23
22
|
files = ["git/", "test/deprecation/"]
|
|
24
23
|
disallow_untyped_defs = true
|
|
25
24
|
no_implicit_optional = true
|
gitpython-3.1.45/VERSION
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
3.1.45
|
|
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
|
|
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
|