2929from time import time
3030import tarfile
3131import typing
32+ from typing import Optional
3233
3334# Import from pygit2
3435from ._pygit2 import Repository as _Repository , init_file_backend
35- from ._pygit2 import Oid , GIT_OID_HEXSZ , GIT_OID_MINPREFIXLEN
36+ from ._pygit2 import Oid , GIT_OID_HEXSZ , GIT_OID_MINPREFIXLEN , Object
3637from ._pygit2 import Reference , Tree , Commit , Blob , Signature
3738from ._pygit2 import InvalidSpecError
3839
@@ -187,20 +188,20 @@ def __iter__(self):
187188 #
188189 # Mapping interface
189190 #
190- def get (self , key , default = None ):
191+ def get (self , key : str , default : Optional [ Commit ] = None ) -> Object :
191192 value = self .git_object_lookup_prefix (key )
192193 return value if (value is not None ) else default
193194
194- def __getitem__ (self , key ) :
195+ def __getitem__ (self , key : str | Oid ) -> Object :
195196 value = self .git_object_lookup_prefix (key )
196197 if value is None :
197198 raise KeyError (key )
198199 return value
199200
200- def __contains__ (self , key ) :
201+ def __contains__ (self , key : str | Oid ) -> bool :
201202 return self .git_object_lookup_prefix (key ) is not None
202203
203- def __repr__ (self ):
204+ def __repr__ (self ) -> str :
204205 return f'pygit2.Repository({ repr (self .path )} )'
205206
206207 #
@@ -529,22 +530,22 @@ def diff(
529530
530531 # Case 1: Diff tree to tree
531532 if isinstance (a , Tree ) and isinstance (b , Tree ):
532- return a .diff_to_tree (b , ** options )
533+ return a .diff_to_tree (b , ** options ) # type: ignore[arg-type]
533534
534535 # Case 2: Index to workdir
535536 elif a is None and b is None :
536- return self .index .diff_to_workdir (** options )
537+ return self .index .diff_to_workdir (** options ) # type: ignore[arg-type]
537538
538539 # Case 3: Diff tree to index or workdir
539540 elif isinstance (a , Tree ) and b is None :
540541 if cached :
541- return a .diff_to_index (self .index , ** options )
542+ return a .diff_to_index (self .index , ** options ) # type: ignore[arg-type]
542543 else :
543- return a .diff_to_workdir (** options )
544+ return a .diff_to_workdir (** options ) # type: ignore[arg-type]
544545
545546 # Case 4: Diff blob to blob
546547 if isinstance (a , Blob ) and isinstance (b , Blob ):
547- return a .diff (b , ** options )
548+ return a .diff (b , ** options ) # type: ignore[arg-type]
548549
549550 raise ValueError ('Only blobs and treeish can be diffed' )
550551
@@ -559,7 +560,7 @@ def state(self) -> RepositoryState:
559560 return RepositoryState (cstate )
560561 except ValueError :
561562 # Some value not in the IntEnum - newer libgit2 version?
562- return cstate
563+ return cstate # type: ignore[return-value]
563564
564565 def state_cleanup (self ):
565566 """Remove all the metadata associated with an ongoing command like
@@ -770,9 +771,15 @@ def merge_commits(
770771 cindex = ffi .new ('git_index **' )
771772
772773 if isinstance (ours , (str , Oid )):
773- ours = self [ours ]
774+ ours_object = self [ours ]
775+ if not isinstance (ours_object , Commit ):
776+ raise TypeError (f'expected Commit, got { type (ours_object )} ' )
777+ ours = ours_object
774778 if isinstance (theirs , (str , Oid )):
775- theirs = self [theirs ]
779+ theirs_object = self [theirs ]
780+ if not isinstance (theirs_object , Commit ):
781+ raise TypeError (f'expected Commit, got { type (theirs_object )} ' )
782+ theirs = theirs_object
776783
777784 ours = ours .peel (Commit )
778785 theirs = theirs .peel (Commit )
@@ -827,16 +834,9 @@ def merge_trees(
827834 theirs_ptr = ffi .new ('git_tree **' )
828835 cindex = ffi .new ('git_index **' )
829836
830- if isinstance (ancestor , (str , Oid )):
831- ancestor = self [ancestor ]
832- if isinstance (ours , (str , Oid )):
833- ours = self [ours ]
834- if isinstance (theirs , (str , Oid )):
835- theirs = self [theirs ]
836-
837- ancestor = ancestor .peel (Tree )
838- ours = ours .peel (Tree )
839- theirs = theirs .peel (Tree )
837+ ancestor = self .__ensure_tree (ancestor )
838+ ours = self .__ensure_tree (ours )
839+ theirs = self .__ensure_tree (theirs )
840840
841841 opts = self ._merge_options (favor , flags , file_flags )
842842
@@ -890,7 +890,7 @@ def merge(
890890 if isinstance (source , Reference ):
891891 # Annotated commit from ref
892892 cptr = ffi .new ('struct git_reference **' )
893- ffi .buffer (cptr )[:] = source ._pointer [:]
893+ ffi .buffer (cptr )[:] = source ._pointer [:] # type: ignore[attr-defined]
894894 commit_ptr = ffi .new ('git_annotated_commit **' )
895895 err = C .git_annotated_commit_from_ref (commit_ptr , self ._repo , cptr [0 ])
896896 check_error (err )
@@ -1615,6 +1615,11 @@ def amend_commit(
16151615
16161616 return Oid (raw = bytes (ffi .buffer (coid )[:]))
16171617
1618+ def __ensure_tree (self , maybe_tree : str | Oid | Tree ) -> Tree :
1619+ if isinstance (maybe_tree , Tree ):
1620+ return maybe_tree
1621+ return self [maybe_tree ].peel (Tree )
1622+
16181623
16191624class Repository (BaseRepository ):
16201625 def __init__ (
0 commit comments