sha1_file: add for_each iterators for loose and packed objects
We typically iterate over the reachable objects in a repository by starting at the tips and walking the graph. There's no easy way to iterate over all of the objects, including unreachable ones. Let's provide a way of doing so. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Jeff King committed
Oct 15, 2014 at 18:41 UTC
660c889e46d185dc98ba78963528826728b0a55d
2 files changed
+73
cache.h
+11
@@ -1272,6 +1272,17 @@ int for_each_loose_file_in_objdir(const char *path,
1272
each_loose_subdir_fn subdir_cb,
1273
void *data);
1274
1275
+/*
1276
+ * Iterate over loose and packed objects in both the local
1277
+ * repository and any alternates repositories.
1278
+ */
1279
+typedef int each_packed_object_fn(const unsigned char *sha1,
1280
+ struct packed_git *pack,
1281
+ uint32_t pos,
1282
+ void *data);
1283
+extern int for_each_loose_object(each_loose_object_fn, void *);
1284
+extern int for_each_packed_object(each_packed_object_fn, void *);
1285
+
1286
struct object_info {
1287
/* Request */
1288
enum object_type *typep;
sha1_file.c
+62
@@ -3348,3 +3348,65 @@ int for_each_loose_file_in_objdir(const char *path,
3348
strbuf_release(&buf);
3349
return r;
3350
}
3351
+
3352
+struct loose_alt_odb_data {
3353
+ each_loose_object_fn *cb;
3354
+ void *data;
3355
+};
3356
+
3357
+static int loose_from_alt_odb(struct alternate_object_database *alt,
3358
+ void *vdata)
3359
+{
3360
+ struct loose_alt_odb_data *data = vdata;
3361
+ return for_each_loose_file_in_objdir(alt->base,
3362
+ data->cb, NULL, NULL,
3363
+ data->data);
3364
+}
3365
+
3366
+int for_each_loose_object(each_loose_object_fn cb, void *data)
3367
+{
3368
+ struct loose_alt_odb_data alt;
3369
+ int r;
3370
+
3371
+ r = for_each_loose_file_in_objdir(get_object_directory(),
3372
+ cb, NULL, NULL, data);
3373
+ if (r)
3374
+ return r;
3375
+
3376
+ alt.cb = cb;
3377
+ alt.data = data;
3378
+ return foreach_alt_odb(loose_from_alt_odb, &alt);
3379
+}
3380
+
3381
+static int for_each_object_in_pack(struct packed_git *p, each_packed_object_fn cb, void *data)
3382
+{
3383
+ uint32_t i;
3384
+ int r = 0;
3385
+
3386
+ for (i = 0; i < p->num_objects; i++) {
3387
+ const unsigned char *sha1 = nth_packed_object_sha1(p, i);
3388
+
3389
+ if (!sha1)
3390
+ return error("unable to get sha1 of object %u in %s",
3391
+ i, p->pack_name);
3392
+
3393
+ r = cb(sha1, p, i, data);
3394
+ if (r)
3395
+ break;
3396
+ }
3397
+ return r;
3398
+}
3399
+
3400
+int for_each_packed_object(each_packed_object_fn cb, void *data)
3401
+{
3402
+ struct packed_git *p;
3403
+ int r = 0;
3404
+
3405
+ prepare_packed_git();
3406
+ for (p = packed_git; p; p = p->next) {
3407
+ r = for_each_object_in_pack(p, cb, data);
3408
+ if (r)
3409
+ break;
3410
+ }
3411
+ return r;
3412
+}