@@ -519,11 +519,11 @@ static int locate_object_short_oid(
519519 loose_locate_object_state state ;
520520 int error ;
521521
522- /* prealloc memory for OBJ_DIR/xx/ */
523- if (git_buf_grow (object_location , dir_len + 5 ) < 0 )
522+ /* prealloc memory for OBJ_DIR/xx/xx..38x..xx */
523+ if (git_buf_grow (object_location , dir_len + 3 + GIT_OID_HEXSZ ) < 0 )
524524 return -1 ;
525525
526- git_buf_sets (object_location , objects_dir );
526+ git_buf_set (object_location , objects_dir , dir_len );
527527 git_path_to_dir (object_location );
528528
529529 /* save adjusted position at end of dir so it can be restored later */
@@ -533,8 +533,9 @@ static int locate_object_short_oid(
533533 git_oid_fmt ((char * )state .short_oid , short_oid );
534534
535535 /* Explore OBJ_DIR/xx/ where xx is the beginning of hex formatted short oid */
536- if (git_buf_printf (object_location , "%.2s/" , state .short_oid ) < 0 )
536+ if (git_buf_put (object_location , ( char * ) state .short_oid , 3 ) < 0 )
537537 return -1 ;
538+ object_location -> ptr [object_location -> size - 1 ] = '/' ;
538539
539540 /* Check that directory exists */
540541 if (git_path_isdir (object_location -> ptr ) == false)
@@ -646,12 +647,9 @@ static int loose_backend__read_prefix(
646647{
647648 int error = 0 ;
648649
649- assert (len <= GIT_OID_HEXSZ );
650+ assert (len >= GIT_OID_MINPREFIXLEN && len <= GIT_OID_HEXSZ );
650651
651- if (len < GIT_OID_MINPREFIXLEN )
652- error = git_odb__error_ambiguous ("prefix length too short" );
653-
654- else if (len == GIT_OID_HEXSZ ) {
652+ if (len == GIT_OID_HEXSZ ) {
655653 /* We can fall back to regular read method */
656654 error = loose_backend__read (buffer_p , len_p , type_p , backend , short_oid );
657655 if (!error )
@@ -691,6 +689,22 @@ static int loose_backend__exists(git_odb_backend *backend, const git_oid *oid)
691689 return !error ;
692690}
693691
692+ static int loose_backend__exists_prefix (
693+ git_oid * out , git_odb_backend * backend , const git_oid * short_id , size_t len )
694+ {
695+ git_buf object_path = GIT_BUF_INIT ;
696+ int error ;
697+
698+ assert (backend && out && short_id && len >= GIT_OID_MINPREFIXLEN );
699+
700+ error = locate_object_short_oid (
701+ & object_path , out , (loose_backend * )backend , short_id , len );
702+
703+ git_buf_free (& object_path );
704+
705+ return error ;
706+ }
707+
694708struct foreach_state {
695709 size_t dir_len ;
696710 git_odb_foreach_cb cb ;
@@ -939,6 +953,7 @@ int git_odb_backend_loose(
939953 backend -> parent .read_header = & loose_backend__read_header ;
940954 backend -> parent .writestream = & loose_backend__stream ;
941955 backend -> parent .exists = & loose_backend__exists ;
956+ backend -> parent .exists_prefix = & loose_backend__exists_prefix ;
942957 backend -> parent .foreach = & loose_backend__foreach ;
943958 backend -> parent .free = & loose_backend__free ;
944959
0 commit comments