@@ -834,23 +834,28 @@ def merge_trees(
834834
835835 def merge (
836836 self ,
837- id : typing .Union [Oid , str ],
837+ source : typing .Union [Reference , Commit , Oid , str ],
838838 favor = MergeFavor .NORMAL ,
839839 flags = MergeFlag .FIND_RENAMES ,
840840 file_flags = MergeFileFlag .DEFAULT ,
841841 ):
842842 """
843- Merges the given id into HEAD.
843+ Merges the given Reference or Commit into HEAD.
844844
845- Merges the given commit(s) into HEAD, writing the results into the working directory.
845+ Merges the given commit into HEAD, writing the results into the working directory.
846846 Any changes are staged for commit and any conflicts are written to the index.
847847 Callers should inspect the repository's index after this completes,
848848 resolve any conflicts and prepare a commit.
849849
850850 Parameters:
851851
852- id
853- The id to merge into HEAD
852+ source
853+ The Reference, Commit, or commit Oid to merge into HEAD.
854+ It is preferable to pass in a Reference, because this enriches the
855+ merge with additional information (for example, Repository.message will
856+ specify the name of the branch being merged).
857+ Previous versions of pygit2 allowed passing in a partial commit
858+ hash as a string; this is deprecated.
854859
855860 favor
856861 An enums.MergeFavor constant specifying how to deal with file-level conflicts.
@@ -862,12 +867,32 @@ def merge(
862867 file_flags
863868 A combination of enums.MergeFileFlag constants.
864869 """
865- if not isinstance (id , (str , Oid )):
866- raise TypeError (f'expected oid (string or <Oid>) got { type (id )} ' )
867870
868- id = self [id ].id
869- c_id = ffi .new ('git_oid *' )
870- ffi .buffer (c_id )[:] = id .raw [:]
871+ if isinstance (source , Reference ):
872+ # Annotated commit from ref
873+ cptr = ffi .new ('struct git_reference **' )
874+ ffi .buffer (cptr )[:] = source ._pointer [:]
875+ commit_ptr = ffi .new ('git_annotated_commit **' )
876+ err = C .git_annotated_commit_from_ref (commit_ptr , self ._repo , cptr [0 ])
877+ check_error (err )
878+ else :
879+ # Annotated commit from commit id
880+ if isinstance (source , str ):
881+ # For backwards compatibility, parse a string as a partial commit hash
882+ oid = self [source ].peel (Commit ).id
883+ elif isinstance (source , Commit ):
884+ oid = source .id
885+ elif isinstance (source , Oid ):
886+ oid = source
887+ else :
888+ raise TypeError (
889+ 'expected Reference, Commit, Oid, or commit hash string'
890+ )
891+ c_id = ffi .new ('git_oid *' )
892+ ffi .buffer (c_id )[:] = oid .raw [:]
893+ commit_ptr = ffi .new ('git_annotated_commit **' )
894+ err = C .git_annotated_commit_lookup (commit_ptr , self ._repo , c_id )
895+ check_error (err )
871896
872897 merge_opts = self ._merge_options (favor , flags , file_flags )
873898
@@ -877,10 +902,6 @@ def merge(
877902 CheckoutStrategy .SAFE | CheckoutStrategy .RECREATE_MISSING
878903 )
879904
880- commit_ptr = ffi .new ('git_annotated_commit **' )
881- err = C .git_annotated_commit_lookup (commit_ptr , self ._repo , c_id )
882- check_error (err )
883-
884905 err = C .git_merge (self ._repo , commit_ptr , 1 , merge_opts , checkout_opts )
885906 C .git_annotated_commit_free (commit_ptr [0 ])
886907 check_error (err )
0 commit comments