@@ -191,30 +191,27 @@ static int obj_is_recent(const struct object_id *oid, timestamp_t mtime,
191191 return oidset_contains (& data -> extra_recent_oids , oid );
192192}
193193
194- static void add_recent_object (const struct object_id * oid ,
195- struct packed_git * pack ,
196- off_t offset ,
197- timestamp_t mtime ,
198- struct recent_data * data )
194+ static int want_recent_object (struct recent_data * data ,
195+ const struct object_id * oid )
199196{
200- struct object * obj ;
201- enum object_type type ;
197+ if (data -> ignore_in_core_kept_packs &&
198+ has_object_kept_pack (data -> revs -> repo , oid , KEPT_PACK_IN_CORE ))
199+ return 0 ;
200+ return 1 ;
201+ }
202202
203- if (!obj_is_recent (oid , mtime , data ))
204- return ;
203+ static int add_recent_object (const struct object_id * oid ,
204+ struct object_info * oi ,
205+ void * cb_data )
206+ {
207+ struct recent_data * data = cb_data ;
208+ struct object * obj ;
205209
206- /*
207- * We do not want to call parse_object here, because
208- * inflating blobs and trees could be very expensive.
209- * However, we do need to know the correct type for
210- * later processing, and the revision machinery expects
211- * commits and tags to have been parsed.
212- */
213- type = odb_read_object_info (the_repository -> objects , oid , NULL );
214- if (type < 0 )
215- die ("unable to get object info for %s" , oid_to_hex (oid ));
210+ if (!want_recent_object (data , oid ) ||
211+ !obj_is_recent (oid , * oi -> mtimep , data ))
212+ return 0 ;
216213
217- switch (type ) {
214+ switch (* oi -> typep ) {
218215 case OBJ_TAG :
219216 case OBJ_COMMIT :
220217 obj = parse_object_or_die (the_repository , oid , NULL );
@@ -227,77 +224,22 @@ static void add_recent_object(const struct object_id *oid,
227224 break ;
228225 default :
229226 die ("unknown object type for %s: %s" ,
230- oid_to_hex (oid ), type_name (type ));
227+ oid_to_hex (oid ), type_name (* oi -> typep ));
231228 }
232229
233230 if (!obj )
234231 die ("unable to lookup %s" , oid_to_hex (oid ));
235-
236- add_pending_object (data -> revs , obj , "" );
237- if (data -> cb )
238- data -> cb (obj , pack , offset , mtime );
239- }
240-
241- static int want_recent_object (struct recent_data * data ,
242- const struct object_id * oid )
243- {
244- if (data -> ignore_in_core_kept_packs &&
245- has_object_kept_pack (data -> revs -> repo , oid , KEPT_PACK_IN_CORE ))
232+ if (obj -> flags & SEEN )
246233 return 0 ;
247- return 1 ;
248- }
249234
250- static int add_recent_loose (const struct object_id * oid ,
251- const char * path , void * data )
252- {
253- struct stat st ;
254- struct object * obj ;
255-
256- if (!want_recent_object (data , oid ))
257- return 0 ;
258-
259- obj = lookup_object (the_repository , oid );
260-
261- if (obj && obj -> flags & SEEN )
262- return 0 ;
263-
264- if (stat (path , & st ) < 0 ) {
265- /*
266- * It's OK if an object went away during our iteration; this
267- * could be due to a simultaneous repack. But anything else
268- * we should abort, since we might then fail to mark objects
269- * which should not be pruned.
270- */
271- if (errno == ENOENT )
272- return 0 ;
273- return error_errno ("unable to stat %s" , oid_to_hex (oid ));
235+ add_pending_object (data -> revs , obj , "" );
236+ if (data -> cb ) {
237+ if (oi -> whence == OI_PACKED )
238+ data -> cb (obj , oi -> u .packed .pack , oi -> u .packed .offset , * oi -> mtimep );
239+ else
240+ data -> cb (obj , NULL , 0 , * oi -> mtimep );
274241 }
275242
276- add_recent_object (oid , NULL , 0 , st .st_mtime , data );
277- return 0 ;
278- }
279-
280- static int add_recent_packed (const struct object_id * oid ,
281- struct packed_git * p ,
282- uint32_t pos ,
283- void * data )
284- {
285- struct object * obj ;
286- timestamp_t mtime = p -> mtime ;
287-
288- if (!want_recent_object (data , oid ))
289- return 0 ;
290-
291- obj = lookup_object (the_repository , oid );
292-
293- if (obj && obj -> flags & SEEN )
294- return 0 ;
295- if (p -> is_cruft ) {
296- if (load_pack_mtimes (p ) < 0 )
297- die (_ ("could not load cruft pack .mtimes" ));
298- mtime = nth_packed_mtime (p , pos );
299- }
300- add_recent_object (oid , p , nth_packed_object_offset (p , pos ), mtime , data );
301243 return 0 ;
302244}
303245
@@ -307,7 +249,13 @@ int add_unseen_recent_objects_to_traversal(struct rev_info *revs,
307249 int ignore_in_core_kept_packs )
308250{
309251 struct recent_data data ;
310- enum odb_for_each_object_flags flags ;
252+ unsigned flags ;
253+ enum object_type type ;
254+ time_t mtime ;
255+ struct object_info oi = {
256+ .mtimep = & mtime ,
257+ .typep = & type ,
258+ };
311259 int r ;
312260
313261 data .revs = revs ;
@@ -318,16 +266,13 @@ int add_unseen_recent_objects_to_traversal(struct rev_info *revs,
318266 oidset_init (& data .extra_recent_oids , 0 );
319267 data .extra_recent_oids_loaded = 0 ;
320268
321- r = for_each_loose_object (the_repository -> objects , add_recent_loose , & data ,
322- ODB_FOR_EACH_OBJECT_LOCAL_ONLY );
323- if (r )
324- goto done ;
325-
326269 flags = ODB_FOR_EACH_OBJECT_LOCAL_ONLY | ODB_FOR_EACH_OBJECT_PACK_ORDER ;
327270 if (ignore_in_core_kept_packs )
328271 flags |= ODB_FOR_EACH_OBJECT_SKIP_IN_CORE_KEPT_PACKS ;
329272
330- r = for_each_packed_object (revs -> repo , add_recent_packed , & data , flags );
273+ r = odb_for_each_object (revs -> repo -> objects , & oi , add_recent_object , & data , flags );
274+ if (r )
275+ goto done ;
331276
332277done :
333278 oidset_clear (& data .extra_recent_oids );
0 commit comments