@@ -250,7 +250,7 @@ def clone(
250250 url ,
251251 target = to_path ,
252252 errstream = (
253- DulwichProgressReporter (progress ) if progress else NoneStream ()
253+ DulwichProgressReporter (progress ) if progress else NoneStream () # type: ignore[arg-type]
254254 ),
255255 bare = bare ,
256256 )
@@ -278,8 +278,11 @@ def clone(
278278 def _set_default_tracking_branch (repo : "Repo" ):
279279 from dulwich .refs import LOCAL_BRANCH_PREFIX , parse_symref_value
280280
281+ head_ref = repo .refs .read_ref (b"HEAD" )
282+ if head_ref is None :
283+ return
281284 try :
282- ref = parse_symref_value (repo . refs . read_ref ( b"HEAD" ) )
285+ ref = parse_symref_value (head_ref )
283286 except ValueError :
284287 return
285288 if ref .startswith (LOCAL_BRANCH_PREFIX ):
@@ -307,7 +310,7 @@ def _set_mirror(
307310 fetch (
308311 repo ,
309312 remote_location = b"origin" ,
310- errstream = (DulwichProgressReporter (progress ) if progress else NoneStream ()),
313+ errstream = (DulwichProgressReporter (progress ) if progress else NoneStream ()), # type: ignore[arg-type]
311314 )
312315
313316 @staticmethod
@@ -599,11 +602,11 @@ def iter_remote_refs(self, url: str, base: Optional[str] = None, **kwargs):
599602 if base :
600603 yield from (
601604 os .fsdecode (ref )
602- for ref in client .get_refs (path )
605+ for ref in client .get_refs (path . encode () )
603606 if ref .startswith (os .fsencode (base ))
604607 )
605608 else :
606- yield from (os .fsdecode (ref ) for ref in client .get_refs (path ))
609+ yield from (os .fsdecode (ref ) for ref in client .get_refs (path . encode () ))
607610 except NotGitRepository as exc :
608611 raise InvalidRemote (url ) from exc
609612 except HTTPUnauthorized as exc :
@@ -634,7 +637,7 @@ def push_refspecs( # noqa: C901
634637 raise SCMError (f"'{ url } ' is not a valid Git remote or URL" ) from exc
635638
636639 change_result = {}
637- selected_refs = []
640+ selected_refs : list [ tuple [ Optional [ bytes ], Optional [ bytes ], bool ]] = []
638641
639642 def update_refs (refs ):
640643 from dulwich .objects import ZERO_SHA
@@ -649,6 +652,7 @@ def update_refs(refs):
649652 )
650653 new_refs = {}
651654 for lh , rh , _ in selected_refs :
655+ assert rh is not None
652656 refname = os .fsdecode (rh )
653657 if rh in refs and lh is not None :
654658 if refs [rh ] == self .repo .refs [lh ]:
@@ -679,9 +683,9 @@ def update_refs(refs):
679683
680684 try :
681685 result = client .send_pack (
682- path ,
686+ path . encode () ,
683687 update_refs ,
684- generate_pack_data = self .repo .generate_pack_data ,
688+ generate_pack_data = self .repo .generate_pack_data , # type: ignore[arg-type]
685689 progress = (DulwichProgressReporter (progress ) if progress else None ),
686690 )
687691 except (NotGitRepository , SendPackError ) as exc :
@@ -717,7 +721,7 @@ def fetch_refspecs(
717721 from dulwich .porcelain import DivergedBranches , check_diverged , get_remote_repo
718722 from dulwich .refs import DictRefsContainer
719723
720- fetch_refs = []
724+ fetch_refs : list [ tuple [ Optional [ bytes ], Optional [ bytes ], bool ]] = []
721725
722726 def determine_wants (
723727 remote_refs : dict [bytes , bytes ],
@@ -736,7 +740,7 @@ def determine_wants(
736740 return [
737741 remote_refs [lh ]
738742 for (lh , _ , _ ) in fetch_refs
739- if remote_refs [lh ] not in self .repo .object_store
743+ if lh is not None and remote_refs [lh ] not in self .repo .object_store
740744 ]
741745
742746 with reraise (Exception , SCMError (f"'{ url } ' is not a valid Git remote or URL" )):
@@ -749,41 +753,42 @@ def determine_wants(
749753 SCMError (f"Git failed to fetch ref from '{ url } '" ),
750754 ):
751755 fetch_result = client .fetch (
752- path ,
756+ path . encode () ,
753757 self .repo ,
754758 progress = DulwichProgressReporter (progress ) if progress else None ,
755- determine_wants = determine_wants ,
759+ determine_wants = determine_wants , # type: ignore[arg-type]
756760 )
757761
758762 result = {}
759763
760764 for lh , rh , _ in fetch_refs :
765+ assert rh is not None
761766 refname = os .fsdecode (rh )
767+ assert lh is not None
768+ fetch_ref_lh = fetch_result .refs [lh ]
769+ assert fetch_ref_lh is not None
762770 if rh in self .repo .refs :
763- if self .repo .refs [rh ] == fetch_result . refs [ lh ] :
771+ if self .repo .refs [rh ] == fetch_ref_lh :
764772 result [refname ] = SyncStatus .UP_TO_DATE
765773 continue
766774 try :
767775 check_diverged (
768776 self .repo ,
769777 self .repo .refs [rh ],
770- fetch_result . refs [ lh ] ,
778+ fetch_ref_lh ,
771779 )
772780 except DivergedBranches :
773781 if not force :
774782 overwrite = (
775- on_diverged (
776- os .fsdecode (rh ),
777- os .fsdecode (fetch_result .refs [lh ]),
778- )
783+ on_diverged (os .fsdecode (rh ), os .fsdecode (fetch_ref_lh ))
779784 if on_diverged
780785 else False
781786 )
782787 if not overwrite :
783788 result [refname ] = SyncStatus .DIVERGED
784789 continue
785790
786- self .repo .refs [rh ] = fetch_result . refs [ lh ]
791+ self .repo .refs [rh ] = fetch_ref_lh
787792 result [refname ] = SyncStatus .SUCCESS
788793 return result
789794
@@ -865,6 +870,7 @@ def _describe(
865870 return results
866871
867872 def diff (self , rev_a : str , rev_b : str , binary = False ) -> str :
873+ from dulwich .objects import Commit
868874 from dulwich .patch import write_tree_diff
869875
870876 try :
@@ -873,6 +879,9 @@ def diff(self, rev_a: str, rev_b: str, binary=False) -> str:
873879 except KeyError as exc :
874880 raise RevError ("Invalid revision" ) from exc
875881
882+ assert isinstance (commit_a , Commit )
883+ assert isinstance (commit_b , Commit )
884+
876885 buf = BytesIO ()
877886 write_tree_diff (buf , self .repo .object_store , commit_a .tree , commit_b .tree )
878887 return buf .getvalue ().decode ("utf-8" )
@@ -958,20 +967,22 @@ def get_tag(self, name: str) -> Optional[Union[str, "GitTag"]]:
958967 ref = self .repo .refs [name_b ]
959968 except KeyError :
960969 return None
961- if ref in self .repo and isinstance (self .repo [ref ], Tag ):
962- tag = self .repo [ref ]
963- _typ , target_sha = tag .object
964- tagger_name , tagger_email = _parse_identity (tag .tagger .decode ("utf-8" ))
965- return GitTag (
966- os .fsdecode (tag .name ),
967- tag .id ,
968- target_sha .decode ("ascii" ),
969- tagger_name ,
970- tagger_email ,
971- tag .tag_time ,
972- tag .tag_timezone ,
973- tag .message .decode ("utf-8" ),
974- )
970+ if ref in self .repo :
971+ shafile = self .repo [ref ]
972+ if isinstance (shafile , Tag ):
973+ tag = shafile
974+ _typ , target_sha = tag .object
975+ tagger_name , tagger_email = _parse_identity (tag .tagger .decode ("utf-8" ))
976+ return GitTag (
977+ os .fsdecode (tag .name ),
978+ tag .id .decode ("ascii" ),
979+ target_sha .decode ("ascii" ),
980+ tagger_name ,
981+ tagger_email ,
982+ tag .tag_time ,
983+ tag .tag_timezone ,
984+ tag .message .decode ("utf-8" ),
985+ )
975986 return os .fsdecode (ref )
976987
977988 def get_config (self , path : Optional [str ] = None ) -> "Config" :
@@ -1000,13 +1011,16 @@ def _parse_identity(identity: str) -> tuple[str, str]:
10001011 return m .group ("name" ), m .group ("email" )
10011012
10021013
1003- def ls_remote (url : str ) -> dict [str , str ]:
1014+ def ls_remote (url : str ) -> dict [str , Optional [ str ] ]:
10041015 from dulwich import porcelain
10051016 from dulwich .client import HTTPUnauthorized
10061017
10071018 try :
10081019 refs = porcelain .ls_remote (url ).refs
1009- return {os .fsdecode (ref ): sha .decode ("ascii" ) for ref , sha in refs .items ()}
1020+ return {
1021+ os .fsdecode (ref ): sha .decode ("ascii" ) if sha is not None else None
1022+ for ref , sha in refs .items ()
1023+ }
10101024 except HTTPUnauthorized as exc :
10111025 raise AuthError (url ) from exc
10121026 except Exception as exc :
0 commit comments