33#
44# This module is part of GitPython and is released under
55# the BSD License: http://www.opensource.org/licenses/bsd-license.php
6+ from git .refs .reference import Reference
67import glob
78from io import BytesIO
89import os
6566
6667# typing -----------------------------------------------------------------------------
6768
68- from typing import Any , Callable , Dict , IO , Iterator , List , Sequence , TYPE_CHECKING , Tuple , Union
69+ from typing import (Any , Callable , Dict , IO , Iterable , Iterator , List ,
70+ Sequence , TYPE_CHECKING , Tuple , Union )
6971
7072from git .types import PathLike , TBD
7173
7274if TYPE_CHECKING :
7375 from subprocess import Popen
7476 from git .repo import Repo
7577
78+
7679StageType = int
77- Treeish = Union [Tree , Commit , bytes ]
80+ Treeish = Union [Tree , Commit , str , bytes ]
7881
7982
8083__all__ = ('IndexFile' , 'CheckoutError' )
@@ -490,7 +493,7 @@ def unmerged_blobs(self) -> Dict[PathLike, List[Tuple[StageType, Blob]]]:
490493 return path_map
491494
492495 @classmethod
493- def entry_key (cls , * entry : Union [Tuple [ BaseIndexEntry ], Tuple [ PathLike , StageType ] ]) -> Tuple [PathLike , StageType ]:
496+ def entry_key (cls , * entry : Union [BaseIndexEntry , PathLike , StageType ]) -> Tuple [PathLike , StageType ]:
494497 return entry_key (* entry )
495498
496499 def resolve_blobs (self , iter_blobs : Iterator [Blob ]) -> 'IndexFile' :
@@ -513,7 +516,7 @@ def resolve_blobs(self, iter_blobs: Iterator[Blob]) -> 'IndexFile':
513516 if stage_null_key in self .entries :
514517 raise ValueError ("Path %r already exists at stage 0" % str (blob .path ))
515518 # END assert blob is not stage 0 already
516-
519+
517520 # delete all possible stages
518521 for stage in (1 , 2 , 3 ):
519522 try :
@@ -650,8 +653,9 @@ def _entries_for_paths(self, paths, path_rewriter, fprogress, entries):
650653 # END path handling
651654 return entries_added
652655
653- def add (self , items , force = True , fprogress = lambda * args : None , path_rewriter = None ,
654- write = True , write_extension_data = False ):
656+ def add (self , items : Sequence [Union [PathLike , Blob , BaseIndexEntry , Submodule ]], force : bool = True ,
657+ fprogress : Callable = lambda * args : None , path_rewriter : Callable = None ,
658+ write : bool = True , write_extension_data : bool = False ) -> List [BaseIndexEntry ]:
655659 """Add files from the working tree, specific blobs or BaseIndexEntries
656660 to the index.
657661
@@ -838,7 +842,8 @@ def _items_to_rela_paths(self, items):
838842
839843 @post_clear_cache
840844 @default_index
841- def remove (self , items , working_tree = False , ** kwargs ):
845+ def remove (self , items : Sequence [Union [PathLike , Blob , BaseIndexEntry , Submodule ]], working_tree : bool = False ,
846+ ** kwargs : Any ) -> List [str ]:
842847 """Remove the given items from the index and optionally from
843848 the working tree as well.
844849
@@ -889,7 +894,8 @@ def remove(self, items, working_tree=False, **kwargs):
889894
890895 @post_clear_cache
891896 @default_index
892- def move (self , items , skip_errors = False , ** kwargs ):
897+ def move (self , items : Sequence [Union [PathLike , Blob , BaseIndexEntry , Submodule ]], skip_errors : bool = False ,
898+ ** kwargs : Any ) -> List [Tuple [str , str ]]:
893899 """Rename/move the items, whereas the last item is considered the destination of
894900 the move operation. If the destination is a file, the first item ( of two )
895901 must be a file as well. If the destination is a directory, it may be preceded
@@ -951,9 +957,9 @@ def move(self, items, skip_errors=False, **kwargs):
951957
952958 return out
953959
954- def commit (self , message , parent_commits = None , head = True , author = None ,
955- committer = None , author_date = None , commit_date = None ,
956- skip_hooks = False ):
960+ def commit (self , message : str , parent_commits = None , head : bool = True , author : str = None ,
961+ committer : str = None , author_date : str = None , commit_date : str = None ,
962+ skip_hooks : bool = False ) -> Commit :
957963 """Commit the current default index file, creating a commit object.
958964 For more information on the arguments, see tree.commit.
959965
@@ -977,33 +983,39 @@ def commit(self, message, parent_commits=None, head=True, author=None,
977983 run_commit_hook ('post-commit' , self )
978984 return rval
979985
980- def _write_commit_editmsg (self , message ) :
986+ def _write_commit_editmsg (self , message : str ) -> None :
981987 with open (self ._commit_editmsg_filepath (), "wb" ) as commit_editmsg_file :
982988 commit_editmsg_file .write (message .encode (defenc ))
983989
984- def _remove_commit_editmsg (self ):
990+ def _remove_commit_editmsg (self ) -> None :
985991 os .remove (self ._commit_editmsg_filepath ())
986992
987- def _read_commit_editmsg (self ):
993+ def _read_commit_editmsg (self ) -> str :
988994 with open (self ._commit_editmsg_filepath (), "rb" ) as commit_editmsg_file :
989995 return commit_editmsg_file .read ().decode (defenc )
990996
991- def _commit_editmsg_filepath (self ):
997+ def _commit_editmsg_filepath (self ) -> str :
992998 return osp .join (self .repo .common_dir , "COMMIT_EDITMSG" )
993999
994- @classmethod
995- def _flush_stdin_and_wait (cls , proc , ignore_stdout = False ):
996- proc .stdin .flush ()
997- proc .stdin .close ()
998- stdout = ''
999- if not ignore_stdout :
1000+ def _flush_stdin_and_wait (cls , proc : 'Popen[bytes]' , ignore_stdout : bool = False ) -> bytes :
1001+ stdin_IO = proc .stdin
1002+ if stdin_IO :
1003+ stdin_IO .flush ()
1004+ stdin_IO .close ()
1005+
1006+ stdout = b''
1007+ if not ignore_stdout and proc .stdout :
10001008 stdout = proc .stdout .read ()
1001- proc .stdout .close ()
1002- proc .wait ()
1009+
1010+ if proc .stdout :
1011+ proc .stdout .close ()
1012+ proc .wait ()
10031013 return stdout
10041014
10051015 @default_index
1006- def checkout (self , paths = None , force = False , fprogress = lambda * args : None , ** kwargs ):
1016+ def checkout (self , paths : Union [None , Iterable [PathLike ]] = None , force : bool = False ,
1017+ fprogress : Callable = lambda * args : None , ** kwargs : Any
1018+ ) -> Union [None , Iterator [PathLike ], List [PathLike ]]:
10071019 """Checkout the given paths or all files from the version known to the index into
10081020 the working tree.
10091021
@@ -1054,12 +1066,15 @@ def checkout(self, paths=None, force=False, fprogress=lambda *args: None, **kwar
10541066 failed_reasons = []
10551067 unknown_lines = []
10561068
1057- def handle_stderr (proc , iter_checked_out_files ):
1058- stderr = proc .stderr .read ()
1059- if not stderr :
1060- return
1069+ def handle_stderr (proc : 'Popen[bytes]' , iter_checked_out_files : Iterable [PathLike ]) -> None :
1070+
1071+ stderr_IO = proc .stderr
1072+ if not stderr_IO :
1073+ return None # return early if stderr empty
1074+ else :
1075+ stderr_bytes = stderr_IO .read ()
10611076 # line contents:
1062- stderr = stderr .decode (defenc )
1077+ stderr = stderr_bytes .decode (defenc )
10631078 # git-checkout-index: this already exists
10641079 endings = (' already exists' , ' is not in the cache' , ' does not exist at stage' , ' is unmerged' )
10651080 for line in stderr .splitlines ():
@@ -1123,7 +1138,7 @@ def handle_stderr(proc, iter_checked_out_files):
11231138 proc = self .repo .git .checkout_index (args , ** kwargs )
11241139 # FIXME: Reading from GIL!
11251140 make_exc = lambda : GitCommandError (("git-checkout-index" ,) + tuple (args ), 128 , proc .stderr .read ())
1126- checked_out_files = []
1141+ checked_out_files = [] # type: List[PathLike]
11271142
11281143 for path in paths :
11291144 co_path = to_native_path_linux (self ._to_relative_path (path ))
@@ -1133,11 +1148,11 @@ def handle_stderr(proc, iter_checked_out_files):
11331148 try :
11341149 self .entries [(co_path , 0 )]
11351150 except KeyError :
1136- folder = co_path
1151+ folder = str ( co_path )
11371152 if not folder .endswith ('/' ):
11381153 folder += '/'
11391154 for entry in self .entries .values ():
1140- if entry .path .startswith (folder ):
1155+ if str ( entry .path ) .startswith (folder ):
11411156 p = entry .path
11421157 self ._write_path_to_stdin (proc , p , p , make_exc ,
11431158 fprogress , read_from_stdout = False )
@@ -1167,7 +1182,9 @@ def handle_stderr(proc, iter_checked_out_files):
11671182 assert "Should not reach this point"
11681183
11691184 @default_index
1170- def reset (self , commit = 'HEAD' , working_tree = False , paths = None , head = False , ** kwargs ):
1185+ def reset (self , commit : Union [Commit , Reference , str ] = 'HEAD' , working_tree : bool = False ,
1186+ paths : Union [None , Iterable [PathLike ]] = None ,
1187+ head : bool = False , ** kwargs : Any ) -> 'IndexFile' :
11711188 """Reset the index to reflect the tree at the given commit. This will not
11721189 adjust our HEAD reference as opposed to HEAD.reset by default.
11731190
@@ -1235,10 +1252,12 @@ def reset(self, commit='HEAD', working_tree=False, paths=None, head=False, **kwa
12351252 return self
12361253
12371254 @default_index
1238- def diff (self , other = diff .Diffable .Index , paths = None , create_patch = False , ** kwargs ):
1255+ def diff (self , other : Union [diff .Diffable .Index , 'IndexFile.Index' , Treeish , None , object ] = diff .Diffable .Index ,
1256+ paths : Union [str , List [PathLike ], Tuple [PathLike , ...]] = None , create_patch : bool = False , ** kwargs : Any
1257+ ) -> diff .DiffIndex :
12391258 """Diff this index against the working copy or a Tree or Commit object
12401259
1241- For a documentation of the parameters and return values, see
1260+ For a documentation of the parameters and return values, see,
12421261 Diffable.diff
12431262
12441263 :note:
@@ -1256,7 +1275,7 @@ def diff(self, other=diff.Diffable.Index, paths=None, create_patch=False, **kwar
12561275 other = self .repo .rev_parse (other )
12571276 # END object conversion
12581277
1259- if isinstance (other , Object ):
1278+ if isinstance (other , Object ): # for Tree or Commit
12601279 # invert the existing R flag
12611280 cur_val = kwargs .get ('R' , False )
12621281 kwargs ['R' ] = not cur_val
0 commit comments