4949
5050
5151# typing ----------------------------------------------------------------------
52- from typing import Callable , Dict , Mapping , Sequence , TYPE_CHECKING , cast
52+ from typing import Dict , TYPE_CHECKING
5353from typing import Any , Iterator , Union
5454
55- from git .types import Commit_ish , PathLike , TBD
55+ from git .types import Commit_ish , PathLike
5656
5757if TYPE_CHECKING :
5858 from git .repo import Repo
59- from git .index import IndexFile
6059
6160
6261# -----------------------------------------------------------------------------
@@ -132,17 +131,17 @@ def __init__(self, repo: 'Repo', binsha: bytes,
132131 if url is not None :
133132 self ._url = url
134133 if branch_path is not None :
135- # assert isinstance(branch_path, str)
134+ assert isinstance (branch_path , str )
136135 self ._branch_path = branch_path
137136 if name is not None :
138137 self ._name = name
139138
140139 def _set_cache_ (self , attr : str ) -> None :
141140 if attr in ('path' , '_url' , '_branch_path' ):
142- reader : SectionConstraint = self .config_reader ()
141+ reader = self .config_reader ()
143142 # default submodule values
144143 try :
145- self .path : PathLike = reader .get ('path' )
144+ self .path = reader .get ('path' )
146145 except cp .NoSectionError as e :
147146 if self .repo .working_tree_dir is not None :
148147 raise ValueError ("This submodule instance does not exist anymore in '%s' file"
@@ -227,7 +226,7 @@ def _config_parser(cls, repo: 'Repo',
227226
228227 return SubmoduleConfigParser (fp_module , read_only = read_only )
229228
230- def _clear_cache (self ) -> None :
229+ def _clear_cache (self ):
231230 # clear the possibly changed values
232231 for name in self ._cache_attrs :
233232 try :
@@ -247,7 +246,7 @@ def _sio_modules(cls, parent_commit: Commit_ish) -> BytesIO:
247246 def _config_parser_constrained (self , read_only : bool ) -> SectionConstraint :
248247 """:return: Config Parser constrained to our submodule in read or write mode"""
249248 try :
250- pc : Union [ 'Commit_ish' , None ] = self .parent_commit
249+ pc = self .parent_commit
251250 except ValueError :
252251 pc = None
253252 # end handle empty parent repository
@@ -256,12 +255,10 @@ def _config_parser_constrained(self, read_only: bool) -> SectionConstraint:
256255 return SectionConstraint (parser , sm_section (self .name ))
257256
258257 @classmethod
259- def _module_abspath (cls , parent_repo : 'Repo' , path : PathLike , name : str ) -> PathLike :
258+ def _module_abspath (cls , parent_repo , path , name ) :
260259 if cls ._need_gitfile_submodules (parent_repo .git ):
261260 return osp .join (parent_repo .git_dir , 'modules' , name )
262- if parent_repo .working_tree_dir :
263- return osp .join (parent_repo .working_tree_dir , path )
264- raise NotADirectoryError ()
261+ return osp .join (parent_repo .working_tree_dir , path )
265262 # end
266263
267264 @classmethod
@@ -289,15 +286,15 @@ def _clone_repo(cls, repo, url, path, name, **kwargs):
289286 return clone
290287
291288 @classmethod
292- def _to_relative_path (cls , parent_repo : 'Repo' , path : PathLike ) -> PathLike :
289+ def _to_relative_path (cls , parent_repo , path ) :
293290 """:return: a path guaranteed to be relative to the given parent - repository
294291 :raise ValueError: if path is not contained in the parent repository's working tree"""
295292 path = to_native_path_linux (path )
296293 if path .endswith ('/' ):
297294 path = path [:- 1 ]
298295 # END handle trailing slash
299296
300- if osp .isabs (path ) and parent_repo . working_tree_dir :
297+ if osp .isabs (path ):
301298 working_tree_linux = to_native_path_linux (parent_repo .working_tree_dir )
302299 if not path .startswith (working_tree_linux ):
303300 raise ValueError ("Submodule checkout path '%s' needs to be within the parents repository at '%s'"
@@ -311,7 +308,7 @@ def _to_relative_path(cls, parent_repo: 'Repo', path: PathLike) -> PathLike:
311308 return path
312309
313310 @classmethod
314- def _write_git_file_and_module_config (cls , working_tree_dir : PathLike , module_abspath : PathLike ) -> None :
311+ def _write_git_file_and_module_config (cls , working_tree_dir , module_abspath ) :
315312 """Writes a .git file containing a(preferably) relative path to the actual git module repository.
316313 It is an error if the module_abspath cannot be made into a relative path, relative to the working_tree_dir
317314 :note: will overwrite existing files !
@@ -338,8 +335,7 @@ def _write_git_file_and_module_config(cls, working_tree_dir: PathLike, module_ab
338335
339336 @classmethod
340337 def add (cls , repo : 'Repo' , name : str , path : PathLike , url : Union [str , None ] = 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
338+ branch = None , no_checkout : bool = False , depth = None , env = None
343339 ) -> 'Submodule' :
344340 """Add a new submodule to the given repository. This will alter the index
345341 as well as the .gitmodules file, but will not create a new commit.
@@ -373,8 +369,6 @@ def add(cls, repo: 'Repo', name: str, path: PathLike, url: Union[str, None] = No
373369 and is defined in `os.environ`, value from `os.environ` will be used.
374370 If you want to unset some variable, consider providing empty string
375371 as its value.
376- :param clone_multi_options: A list of Clone options. Please see ``git.repo.base.Repo.clone``
377- for details.
378372 :return: The newly created submodule instance
379373 :note: works atomically, such that no change will be done if the repository
380374 update fails for instance"""
@@ -387,15 +381,15 @@ def add(cls, repo: 'Repo', name: str, path: PathLike, url: Union[str, None] = No
387381 # assure we never put backslashes into the url, as some operating systems
388382 # like it ...
389383 if url is not None :
390- url = to_native_path_linux (url )
384+ url = to_native_path_linux (url ) # to_native_path_linux does nothing??
391385 # END assure url correctness
392386
393387 # INSTANTIATE INTERMEDIATE SM
394388 sm = cls (repo , cls .NULL_BIN_SHA , cls .k_default_mode , path , name , url = 'invalid-temporary' )
395389 if sm .exists ():
396390 # reretrieve submodule from tree
397391 try :
398- sm = repo .head .commit .tree [str ( path )]
392+ sm = repo .head .commit .tree [path ] # type: ignore
399393 sm ._name = name
400394 return sm
401395 except KeyError :
@@ -418,8 +412,7 @@ def add(cls, repo: 'Repo', name: str, path: PathLike, url: Union[str, None] = No
418412 # END check url
419413 # END verify urls match
420414
421- mrepo : Union [Repo , None ] = None
422-
415+ mrepo = None
423416 if url is None :
424417 if not has_module :
425418 raise ValueError ("A URL was not given and a repository did not exist at %s" % path )
@@ -432,7 +425,7 @@ def add(cls, repo: 'Repo', name: str, path: PathLike, url: Union[str, None] = No
432425 url = urls [0 ]
433426 else :
434427 # clone new repo
435- kwargs : Dict [str , Union [bool , int , Sequence [ TBD ] ]] = {'n' : no_checkout }
428+ kwargs : Dict [str , Union [bool , int ]] = {'n' : no_checkout }
436429 if not branch_is_default :
437430 kwargs ['b' ] = br .name
438431 # END setup checkout-branch
@@ -442,8 +435,6 @@ def add(cls, repo: 'Repo', name: str, path: PathLike, url: Union[str, None] = No
442435 kwargs ['depth' ] = depth
443436 else :
444437 raise ValueError ("depth should be an integer" )
445- if clone_multi_options :
446- kwargs ['multi_options' ] = clone_multi_options
447438
448439 # _clone_repo(cls, repo, url, path, name, **kwargs):
449440 mrepo = cls ._clone_repo (repo , url , path , name , env = env , ** kwargs )
@@ -456,8 +447,6 @@ def add(cls, repo: 'Repo', name: str, path: PathLike, url: Union[str, None] = No
456447 # otherwise there is a '-' character in front of the submodule listing
457448 # a38efa84daef914e4de58d1905a500d8d14aaf45 mymodule (v0.9.0-1-ga38efa8)
458449 # -a38efa84daef914e4de58d1905a500d8d14aaf45 submodules/intermediate/one
459- writer : Union [GitConfigParser , SectionConstraint ]
460-
461450 with sm .repo .config_writer () as writer :
462451 writer .set_value (sm_section (name ), 'url' , url )
463452
@@ -474,16 +463,13 @@ def add(cls, repo: 'Repo', name: str, path: PathLike, url: Union[str, None] = No
474463 sm ._branch_path = br .path
475464
476465 # we deliberately assume that our head matches our index !
477- mrepo = cast ('Repo' , mrepo )
478466 sm .binsha = mrepo .head .commit .binsha
479467 index .add ([sm ], write = True )
480468
481469 return sm
482470
483- def update (self , recursive : bool = False , init : bool = True , to_latest_revision : bool = False ,
484- progress : Union ['UpdateProgress' , None ] = None , dry_run : bool = False ,
485- force : bool = False , keep_going : bool = False , env : Mapping [str , str ] = None ,
486- clone_multi_options : Union [Sequence [TBD ], None ] = None ):
471+ def update (self , recursive = False , init = True , to_latest_revision = False , progress = None , dry_run = False ,
472+ force = False , keep_going = False , env = None ):
487473 """Update the repository of this submodule to point to the checkout
488474 we point at with the binsha of this instance.
489475
@@ -514,8 +500,6 @@ def update(self, recursive: bool = False, init: bool = True, to_latest_revision:
514500 and is defined in `os.environ`, value from `os.environ` will be used.
515501 If you want to unset some variable, consider providing empty string
516502 as its value.
517- :param clone_multi_options: list of Clone options. Please see ``git.repo.base.Repo.clone``
518- for details. Only take effect with `init` option.
519503 :note: does nothing in bare repositories
520504 :note: method is definitely not atomic if recurisve is True
521505 :return: self"""
@@ -582,16 +566,13 @@ def update(self, recursive: bool = False, init: bool = True, to_latest_revision:
582566 progress .update (BEGIN | CLONE , 0 , 1 , prefix + "Cloning url '%s' to '%s' in submodule %r" %
583567 (self .url , checkout_module_abspath , self .name ))
584568 if not dry_run :
585- mrepo = self ._clone_repo (self .repo , self .url , self .path , self .name , n = True , env = env ,
586- multi_options = clone_multi_options )
569+ mrepo = self ._clone_repo (self .repo , self .url , self .path , self .name , n = True , env = env )
587570 # END handle dry-run
588571 progress .update (END | CLONE , 0 , 1 , prefix + "Done cloning to %s" % checkout_module_abspath )
589572
590573 if not dry_run :
591574 # see whether we have a valid branch to checkout
592575 try :
593- # assert isinstance(mrepo, Repo) # cant do this cos of circular import
594- mrepo = cast ('Repo' , mrepo ) # Try TypeGuard wirh hasattr, or has_remotes&_head protocol?
595576 # find a remote which has our branch - we try to be flexible
596577 remote_branch = find_first_remote_branch (mrepo .remotes , self .branch_name )
597578 local_branch = mkhead (mrepo , self .branch_path )
@@ -652,7 +633,7 @@ def update(self, recursive: bool = False, init: bool = True, to_latest_revision:
652633 may_reset = True
653634 if mrepo .head .commit .binsha != self .NULL_BIN_SHA :
654635 base_commit = mrepo .merge_base (mrepo .head .commit , hexsha )
655- if len (base_commit ) == 0 or base_commit [0 ].hexsha == hexsha : # type: ignore
636+ if len (base_commit ) == 0 or base_commit [0 ].hexsha == hexsha :
656637 if force :
657638 msg = "Will force checkout or reset on local branch that is possibly in the future of"
658639 msg += "the commit it will be checked out to, effectively 'forgetting' new commits"
@@ -819,8 +800,7 @@ def move(self, module_path, configuration=True, module=True):
819800 return self
820801
821802 @unbare_repo
822- def remove (self , module : bool = True , force : bool = False ,
823- configuration : bool = True , dry_run : bool = False ) -> 'Submodule' :
803+ def remove (self , module = True , force = False , configuration = True , dry_run = False ):
824804 """Remove this submodule from the repository. This will remove our entry
825805 from the .gitmodules file and the entry in the .git / config file.
826806
@@ -874,7 +854,7 @@ def remove(self, module: bool = True, force: bool = False,
874854 # TODO: If we run into permission problems, we have a highly inconsistent
875855 # state. Delete the .git folders last, start with the submodules first
876856 mp = self .abspath
877- method : Union [ None , Callable [[ PathLike ], None ]] = None
857+ method = None
878858 if osp .islink (mp ):
879859 method = os .remove
880860 elif osp .isdir (mp ):
@@ -927,7 +907,7 @@ def remove(self, module: bool = True, force: bool = False,
927907 import gc
928908 gc .collect ()
929909 try :
930- rmtree (str ( wtd ) )
910+ rmtree (wtd )
931911 except Exception as ex :
932912 if HIDE_WINDOWS_KNOWN_ERRORS :
933913 raise SkipTest ("FIXME: fails with: PermissionError\n {}" .format (ex )) from ex
@@ -941,7 +921,7 @@ def remove(self, module: bool = True, force: bool = False,
941921 rmtree (git_dir )
942922 except Exception as ex :
943923 if HIDE_WINDOWS_KNOWN_ERRORS :
944- raise SkipTest (f "FIXME: fails with: PermissionError\n { ex } " ) from ex
924+ raise SkipTest ("FIXME: fails with: PermissionError\n %s" , ex ) from ex
945925 else :
946926 raise
947927 # end handle separate bare repository
@@ -965,8 +945,6 @@ def remove(self, module: bool = True, force: bool = False,
965945
966946 # now git config - need the config intact, otherwise we can't query
967947 # information anymore
968- writer : Union [GitConfigParser , SectionConstraint ]
969-
970948 with self .repo .config_writer () as writer :
971949 writer .remove_section (sm_section (self .name ))
972950
@@ -976,7 +954,7 @@ def remove(self, module: bool = True, force: bool = False,
976954
977955 return self
978956
979- def set_parent_commit (self , commit : Union [Commit_ish , None ], check : bool = True ) -> 'Submodule' :
957+ def set_parent_commit (self , commit : Union [Commit_ish , None ], check = True ):
980958 """Set this instance to use the given commit whose tree is supposed to
981959 contain the .gitmodules blob.
982960
@@ -1015,7 +993,7 @@ def set_parent_commit(self, commit: Union[Commit_ish, None], check: bool = True)
1015993 # If check is False, we might see a parent-commit that doesn't even contain the submodule anymore.
1016994 # in that case, mark our sha as being NULL
1017995 try :
1018- self .binsha = pctree [str ( self .path ) ].binsha
996+ self .binsha = pctree [self .path ].binsha # type: ignore
1019997 except KeyError :
1020998 self .binsha = self .NULL_BIN_SHA
1021999 # end
@@ -1024,7 +1002,7 @@ def set_parent_commit(self, commit: Union[Commit_ish, None], check: bool = True)
10241002 return self
10251003
10261004 @unbare_repo
1027- def config_writer (self , index : Union [ 'IndexFile' , None ] = None , write : bool = True ) -> SectionConstraint :
1005+ def config_writer (self , index = None , write = True ):
10281006 """:return: a config writer instance allowing you to read and write the data
10291007 belonging to this submodule into the .gitmodules file.
10301008
@@ -1045,7 +1023,7 @@ def config_writer(self, index: Union['IndexFile', None] = None, write: bool = Tr
10451023 return writer
10461024
10471025 @unbare_repo
1048- def rename (self , new_name : str ) -> 'Submodule' :
1026+ def rename (self , new_name ) :
10491027 """Rename this submodule
10501028 :note: This method takes care of renaming the submodule in various places, such as
10511029
@@ -1080,14 +1058,13 @@ def rename(self, new_name: str) -> 'Submodule':
10801058 destination_module_abspath = self ._module_abspath (self .repo , self .path , new_name )
10811059 source_dir = mod .git_dir
10821060 # Let's be sure the submodule name is not so obviously tied to a directory
1083- if str ( destination_module_abspath ) .startswith (str ( mod .git_dir ) ):
1061+ if destination_module_abspath .startswith (mod .git_dir ):
10841062 tmp_dir = self ._module_abspath (self .repo , self .path , str (uuid .uuid4 ()))
10851063 os .renames (source_dir , tmp_dir )
10861064 source_dir = tmp_dir
10871065 # end handle self-containment
10881066 os .renames (source_dir , destination_module_abspath )
1089- if mod .working_tree_dir :
1090- self ._write_git_file_and_module_config (mod .working_tree_dir , destination_module_abspath )
1067+ self ._write_git_file_and_module_config (mod .working_tree_dir , destination_module_abspath )
10911068 # end move separate git repository
10921069
10931070 return self
@@ -1097,7 +1074,7 @@ def rename(self, new_name: str) -> 'Submodule':
10971074 #{ Query Interface
10981075
10991076 @unbare_repo
1100- def module (self ) -> 'Repo' :
1077+ def module (self ):
11011078 """:return: Repo instance initialized from the repository at our submodule path
11021079 :raise InvalidGitRepositoryError: if a repository was not available. This could
11031080 also mean that it was not yet initialized"""
@@ -1114,7 +1091,7 @@ def module(self) -> 'Repo':
11141091 raise InvalidGitRepositoryError ("Repository at %r was not yet checked out" % module_checkout_abspath )
11151092 # END handle exceptions
11161093
1117- def module_exists (self ) -> bool :
1094+ def module_exists (self ):
11181095 """:return: True if our module exists and is a valid git repository. See module() method"""
11191096 try :
11201097 self .module ()
@@ -1123,7 +1100,7 @@ def module_exists(self) -> bool:
11231100 return False
11241101 # END handle exception
11251102
1126- def exists (self ) -> bool :
1103+ def exists (self ):
11271104 """
11281105 :return: True if the submodule exists, False otherwise. Please note that
11291106 a submodule may exist ( in the .gitmodules file) even though its module
@@ -1164,34 +1141,34 @@ def branch(self):
11641141 return mkhead (self .module (), self ._branch_path )
11651142
11661143 @property
1167- def branch_path (self ) -> PathLike :
1144+ def branch_path (self ):
11681145 """
11691146 :return: full(relative) path as string to the branch we would checkout
11701147 from the remote and track"""
11711148 return self ._branch_path
11721149
11731150 @property
1174- def branch_name (self ) -> str :
1151+ def branch_name (self ):
11751152 """:return: the name of the branch, which is the shortest possible branch name"""
11761153 # use an instance method, for this we create a temporary Head instance
11771154 # which uses a repository that is available at least ( it makes no difference )
11781155 return git .Head (self .repo , self ._branch_path ).name
11791156
11801157 @property
1181- def url (self ) -> str :
1158+ def url (self ):
11821159 """:return: The url to the repository which our module - repository refers to"""
11831160 return self ._url
11841161
11851162 @property
1186- def parent_commit (self ) -> 'Commit_ish' :
1163+ def parent_commit (self ):
11871164 """:return: Commit instance with the tree containing the .gitmodules file
11881165 :note: will always point to the current head's commit if it was not set explicitly"""
11891166 if self ._parent_commit is None :
11901167 return self .repo .commit ()
11911168 return self ._parent_commit
11921169
11931170 @property
1194- def name (self ) -> str :
1171+ def name (self ):
11951172 """:return: The name of this submodule. It is used to identify it within the
11961173 .gitmodules file.
11971174 :note: by default, the name is the path at which to find the submodule, but
0 commit comments