49
49
50
50
51
51
# typing ----------------------------------------------------------------------
52
- from typing import Callable , Dict , TYPE_CHECKING
52
+ from typing import Callable , Dict , Mapping , Sequence , TYPE_CHECKING
53
53
from typing import Any , Iterator , Union
54
54
55
- from git .types import Commit_ish , PathLike
55
+ from git .types import Commit_ish , PathLike , TBD
56
56
57
57
if TYPE_CHECKING :
58
58
from git .repo import Repo
@@ -227,7 +227,7 @@ def _config_parser(cls, repo: 'Repo',
227
227
228
228
return SubmoduleConfigParser (fp_module , read_only = read_only )
229
229
230
- def _clear_cache (self ):
230
+ def _clear_cache (self ) -> None :
231
231
# clear the possibly changed values
232
232
for name in self ._cache_attrs :
233
233
try :
@@ -247,7 +247,7 @@ def _sio_modules(cls, parent_commit: Commit_ish) -> BytesIO:
247
247
def _config_parser_constrained (self , read_only : bool ) -> SectionConstraint :
248
248
""":return: Config Parser constrained to our submodule in read or write mode"""
249
249
try :
250
- pc = self .parent_commit
250
+ pc : Union [ 'Commit_ish' , None ] = self .parent_commit
251
251
except ValueError :
252
252
pc = None
253
253
# end handle empty parent repository
@@ -256,10 +256,12 @@ def _config_parser_constrained(self, read_only: bool) -> SectionConstraint:
256
256
return SectionConstraint (parser , sm_section (self .name ))
257
257
258
258
@classmethod
259
- def _module_abspath (cls , parent_repo , path , name ) :
259
+ def _module_abspath (cls , parent_repo : 'Repo' , path : PathLike , name : str ) -> PathLike :
260
260
if cls ._need_gitfile_submodules (parent_repo .git ):
261
261
return osp .join (parent_repo .git_dir , 'modules' , name )
262
- return osp .join (parent_repo .working_tree_dir , path )
262
+ if parent_repo .working_tree_dir :
263
+ return osp .join (parent_repo .working_tree_dir , path )
264
+ raise NotADirectoryError ()
263
265
# end
264
266
265
267
@classmethod
@@ -287,15 +289,15 @@ def _clone_repo(cls, repo, url, path, name, **kwargs):
287
289
return clone
288
290
289
291
@classmethod
290
- def _to_relative_path (cls , parent_repo , path ) :
292
+ def _to_relative_path (cls , parent_repo : 'Repo' , path : PathLike ) -> PathLike :
291
293
""":return: a path guaranteed to be relative to the given parent - repository
292
294
:raise ValueError: if path is not contained in the parent repository's working tree"""
293
295
path = to_native_path_linux (path )
294
296
if path .endswith ('/' ):
295
297
path = path [:- 1 ]
296
298
# END handle trailing slash
297
299
298
- if osp .isabs (path ):
300
+ if osp .isabs (path ) and parent_repo . working_tree_dir :
299
301
working_tree_linux = to_native_path_linux (parent_repo .working_tree_dir )
300
302
if not path .startswith (working_tree_linux ):
301
303
raise ValueError ("Submodule checkout path '%s' needs to be within the parents repository at '%s'"
@@ -309,7 +311,7 @@ def _to_relative_path(cls, parent_repo, path):
309
311
return path
310
312
311
313
@classmethod
312
- def _write_git_file_and_module_config (cls , working_tree_dir , module_abspath ) :
314
+ def _write_git_file_and_module_config (cls , working_tree_dir : PathLike , module_abspath : PathLike ) -> None :
313
315
"""Writes a .git file containing a(preferably) relative path to the actual git module repository.
314
316
It is an error if the module_abspath cannot be made into a relative path, relative to the working_tree_dir
315
317
:note: will overwrite existing files !
@@ -336,7 +338,8 @@ def _write_git_file_and_module_config(cls, working_tree_dir, module_abspath):
336
338
337
339
@classmethod
338
340
def add (cls , repo : 'Repo' , name : str , path : PathLike , url : Union [str , None ] = None ,
339
- branch = None , no_checkout : bool = False , depth = None , env = None , clone_multi_options = None
341
+ branch : Union [str , None ] = None , no_checkout : bool = False , depth : Union [int , None ] = None ,
342
+ env : Mapping [str , str ] = None , clone_multi_options : Union [Sequence [TBD ], None ] = None
340
343
) -> 'Submodule' :
341
344
"""Add a new submodule to the given repository. This will alter the index
342
345
as well as the .gitmodules file, but will not create a new commit.
@@ -415,7 +418,8 @@ def add(cls, repo: 'Repo', name: str, path: PathLike, url: Union[str, None] = No
415
418
# END check url
416
419
# END verify urls match
417
420
418
- mrepo = None
421
+ # mrepo: Union[Repo, None] = None
422
+
419
423
if url is None :
420
424
if not has_module :
421
425
raise ValueError ("A URL was not given and a repository did not exist at %s" % path )
@@ -428,7 +432,7 @@ def add(cls, repo: 'Repo', name: str, path: PathLike, url: Union[str, None] = No
428
432
url = urls [0 ]
429
433
else :
430
434
# clone new repo
431
- kwargs : Dict [str , Union [bool , int ]] = {'n' : no_checkout }
435
+ kwargs : Dict [str , Union [bool , int , Sequence [ TBD ] ]] = {'n' : no_checkout }
432
436
if not branch_is_default :
433
437
kwargs ['b' ] = br .name
434
438
# END setup checkout-branch
@@ -452,6 +456,8 @@ def add(cls, repo: 'Repo', name: str, path: PathLike, url: Union[str, None] = No
452
456
# otherwise there is a '-' character in front of the submodule listing
453
457
# a38efa84daef914e4de58d1905a500d8d14aaf45 mymodule (v0.9.0-1-ga38efa8)
454
458
# -a38efa84daef914e4de58d1905a500d8d14aaf45 submodules/intermediate/one
459
+ writer : Union [GitConfigParser , SectionConstraint ]
460
+
455
461
with sm .repo .config_writer () as writer :
456
462
writer .set_value (sm_section (name ), 'url' , url )
457
463
@@ -473,8 +479,10 @@ def add(cls, repo: 'Repo', name: str, path: PathLike, url: Union[str, None] = No
473
479
474
480
return sm
475
481
476
- def update (self , recursive = False , init = True , to_latest_revision = False , progress = None , dry_run = False ,
477
- force = False , keep_going = False , env = None , clone_multi_options = None ):
482
+ def update (self , recursive : bool = False , init : bool = True , to_latest_revision : bool = False ,
483
+ progress : Union ['UpdateProgress' , None ] = None , dry_run : bool = False ,
484
+ force : bool = False , keep_going : bool = False , env : Mapping [str , str ] = None ,
485
+ clone_multi_options : Union [Sequence [TBD ], None ] = None ):
478
486
"""Update the repository of this submodule to point to the checkout
479
487
we point at with the binsha of this instance.
480
488
@@ -581,6 +589,7 @@ def update(self, recursive=False, init=True, to_latest_revision=False, progress=
581
589
if not dry_run :
582
590
# see whether we have a valid branch to checkout
583
591
try :
592
+ assert isinstance (mrepo , Repo )
584
593
# find a remote which has our branch - we try to be flexible
585
594
remote_branch = find_first_remote_branch (mrepo .remotes , self .branch_name )
586
595
local_branch = mkhead (mrepo , self .branch_path )
@@ -641,7 +650,7 @@ def update(self, recursive=False, init=True, to_latest_revision=False, progress=
641
650
may_reset = True
642
651
if mrepo .head .commit .binsha != self .NULL_BIN_SHA :
643
652
base_commit = mrepo .merge_base (mrepo .head .commit , hexsha )
644
- if len (base_commit ) == 0 or base_commit [0 ].hexsha == hexsha :
653
+ if len (base_commit ) == 0 or ( base_commit [0 ] is not None and base_commit [ 0 ] .hexsha == hexsha ) :
645
654
if force :
646
655
msg = "Will force checkout or reset on local branch that is possibly in the future of"
647
656
msg += "the commit it will be checked out to, effectively 'forgetting' new commits"
@@ -916,7 +925,7 @@ def remove(self, module: bool = True, force: bool = False,
916
925
import gc
917
926
gc .collect ()
918
927
try :
919
- rmtree (wtd )
928
+ rmtree (str ( wtd ) )
920
929
except Exception as ex :
921
930
if HIDE_WINDOWS_KNOWN_ERRORS :
922
931
raise SkipTest ("FIXME: fails with: PermissionError\n {}" .format (ex )) from ex
@@ -954,6 +963,8 @@ def remove(self, module: bool = True, force: bool = False,
954
963
955
964
# now git config - need the config intact, otherwise we can't query
956
965
# information anymore
966
+ writer : Union [GitConfigParser , SectionConstraint ]
967
+
957
968
with self .repo .config_writer () as writer :
958
969
writer .remove_section (sm_section (self .name ))
959
970
@@ -1067,13 +1078,14 @@ def rename(self, new_name: str) -> 'Submodule':
1067
1078
destination_module_abspath = self ._module_abspath (self .repo , self .path , new_name )
1068
1079
source_dir = mod .git_dir
1069
1080
# Let's be sure the submodule name is not so obviously tied to a directory
1070
- if destination_module_abspath .startswith (mod .git_dir ):
1081
+ if str ( destination_module_abspath ) .startswith (str ( mod .git_dir ) ):
1071
1082
tmp_dir = self ._module_abspath (self .repo , self .path , str (uuid .uuid4 ()))
1072
1083
os .renames (source_dir , tmp_dir )
1073
1084
source_dir = tmp_dir
1074
1085
# end handle self-containment
1075
1086
os .renames (source_dir , destination_module_abspath )
1076
- self ._write_git_file_and_module_config (mod .working_tree_dir , destination_module_abspath )
1087
+ if mod .working_tree_dir :
1088
+ self ._write_git_file_and_module_config (mod .working_tree_dir , destination_module_abspath )
1077
1089
# end move separate git repository
1078
1090
1079
1091
return self
@@ -1150,34 +1162,34 @@ def branch(self):
1150
1162
return mkhead (self .module (), self ._branch_path )
1151
1163
1152
1164
@property
1153
- def branch_path (self ):
1165
+ def branch_path (self ) -> PathLike :
1154
1166
"""
1155
1167
:return: full(relative) path as string to the branch we would checkout
1156
1168
from the remote and track"""
1157
1169
return self ._branch_path
1158
1170
1159
1171
@property
1160
- def branch_name (self ):
1172
+ def branch_name (self ) -> str :
1161
1173
""":return: the name of the branch, which is the shortest possible branch name"""
1162
1174
# use an instance method, for this we create a temporary Head instance
1163
1175
# which uses a repository that is available at least ( it makes no difference )
1164
1176
return git .Head (self .repo , self ._branch_path ).name
1165
1177
1166
1178
@property
1167
- def url (self ):
1179
+ def url (self ) -> str :
1168
1180
""":return: The url to the repository which our module - repository refers to"""
1169
1181
return self ._url
1170
1182
1171
1183
@property
1172
- def parent_commit (self ):
1184
+ def parent_commit (self ) -> 'Commit_ish' :
1173
1185
""":return: Commit instance with the tree containing the .gitmodules file
1174
1186
:note: will always point to the current head's commit if it was not set explicitly"""
1175
1187
if self ._parent_commit is None :
1176
1188
return self .repo .commit ()
1177
1189
return self ._parent_commit
1178
1190
1179
1191
@property
1180
- def name (self ):
1192
+ def name (self ) -> str :
1181
1193
""":return: The name of this submodule. It is used to identify it within the
1182
1194
.gitmodules file.
1183
1195
:note: by default, the name is the path at which to find the submodule, but
0 commit comments