aboutsummaryrefslogtreecommitdiffstats
path: root/pack-bitmap.c
diff options
context:
space:
mode:
Diffstat (limited to 'pack-bitmap.c')
-rw-r--r--pack-bitmap.c96
1 files changed, 80 insertions, 16 deletions
diff --git a/pack-bitmap.c b/pack-bitmap.c
index 6f7fd94c36..5299f49d59 100644
--- a/pack-bitmap.c
+++ b/pack-bitmap.c
@@ -745,6 +745,21 @@ struct bitmap_index *prepare_midx_bitmap_git(struct multi_pack_index *midx)
return NULL;
}
+int bitmap_index_contains_pack(struct bitmap_index *bitmap, struct packed_git *pack)
+{
+ for (; bitmap; bitmap = bitmap->base) {
+ if (bitmap_is_midx(bitmap)) {
+ for (size_t i = 0; i < bitmap->midx->num_packs; i++)
+ if (bitmap->midx->packs[i] == pack)
+ return 1;
+ } else if (bitmap->pack == pack) {
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
struct include_data {
struct bitmap_index *bitmap_git;
struct bitmap *base;
@@ -1409,7 +1424,7 @@ static struct bitmap *find_boundary_objects(struct bitmap_index *bitmap_git,
revs->tag_objects = tmp_tags;
reset_revision_walk();
- clear_object_flags(UNINTERESTING);
+ clear_object_flags(repo, UNINTERESTING);
/*
* Then add the boundary commit(s) as fill-in traversal tips.
@@ -1625,7 +1640,7 @@ static void show_extended_objects(struct bitmap_index *bitmap_git,
(obj->type == OBJ_TAG && !revs->tag_objects))
continue;
- show_reach(&obj->oid, obj->type, 0, eindex->hashes[i], NULL, 0);
+ show_reach(&obj->oid, obj->type, 0, eindex->hashes[i], NULL, 0, NULL);
}
}
@@ -1662,8 +1677,10 @@ static void init_type_iterator(struct ewah_or_iterator *it,
static void show_objects_for_type(
struct bitmap_index *bitmap_git,
+ struct bitmap *objects,
enum object_type object_type,
- show_reachable_fn show_reach)
+ show_reachable_fn show_reach,
+ void *payload)
{
size_t i = 0;
uint32_t offset;
@@ -1671,8 +1688,6 @@ static void show_objects_for_type(
struct ewah_or_iterator it;
eword_t filter;
- struct bitmap *objects = bitmap_git->result;
-
init_type_iterator(&it, bitmap_git, object_type);
for (i = 0; i < objects->word_alloc &&
@@ -1715,7 +1730,7 @@ static void show_objects_for_type(
if (bitmap_git->hashes)
hash = get_be32(bitmap_git->hashes + index_pos);
- show_reach(&oid, object_type, 0, hash, pack, ofs);
+ show_reach(&oid, object_type, 0, hash, pack, ofs, payload);
}
}
@@ -2024,6 +2039,50 @@ static void filter_packed_objects_from_bitmap(struct bitmap_index *bitmap_git,
}
}
+int for_each_bitmapped_object(struct bitmap_index *bitmap_git,
+ struct list_objects_filter_options *filter,
+ show_reachable_fn show_reach,
+ void *payload)
+{
+ struct bitmap *filtered_bitmap = NULL;
+ uint32_t objects_nr;
+ size_t full_word_count;
+ int ret;
+
+ if (!can_filter_bitmap(filter)) {
+ ret = -1;
+ goto out;
+ }
+
+ objects_nr = bitmap_num_objects(bitmap_git);
+ full_word_count = objects_nr / BITS_IN_EWORD;
+
+ /* We start from the all-1 bitmap and then filter down from there. */
+ filtered_bitmap = bitmap_word_alloc(full_word_count + !!(objects_nr % BITS_IN_EWORD));
+ memset(filtered_bitmap->words, 0xff, full_word_count * sizeof(*filtered_bitmap->words));
+ for (size_t i = full_word_count * BITS_IN_EWORD; i < objects_nr; i++)
+ bitmap_set(filtered_bitmap, i);
+
+ if (filter_bitmap(bitmap_git, NULL, filtered_bitmap, filter) < 0) {
+ ret = -1;
+ goto out;
+ }
+
+ show_objects_for_type(bitmap_git, filtered_bitmap,
+ OBJ_COMMIT, show_reach, payload);
+ show_objects_for_type(bitmap_git, filtered_bitmap,
+ OBJ_TREE, show_reach, payload);
+ show_objects_for_type(bitmap_git, filtered_bitmap,
+ OBJ_BLOB, show_reach, payload);
+ show_objects_for_type(bitmap_git, filtered_bitmap,
+ OBJ_TAG, show_reach, payload);
+
+ ret = 0;
+out:
+ bitmap_free(filtered_bitmap);
+ return ret;
+}
+
struct bitmap_index *prepare_bitmap_walk(struct rev_info *revs,
int filter_provided_objects)
{
@@ -2060,7 +2119,7 @@ struct bitmap_index *prepare_bitmap_walk(struct rev_info *revs,
struct object *object = revs->pending.objects[i].item;
if (object->type == OBJ_NONE)
- parse_object_or_die(&object->oid, NULL);
+ parse_object_or_die(revs->repo, &object->oid, NULL);
while (object->type == OBJ_TAG) {
struct tag *tag = (struct tag *) object;
@@ -2070,7 +2129,7 @@ struct bitmap_index *prepare_bitmap_walk(struct rev_info *revs,
else
object_list_insert(object, &wants);
- object = parse_object_or_die(get_tagged_oid(tag), NULL);
+ object = parse_object_or_die(revs->repo, get_tagged_oid(tag), NULL);
object->flags |= (tag->object.flags & UNINTERESTING);
}
@@ -2518,13 +2577,17 @@ void traverse_bitmap_commit_list(struct bitmap_index *bitmap_git,
{
assert(bitmap_git->result);
- show_objects_for_type(bitmap_git, OBJ_COMMIT, show_reachable);
+ show_objects_for_type(bitmap_git, bitmap_git->result,
+ OBJ_COMMIT, show_reachable, NULL);
if (revs->tree_objects)
- show_objects_for_type(bitmap_git, OBJ_TREE, show_reachable);
+ show_objects_for_type(bitmap_git, bitmap_git->result,
+ OBJ_TREE, show_reachable, NULL);
if (revs->blob_objects)
- show_objects_for_type(bitmap_git, OBJ_BLOB, show_reachable);
+ show_objects_for_type(bitmap_git, bitmap_git->result,
+ OBJ_BLOB, show_reachable, NULL);
if (revs->tag_objects)
- show_objects_for_type(bitmap_git, OBJ_TAG, show_reachable);
+ show_objects_for_type(bitmap_git, bitmap_git->result,
+ OBJ_TAG, show_reachable, NULL);
show_extended_objects(bitmap_git, revs, show_reachable);
}
@@ -3216,7 +3279,8 @@ int bitmap_is_preferred_refname(struct repository *r, const char *refname)
return 0;
}
-static int verify_bitmap_file(const char *name)
+static int verify_bitmap_file(const struct git_hash_algo *algop,
+ const char *name)
{
struct stat st;
unsigned char *data;
@@ -3232,7 +3296,7 @@ static int verify_bitmap_file(const char *name)
data = xmmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
close(fd);
- if (!hashfile_checksum_valid(data, st.st_size))
+ if (!hashfile_checksum_valid(algop, data, st.st_size))
res = error(_("bitmap file '%s' has invalid checksum"),
name);
@@ -3247,14 +3311,14 @@ int verify_bitmap_files(struct repository *r)
for (struct multi_pack_index *m = get_multi_pack_index(r);
m; m = m->next) {
char *midx_bitmap_name = midx_bitmap_filename(m);
- res |= verify_bitmap_file(midx_bitmap_name);
+ res |= verify_bitmap_file(r->hash_algo, midx_bitmap_name);
free(midx_bitmap_name);
}
for (struct packed_git *p = get_all_packs(r);
p; p = p->next) {
char *pack_bitmap_name = pack_bitmap_filename(p);
- res |= verify_bitmap_file(pack_bitmap_name);
+ res |= verify_bitmap_file(r->hash_algo, pack_bitmap_name);
free(pack_bitmap_name);
}