diff options
author | Jeff King <peff@peff.net> | 2014-10-15 18:41:21 -0400 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2014-10-16 10:10:41 -0700 |
commit | 660c889e46d185dc98ba78963528826728b0a55d (patch) | |
tree | f70f42402438859d21623c290330cca9bc54a979 | |
parent | 4a1e693a30c816fa5293c5f9e83e1e98ee87584e (diff) | |
download | git-660c889e46d185dc98ba78963528826728b0a55d.tar.gz |
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>
-rw-r--r-- | cache.h | 11 | ||||
-rw-r--r-- | sha1_file.c | 62 |
2 files changed, 73 insertions, 0 deletions
@@ -1272,6 +1272,17 @@ int for_each_loose_file_in_objdir(const char *path, each_loose_subdir_fn subdir_cb, void *data); +/* + * Iterate over loose and packed objects in both the local + * repository and any alternates repositories. + */ +typedef int each_packed_object_fn(const unsigned char *sha1, + struct packed_git *pack, + uint32_t pos, + void *data); +extern int for_each_loose_object(each_loose_object_fn, void *); +extern int for_each_packed_object(each_packed_object_fn, void *); + struct object_info { /* Request */ enum object_type *typep; diff --git a/sha1_file.c b/sha1_file.c index fa08475c91..55c65b7ef6 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -3348,3 +3348,65 @@ int for_each_loose_file_in_objdir(const char *path, strbuf_release(&buf); return r; } + +struct loose_alt_odb_data { + each_loose_object_fn *cb; + void *data; +}; + +static int loose_from_alt_odb(struct alternate_object_database *alt, + void *vdata) +{ + struct loose_alt_odb_data *data = vdata; + return for_each_loose_file_in_objdir(alt->base, + data->cb, NULL, NULL, + data->data); +} + +int for_each_loose_object(each_loose_object_fn cb, void *data) +{ + struct loose_alt_odb_data alt; + int r; + + r = for_each_loose_file_in_objdir(get_object_directory(), + cb, NULL, NULL, data); + if (r) + return r; + + alt.cb = cb; + alt.data = data; + return foreach_alt_odb(loose_from_alt_odb, &alt); +} + +static int for_each_object_in_pack(struct packed_git *p, each_packed_object_fn cb, void *data) +{ + uint32_t i; + int r = 0; + + for (i = 0; i < p->num_objects; i++) { + const unsigned char *sha1 = nth_packed_object_sha1(p, i); + + if (!sha1) + return error("unable to get sha1 of object %u in %s", + i, p->pack_name); + + r = cb(sha1, p, i, data); + if (r) + break; + } + return r; +} + +int for_each_packed_object(each_packed_object_fn cb, void *data) +{ + struct packed_git *p; + int r = 0; + + prepare_packed_git(); + for (p = packed_git; p; p = p->next) { + r = for_each_object_in_pack(p, cb, data); + if (r) + break; + } + return r; +} |