@@ -1045,10 +1045,13 @@ static VALUE rb_git_repo_read_header(VALUE self, VALUE hex)
1045
1045
/**
1046
1046
* call-seq:
1047
1047
* repo.expand_oids([oid..], object_type = :any) -> hash
1048
+ * repo.expand_oids([oid..], object_type = [type..]) -> hash
1048
1049
*
1049
1050
* Expand a list of short oids to their full value, assuming they exist
1050
- * in the repository. If `object_type` is passed, OIDs are expected to be
1051
- * of the given type.
1051
+ * in the repository. If `object_type` is passed and is an array, it must
1052
+ * be the same length as the OIDs array. If it's a single type name, all
1053
+ * OIDs will be expected to resolve to that object type. OIDs that don't
1054
+ * match the expected object types will not be expanded.
1052
1055
*
1053
1056
* Returns a hash of `{ short_oid => full_oid }` for the short OIDs which
1054
1057
* exist in the repository and match the expected object type. Missing OIDs
@@ -1058,59 +1061,64 @@ static VALUE rb_git_repo_expand_oids(int argc, VALUE *argv, VALUE self)
1058
1061
{
1059
1062
VALUE rb_result , rb_oids , rb_expected_type ;
1060
1063
1061
- git_otype expected_type = GIT_OBJ_ANY ;
1062
-
1063
1064
git_repository * repo ;
1064
- git_oid oid ;
1065
1065
git_odb * odb ;
1066
- int i , error ;
1066
+ git_odb_expand_id * expand ;
1067
+ long i , expand_count ;
1068
+ int error ;
1067
1069
1068
1070
Data_Get_Struct (self , git_repository , repo );
1069
-
1070
1071
rb_scan_args (argc , argv , "11" , & rb_oids , & rb_expected_type );
1071
1072
1072
1073
Check_Type (rb_oids , T_ARRAY );
1073
- expected_type = rugged_otype_get (rb_expected_type );
1074
+ expand_count = RARRAY_LEN (rb_oids );
1075
+ expand = alloca (expand_count * sizeof (git_odb_expand_id ));
1074
1076
1075
- error = git_repository_odb (& odb , repo );
1076
- rugged_exception_check (error );
1077
+ for (i = 0 ; i < expand_count ; ++ i ) {
1078
+ VALUE rb_hex = rb_ary_entry (rb_oids , i );
1079
+ Check_Type (rb_hex , T_STRING );
1077
1080
1078
- rb_result = rb_hash_new ();
1081
+ rugged_exception_check (
1082
+ git_oid_fromstrn (& expand [i ].id , RSTRING_PTR (rb_hex ), RSTRING_LEN (rb_hex ))
1083
+ );
1084
+ expand [i ].length = RSTRING_LEN (rb_hex );
1085
+ }
1079
1086
1080
- for (i = 0 ; i < RARRAY_LEN (rb_oids ); ++ i ) {
1081
- VALUE hex_oid = rb_ary_entry (rb_oids , i );
1082
- git_oid found_oid ;
1087
+ if (TYPE (rb_expected_type ) == T_ARRAY ) {
1088
+ if (RARRAY_LEN (rb_expected_type ) != expand_count )
1089
+ rb_raise (rb_eRuntimeError ,
1090
+ "the `object_type` array must be the same length as the `oids` array" );
1083
1091
1084
- if ( TYPE ( hex_oid ) != T_STRING ) {
1085
- git_odb_free ( odb );
1086
- rb_raise ( rb_eTypeError , "Expected a SHA1 OID" );
1092
+ for ( i = 0 ; i < expand_count ; ++ i ) {
1093
+ VALUE rb_type = rb_ary_entry ( rb_expected_type , i );
1094
+ expand [ i ]. type = rugged_otype_get ( rb_type );
1087
1095
}
1096
+ } else {
1097
+ git_otype expected_type = GIT_OBJ_ANY ;
1088
1098
1089
- error = git_oid_fromstrn (& oid , RSTRING_PTR (hex_oid ), RSTRING_LEN (hex_oid ));
1090
- if (error < 0 ) {
1091
- git_odb_free (odb );
1092
- rugged_exception_check (error );
1093
- }
1099
+ if (!NIL_P (rb_expected_type ))
1100
+ expected_type = rugged_otype_get (rb_expected_type );
1094
1101
1095
- error = git_odb_exists_prefix (& found_oid , odb , & oid , RSTRING_LEN (hex_oid ));
1102
+ for (i = 0 ; i < expand_count ; ++ i )
1103
+ expand [i ].type = expected_type ;
1104
+ }
1096
1105
1097
- if (!error ) {
1098
- if (expected_type != GIT_OBJ_ANY ) {
1099
- size_t found_size ;
1100
- git_otype found_type ;
1106
+ error = git_repository_odb (& odb , repo );
1107
+ rugged_exception_check (error );
1101
1108
1102
- if (git_odb_read_header (& found_size , & found_type , odb , & found_oid ) < 0 )
1103
- continue ;
1109
+ error = git_odb_expand_ids (odb , expand , (size_t )expand_count );
1110
+ git_odb_free (odb );
1111
+ rugged_exception_check (error );
1104
1112
1105
- if (found_type != expected_type )
1106
- continue ;
1107
- }
1113
+ rb_result = rb_hash_new ();
1108
1114
1109
- rb_hash_aset (rb_result , hex_oid , rugged_create_oid (& found_oid ));
1115
+ for (i = 0 ; i < expand_count ; ++ i ) {
1116
+ if (expand [i ].length ) {
1117
+ rb_hash_aset (rb_result ,
1118
+ rb_ary_entry (rb_oids , i ), rugged_create_oid (& expand [i ].id ));
1110
1119
}
1111
1120
}
1112
1121
1113
- git_odb_free (odb );
1114
1122
return rb_result ;
1115
1123
}
1116
1124
0 commit comments