Skip to content

Commit 660c889

Browse files
peffgitster
authored andcommitted
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 <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 4a1e693 commit 660c889

File tree

2 files changed

+73
-0
lines changed

2 files changed

+73
-0
lines changed

cache.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1272,6 +1272,17 @@ int for_each_loose_file_in_objdir(const char *path,
12721272
each_loose_subdir_fn subdir_cb,
12731273
void *data);
12741274

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+
12751286
struct object_info {
12761287
/* Request */
12771288
enum object_type *typep;

sha1_file.c

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3348,3 +3348,65 @@ int for_each_loose_file_in_objdir(const char *path,
33483348
strbuf_release(&buf);
33493349
return r;
33503350
}
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+
}

0 commit comments

Comments
 (0)