@@ -84,8 +84,10 @@ void git_repository_free(git_repository *repo)
8484
8585 while ((object = (git_repository_object * )
8686 git_hashtable_iterator_next (& it )) != NULL ) {
87+
88+ git_obj_close (& object -> dbo );
8789
88- switch (object -> type ) {
90+ switch (object -> dbo . type ) {
8991 case GIT_OBJ_COMMIT :
9092 git_commit__free ((git_commit * )object );
9193 break ;
@@ -109,8 +111,39 @@ void git_repository_free(git_repository *repo)
109111 free (repo );
110112}
111113
114+ int git_repository__open_dbo (git_repository_object * object )
115+ {
116+ int error ;
117+
118+ if (object -> dbo_open )
119+ return GIT_SUCCESS ;
120+
121+ error = git_odb_read (& object -> dbo , object -> repo -> db , & object -> id );
122+ if (error < 0 )
123+ return error ;
124+
125+ object -> dbo_open = 1 ;
126+ return GIT_SUCCESS ;
127+ }
128+
129+ void git_repository__close_dbo (git_repository_object * object )
130+ {
131+ if (!object -> dbo_open ) {
132+ git_obj_close (& object -> dbo );
133+ object -> dbo_open = 0 ;
134+ }
135+ }
136+
112137git_repository_object * git_repository_lookup (git_repository * repo , const git_oid * id , git_otype type )
113138{
139+ static const size_t object_sizes [] = {
140+ 0 ,
141+ sizeof (git_commit ),
142+ sizeof (git_tree ),
143+ sizeof (git_repository_object ), /* TODO: sizeof(git_blob) */
144+ sizeof (git_tag )
145+ };
146+
114147 git_repository_object * object = NULL ;
115148 git_obj obj_file ;
116149
@@ -120,24 +153,61 @@ git_repository_object *git_repository_lookup(git_repository *repo, const git_oid
120153 if (object != NULL )
121154 return object ;
122155
123- if (git_odb_read (& obj_file , repo -> db , id ) < 0 ||
124- (type != GIT_OBJ_ANY && type != obj_file .type ))
156+ if (git_odb_read (& obj_file , repo -> db , id ) < 0 )
125157 return NULL ;
126158
127- object = git__malloc (sizeof (git_commit ));
159+ if (type != GIT_OBJ_ANY && type != obj_file .type )
160+ return NULL ;
161+
162+ type = obj_file .type ;
163+
164+ object = git__malloc (object_sizes [type ]);
128165
129166 if (object == NULL )
130167 return NULL ;
131168
132- memset (object , 0x0 , sizeof ( git_commit ) );
169+ memset (object , 0x0 , object_sizes [ type ] );
133170
134171 /* Initialize parent object */
135172 git_oid_cpy (& object -> id , id );
136173 object -> repo = repo ;
137- object -> type = obj_file .type ;
174+ object -> dbo_open = 1 ;
175+ memcpy (& object -> dbo , & obj_file , sizeof (git_obj ));
138176
139- git_hashtable_insert (repo -> objects , & object -> id , object );
140- git_obj_close (& obj_file );
177+ switch (type ) {
141178
179+ case GIT_OBJ_COMMIT :
180+ if (git_commit__parse_basic ((git_commit * )object ) < 0 ) {
181+ free (object );
182+ return NULL ;
183+ }
184+
185+ break ;
186+
187+ case GIT_OBJ_TREE :
188+ if (git_tree__parse ((git_tree * )object ) < 0 ) {
189+ free (object );
190+ return NULL ;
191+ }
192+
193+ break ;
194+
195+ case GIT_OBJ_TAG :
196+ if (git_tag__parse ((git_tag * )object ) < 0 ) {
197+ free (object );
198+ return NULL ;
199+ }
200+
201+ break ;
202+
203+ default :
204+ /* blobs get no parsing */
205+ break ;
206+ }
207+
208+ git_obj_close (& object -> dbo );
209+ object -> dbo_open = 0 ;
210+
211+ git_hashtable_insert (repo -> objects , & object -> id , object );
142212 return object ;
143213}
0 commit comments