@@ -33,7 +33,9 @@ typedef struct loose_backend {
33
33
34
34
int object_zlib_level ; /** loose object zlib compression level. */
35
35
int fsync_object_files ; /** loose object file fsync flag. */
36
- char * objects_dir ;
36
+
37
+ size_t objects_dirlen ;
38
+ char objects_dir [GIT_FLEX_ARRAY ];
37
39
} loose_backend ;
38
40
39
41
/* State structure for exploring directories,
@@ -56,24 +58,30 @@ typedef struct {
56
58
*
57
59
***********************************************************/
58
60
59
- static int object_file_name (git_buf * name , const char * dir , const git_oid * id )
61
+ static int object_file_name (
62
+ git_buf * name , const loose_backend * be , const git_oid * id )
60
63
{
61
- git_buf_sets (name , dir );
62
-
63
- /* expand length for 40 hex sha1 chars + 2 * '/' + '\0' */
64
- if (git_buf_grow (name , git_buf_len (name ) + GIT_OID_HEXSZ + 3 ) < 0 )
64
+ /* expand length for object root + 40 hex sha1 chars + 2 * '/' + '\0' */
65
+ if (git_buf_grow (name , be -> objects_dirlen + GIT_OID_HEXSZ + 3 ) < 0 )
65
66
return -1 ;
66
67
68
+ git_buf_set (name , be -> objects_dir , be -> objects_dirlen );
67
69
git_path_to_dir (name );
68
70
69
71
/* loose object filename: aa/aaa... (41 bytes) */
70
- git_oid_pathfmt (name -> ptr + git_buf_len ( name ) , id );
72
+ git_oid_pathfmt (name -> ptr + name -> size , id );
71
73
name -> size += GIT_OID_HEXSZ + 1 ;
72
74
name -> ptr [name -> size ] = '\0' ;
73
75
74
76
return 0 ;
75
77
}
76
78
79
+ static int object_mkdir (const git_buf * name , const loose_backend * be )
80
+ {
81
+ return git_futils_mkdir (
82
+ name -> ptr + be -> objects_dirlen , be -> objects_dir , GIT_OBJECT_DIR_MODE ,
83
+ GIT_MKDIR_PATH | GIT_MKDIR_SKIP_LAST | GIT_MKDIR_VERIFY_DIR );
84
+ }
77
85
78
86
static size_t get_binary_object_header (obj_hdr * hdr , git_buf * obj )
79
87
{
@@ -457,7 +465,7 @@ static int locate_object(
457
465
loose_backend * backend ,
458
466
const git_oid * oid )
459
467
{
460
- int error = object_file_name (object_location , backend -> objects_dir , oid );
468
+ int error = object_file_name (object_location , backend , oid );
461
469
462
470
if (!error && !git_path_exists (object_location -> ptr ))
463
471
return GIT_ENOTFOUND ;
@@ -769,8 +777,8 @@ static int loose_backend__stream_fwrite(git_oid *oid, git_odb_stream *_stream)
769
777
int error = 0 ;
770
778
771
779
if (git_filebuf_hash (oid , & stream -> fbuf ) < 0 ||
772
- object_file_name (& final_path , backend -> objects_dir , oid ) < 0 ||
773
- git_futils_mkpath2file ( final_path . ptr , GIT_OBJECT_DIR_MODE ) < 0 )
780
+ object_file_name (& final_path , backend , oid ) < 0 ||
781
+ object_mkdir ( & final_path , backend ) < 0 )
774
782
error = -1 ;
775
783
/*
776
784
* Don't try to add an existing object to the repository. This
@@ -880,8 +888,8 @@ static int loose_backend__write(git_oid *oid, git_odb_backend *_backend, const v
880
888
git_filebuf_write (& fbuf , header , header_len );
881
889
git_filebuf_write (& fbuf , data , len );
882
890
883
- if (object_file_name (& final_path , backend -> objects_dir , oid ) < 0 ||
884
- git_futils_mkpath2file ( final_path . ptr , GIT_OBJECT_DIR_MODE ) < 0 ||
891
+ if (object_file_name (& final_path , backend , oid ) < 0 ||
892
+ object_mkdir ( & final_path , backend ) < 0 ||
885
893
git_filebuf_commit_at (& fbuf , final_path .ptr , GIT_OBJECT_FILE_MODE ) < 0 )
886
894
error = -1 ;
887
895
@@ -898,7 +906,6 @@ static void loose_backend__free(git_odb_backend *_backend)
898
906
assert (_backend );
899
907
backend = (loose_backend * )_backend ;
900
908
901
- git__free (backend -> objects_dir );
902
909
git__free (backend );
903
910
}
904
911
@@ -909,13 +916,20 @@ int git_odb_backend_loose(
909
916
int do_fsync )
910
917
{
911
918
loose_backend * backend ;
919
+ size_t objects_dirlen ;
920
+
921
+ assert (backend_out && objects_dir );
922
+
923
+ objects_dirlen = strlen (objects_dir );
912
924
913
- backend = git__calloc (1 , sizeof (loose_backend ));
925
+ backend = git__calloc (1 , sizeof (loose_backend ) + objects_dirlen + 2 );
914
926
GITERR_CHECK_ALLOC (backend );
915
927
916
928
backend -> parent .version = GIT_ODB_BACKEND_VERSION ;
917
- backend -> objects_dir = git__strdup (objects_dir );
918
- GITERR_CHECK_ALLOC (backend -> objects_dir );
929
+ backend -> objects_dirlen = objects_dirlen ;
930
+ memcpy (backend -> objects_dir , objects_dir , objects_dirlen );
931
+ if (backend -> objects_dir [backend -> objects_dirlen - 1 ] != '/' )
932
+ backend -> objects_dir [backend -> objects_dirlen ++ ] = '/' ;
919
933
920
934
if (compression_level < 0 )
921
935
compression_level = Z_BEST_SPEED ;
0 commit comments