mirror of
https://github.com/git-for-windows/git.git
synced 2026-06-13 20:03:18 -05:00
odb/source-packed: wire up for_each_object() callback
Move `packfile_store_for_each_object()` and its associated helpers from "packfile.c" into "odb/source-packed.c" and wire it up as the `for_each_object()` callback of the "packed" source. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
committed by
Junio C Hamano
parent
8813b9486d
commit
f298de400e
@@ -916,8 +916,8 @@ static void batch_each_object(struct batch_options *opt,
|
||||
|
||||
for (source = the_repository->objects->sources; source; source = source->next) {
|
||||
struct odb_source_files *files = odb_source_files_downcast(source);
|
||||
int ret = packfile_store_for_each_object(files->packed, &oi,
|
||||
batch_one_object_oi, &payload, &opts);
|
||||
int ret = odb_source_for_each_object(&files->packed->base, &oi,
|
||||
batch_one_object_oi, &payload, &opts);
|
||||
if (ret)
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -4503,8 +4503,8 @@ static void add_objects_in_unpacked_packs(void)
|
||||
if (!source->local)
|
||||
continue;
|
||||
|
||||
if (packfile_store_for_each_object(files->packed, &oi,
|
||||
add_object_in_unpacked_pack, NULL, &opts))
|
||||
if (odb_source_for_each_object(&files->packed->base, &oi,
|
||||
add_object_in_unpacked_pack, NULL, &opts))
|
||||
die(_("cannot open pack index"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2016,8 +2016,8 @@ static void fill_oids_from_all_packs(struct write_commit_graph_context *ctx)
|
||||
odb_prepare_alternates(ctx->r->objects);
|
||||
for (source = ctx->r->objects->sources; source; source = source->next) {
|
||||
struct odb_source_files *files = odb_source_files_downcast(source);
|
||||
packfile_store_for_each_object(files->packed, &oi, add_packed_commits_oi,
|
||||
ctx, &opts);
|
||||
odb_source_for_each_object(&files->packed->base, &oi, add_packed_commits_oi,
|
||||
ctx, &opts);
|
||||
}
|
||||
|
||||
if (ctx->progress_done < ctx->approx_nr_objects)
|
||||
|
||||
@@ -88,7 +88,7 @@ static int odb_source_files_for_each_object(struct odb_source *source,
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = packfile_store_for_each_object(files->packed, request, cb, cb_data, opts);
|
||||
ret = odb_source_for_each_object(&files->packed->base, request, cb, cb_data, opts);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
||||
@@ -81,6 +81,263 @@ static int odb_source_packed_read_object_stream(struct odb_read_stream **out,
|
||||
return packfile_read_object_stream(out, oid, e.p, e.offset);
|
||||
}
|
||||
|
||||
struct odb_source_packed_for_each_object_wrapper_data {
|
||||
struct odb_source_packed *store;
|
||||
const struct object_info *request;
|
||||
odb_for_each_object_cb cb;
|
||||
void *cb_data;
|
||||
};
|
||||
|
||||
static int odb_source_packed_for_each_object_wrapper(const struct object_id *oid,
|
||||
struct packed_git *pack,
|
||||
uint32_t index_pos,
|
||||
void *cb_data)
|
||||
{
|
||||
struct odb_source_packed_for_each_object_wrapper_data *data = cb_data;
|
||||
|
||||
if (data->request) {
|
||||
off_t offset = nth_packed_object_offset(pack, index_pos);
|
||||
struct object_info oi = *data->request;
|
||||
|
||||
if (packed_object_info_with_index_pos(pack, offset,
|
||||
&index_pos, &oi) < 0) {
|
||||
mark_bad_packed_object(pack, oid);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return data->cb(oid, &oi, data->cb_data);
|
||||
} else {
|
||||
return data->cb(oid, NULL, data->cb_data);
|
||||
}
|
||||
}
|
||||
|
||||
static int match_hash(unsigned len, const unsigned char *a, const unsigned char *b)
|
||||
{
|
||||
do {
|
||||
if (*a != *b)
|
||||
return 0;
|
||||
a++;
|
||||
b++;
|
||||
len -= 2;
|
||||
} while (len > 1);
|
||||
if (len)
|
||||
if ((*a ^ *b) & 0xf0)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int for_each_prefixed_object_in_midx(
|
||||
struct odb_source_packed *store,
|
||||
struct multi_pack_index *m,
|
||||
const struct odb_for_each_object_options *opts,
|
||||
struct odb_source_packed_for_each_object_wrapper_data *data)
|
||||
{
|
||||
int ret;
|
||||
|
||||
for (; m; m = m->base_midx) {
|
||||
uint32_t num, i, first = 0;
|
||||
int len = opts->prefix_hex_len > m->source->odb->repo->hash_algo->hexsz ?
|
||||
m->source->odb->repo->hash_algo->hexsz : opts->prefix_hex_len;
|
||||
|
||||
if (!m->num_objects)
|
||||
continue;
|
||||
|
||||
num = m->num_objects + m->num_objects_in_base;
|
||||
|
||||
bsearch_one_midx(opts->prefix, m, &first);
|
||||
|
||||
/*
|
||||
* At this point, "first" is the location of the lowest
|
||||
* object with an object name that could match "opts->prefix".
|
||||
* See if we have 0, 1 or more objects that actually match(es).
|
||||
*/
|
||||
for (i = first; i < num; i++) {
|
||||
const struct object_id *current = NULL;
|
||||
struct object_id oid;
|
||||
|
||||
current = nth_midxed_object_oid(&oid, m, i);
|
||||
|
||||
if (!match_hash(len, opts->prefix->hash, current->hash))
|
||||
break;
|
||||
|
||||
if (data->request) {
|
||||
struct object_info oi = *data->request;
|
||||
|
||||
ret = odb_source_read_object_info(&store->base, current,
|
||||
&oi, 0);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
ret = data->cb(&oid, &oi, data->cb_data);
|
||||
if (ret)
|
||||
goto out;
|
||||
} else {
|
||||
ret = data->cb(&oid, NULL, data->cb_data);
|
||||
if (ret)
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int for_each_prefixed_object_in_pack(
|
||||
struct odb_source_packed *store,
|
||||
struct packed_git *p,
|
||||
const struct odb_for_each_object_options *opts,
|
||||
struct odb_source_packed_for_each_object_wrapper_data *data)
|
||||
{
|
||||
uint32_t num, i, first = 0;
|
||||
int len = opts->prefix_hex_len > p->repo->hash_algo->hexsz ?
|
||||
p->repo->hash_algo->hexsz : opts->prefix_hex_len;
|
||||
int ret;
|
||||
|
||||
num = p->num_objects;
|
||||
bsearch_pack(opts->prefix, p, &first);
|
||||
|
||||
/*
|
||||
* At this point, "first" is the location of the lowest object
|
||||
* with an object name that could match "bin_pfx". See if we have
|
||||
* 0, 1 or more objects that actually match(es).
|
||||
*/
|
||||
for (i = first; i < num; i++) {
|
||||
struct object_id oid;
|
||||
|
||||
nth_packed_object_id(&oid, p, i);
|
||||
if (!match_hash(len, opts->prefix->hash, oid.hash))
|
||||
break;
|
||||
|
||||
if (data->request) {
|
||||
struct object_info oi = *data->request;
|
||||
|
||||
ret = odb_source_read_object_info(&store->base, &oid, &oi, 0);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
ret = data->cb(&oid, &oi, data->cb_data);
|
||||
if (ret)
|
||||
goto out;
|
||||
} else {
|
||||
ret = data->cb(&oid, NULL, data->cb_data);
|
||||
if (ret)
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int odb_source_packed_for_each_prefixed_object(
|
||||
struct odb_source_packed *store,
|
||||
const struct odb_for_each_object_options *opts,
|
||||
struct odb_source_packed_for_each_object_wrapper_data *data)
|
||||
{
|
||||
struct packfile_list_entry *e;
|
||||
struct multi_pack_index *m;
|
||||
bool pack_errors = false;
|
||||
int ret;
|
||||
|
||||
if (opts->flags)
|
||||
BUG("flags unsupported");
|
||||
|
||||
store->skip_mru_updates = true;
|
||||
|
||||
m = get_multi_pack_index(&store->files->base);
|
||||
if (m) {
|
||||
ret = for_each_prefixed_object_in_midx(store, m, opts, data);
|
||||
if (ret)
|
||||
goto out;
|
||||
}
|
||||
|
||||
for (e = packfile_store_get_packs(store); e; e = e->next) {
|
||||
if (e->pack->multi_pack_index)
|
||||
continue;
|
||||
|
||||
if (open_pack_index(e->pack)) {
|
||||
pack_errors = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!e->pack->num_objects)
|
||||
continue;
|
||||
|
||||
ret = for_each_prefixed_object_in_pack(store, e->pack, opts, data);
|
||||
if (ret)
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
|
||||
out:
|
||||
store->skip_mru_updates = false;
|
||||
if (!ret && pack_errors)
|
||||
ret = -1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int odb_source_packed_for_each_object(struct odb_source *source,
|
||||
const struct object_info *request,
|
||||
odb_for_each_object_cb cb,
|
||||
void *cb_data,
|
||||
const struct odb_for_each_object_options *opts)
|
||||
{
|
||||
struct odb_source_packed *packed = odb_source_packed_downcast(source);
|
||||
struct odb_source_packed_for_each_object_wrapper_data data = {
|
||||
.store = packed,
|
||||
.request = request,
|
||||
.cb = cb,
|
||||
.cb_data = cb_data,
|
||||
};
|
||||
struct packfile_list_entry *e;
|
||||
int pack_errors = 0, ret;
|
||||
|
||||
if (opts->prefix)
|
||||
return odb_source_packed_for_each_prefixed_object(packed, opts, &data);
|
||||
|
||||
packed->skip_mru_updates = true;
|
||||
|
||||
for (e = packfile_store_get_packs(packed); e; e = e->next) {
|
||||
struct packed_git *p = e->pack;
|
||||
|
||||
if ((opts->flags & ODB_FOR_EACH_OBJECT_LOCAL_ONLY) && !p->pack_local)
|
||||
continue;
|
||||
if ((opts->flags & ODB_FOR_EACH_OBJECT_PROMISOR_ONLY) &&
|
||||
!p->pack_promisor)
|
||||
continue;
|
||||
if ((opts->flags & ODB_FOR_EACH_OBJECT_SKIP_IN_CORE_KEPT_PACKS) &&
|
||||
p->pack_keep_in_core)
|
||||
continue;
|
||||
if ((opts->flags & ODB_FOR_EACH_OBJECT_SKIP_ON_DISK_KEPT_PACKS) &&
|
||||
p->pack_keep)
|
||||
continue;
|
||||
if (open_pack_index(p)) {
|
||||
pack_errors = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
ret = for_each_object_in_pack(p, odb_source_packed_for_each_object_wrapper,
|
||||
&data, opts->flags);
|
||||
if (ret)
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
|
||||
out:
|
||||
packed->skip_mru_updates = false;
|
||||
|
||||
if (!ret && pack_errors)
|
||||
ret = -1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void (*report_garbage)(unsigned seen_bits, const char *path);
|
||||
|
||||
static void report_helper(const struct string_list *list,
|
||||
@@ -291,6 +548,7 @@ struct odb_source_packed *odb_source_packed_new(struct odb_source_files *parent)
|
||||
packed->base.reprepare = odb_source_packed_reprepare;
|
||||
packed->base.read_object_info = odb_source_packed_read_object_info;
|
||||
packed->base.read_object_stream = odb_source_packed_read_object_stream;
|
||||
packed->base.for_each_object = odb_source_packed_for_each_object;
|
||||
|
||||
if (!is_absolute_path(parent->base.path))
|
||||
chdir_notify_register(NULL, odb_source_packed_reparent, packed);
|
||||
|
||||
260
packfile.c
260
packfile.c
@@ -1362,8 +1362,8 @@ static void add_delta_base_cache(struct packed_git *p, off_t base_offset,
|
||||
hashmap_add(&delta_base_cache, &ent->ent);
|
||||
}
|
||||
|
||||
static int packed_object_info_with_index_pos(struct packed_git *p, off_t obj_offset,
|
||||
uint32_t *maybe_index_pos, struct object_info *oi)
|
||||
int packed_object_info_with_index_pos(struct packed_git *p, off_t obj_offset,
|
||||
uint32_t *maybe_index_pos, struct object_info *oi)
|
||||
{
|
||||
struct pack_window *w_curs = NULL;
|
||||
size_t size;
|
||||
@@ -2068,262 +2068,6 @@ int for_each_object_in_pack(struct packed_git *p,
|
||||
return r;
|
||||
}
|
||||
|
||||
struct odb_source_packed_for_each_object_wrapper_data {
|
||||
struct odb_source_packed *store;
|
||||
const struct object_info *request;
|
||||
odb_for_each_object_cb cb;
|
||||
void *cb_data;
|
||||
};
|
||||
|
||||
static int packfile_store_for_each_object_wrapper(const struct object_id *oid,
|
||||
struct packed_git *pack,
|
||||
uint32_t index_pos,
|
||||
void *cb_data)
|
||||
{
|
||||
struct odb_source_packed_for_each_object_wrapper_data *data = cb_data;
|
||||
|
||||
if (data->request) {
|
||||
off_t offset = nth_packed_object_offset(pack, index_pos);
|
||||
struct object_info oi = *data->request;
|
||||
|
||||
if (packed_object_info_with_index_pos(pack, offset,
|
||||
&index_pos, &oi) < 0) {
|
||||
mark_bad_packed_object(pack, oid);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return data->cb(oid, &oi, data->cb_data);
|
||||
} else {
|
||||
return data->cb(oid, NULL, data->cb_data);
|
||||
}
|
||||
}
|
||||
|
||||
static int match_hash(unsigned len, const unsigned char *a, const unsigned char *b)
|
||||
{
|
||||
do {
|
||||
if (*a != *b)
|
||||
return 0;
|
||||
a++;
|
||||
b++;
|
||||
len -= 2;
|
||||
} while (len > 1);
|
||||
if (len)
|
||||
if ((*a ^ *b) & 0xf0)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int for_each_prefixed_object_in_midx(
|
||||
struct odb_source_packed *store,
|
||||
struct multi_pack_index *m,
|
||||
const struct odb_for_each_object_options *opts,
|
||||
struct odb_source_packed_for_each_object_wrapper_data *data)
|
||||
{
|
||||
int ret;
|
||||
|
||||
for (; m; m = m->base_midx) {
|
||||
uint32_t num, i, first = 0;
|
||||
int len = opts->prefix_hex_len > m->source->odb->repo->hash_algo->hexsz ?
|
||||
m->source->odb->repo->hash_algo->hexsz : opts->prefix_hex_len;
|
||||
|
||||
if (!m->num_objects)
|
||||
continue;
|
||||
|
||||
num = m->num_objects + m->num_objects_in_base;
|
||||
|
||||
bsearch_one_midx(opts->prefix, m, &first);
|
||||
|
||||
/*
|
||||
* At this point, "first" is the location of the lowest
|
||||
* object with an object name that could match "opts->prefix".
|
||||
* See if we have 0, 1 or more objects that actually match(es).
|
||||
*/
|
||||
for (i = first; i < num; i++) {
|
||||
const struct object_id *current = NULL;
|
||||
struct object_id oid;
|
||||
|
||||
current = nth_midxed_object_oid(&oid, m, i);
|
||||
|
||||
if (!match_hash(len, opts->prefix->hash, current->hash))
|
||||
break;
|
||||
|
||||
if (data->request) {
|
||||
struct object_info oi = *data->request;
|
||||
|
||||
ret = odb_source_read_object_info(&store->base, current,
|
||||
&oi, 0);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
ret = data->cb(&oid, &oi, data->cb_data);
|
||||
if (ret)
|
||||
goto out;
|
||||
} else {
|
||||
ret = data->cb(&oid, NULL, data->cb_data);
|
||||
if (ret)
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int for_each_prefixed_object_in_pack(
|
||||
struct odb_source_packed *store,
|
||||
struct packed_git *p,
|
||||
const struct odb_for_each_object_options *opts,
|
||||
struct odb_source_packed_for_each_object_wrapper_data *data)
|
||||
{
|
||||
uint32_t num, i, first = 0;
|
||||
int len = opts->prefix_hex_len > p->repo->hash_algo->hexsz ?
|
||||
p->repo->hash_algo->hexsz : opts->prefix_hex_len;
|
||||
int ret;
|
||||
|
||||
num = p->num_objects;
|
||||
bsearch_pack(opts->prefix, p, &first);
|
||||
|
||||
/*
|
||||
* At this point, "first" is the location of the lowest object
|
||||
* with an object name that could match "bin_pfx". See if we have
|
||||
* 0, 1 or more objects that actually match(es).
|
||||
*/
|
||||
for (i = first; i < num; i++) {
|
||||
struct object_id oid;
|
||||
|
||||
nth_packed_object_id(&oid, p, i);
|
||||
if (!match_hash(len, opts->prefix->hash, oid.hash))
|
||||
break;
|
||||
|
||||
if (data->request) {
|
||||
struct object_info oi = *data->request;
|
||||
|
||||
ret = odb_source_read_object_info(&store->base, &oid, &oi, 0);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
ret = data->cb(&oid, &oi, data->cb_data);
|
||||
if (ret)
|
||||
goto out;
|
||||
} else {
|
||||
ret = data->cb(&oid, NULL, data->cb_data);
|
||||
if (ret)
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int packfile_store_for_each_prefixed_object(
|
||||
struct odb_source_packed *store,
|
||||
const struct odb_for_each_object_options *opts,
|
||||
struct odb_source_packed_for_each_object_wrapper_data *data)
|
||||
{
|
||||
struct packfile_list_entry *e;
|
||||
struct multi_pack_index *m;
|
||||
bool pack_errors = false;
|
||||
int ret;
|
||||
|
||||
if (opts->flags)
|
||||
BUG("flags unsupported");
|
||||
|
||||
store->skip_mru_updates = true;
|
||||
|
||||
m = get_multi_pack_index(&store->files->base);
|
||||
if (m) {
|
||||
ret = for_each_prefixed_object_in_midx(store, m, opts, data);
|
||||
if (ret)
|
||||
goto out;
|
||||
}
|
||||
|
||||
for (e = packfile_store_get_packs(store); e; e = e->next) {
|
||||
if (e->pack->multi_pack_index)
|
||||
continue;
|
||||
|
||||
if (open_pack_index(e->pack)) {
|
||||
pack_errors = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!e->pack->num_objects)
|
||||
continue;
|
||||
|
||||
ret = for_each_prefixed_object_in_pack(store, e->pack, opts, data);
|
||||
if (ret)
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
|
||||
out:
|
||||
store->skip_mru_updates = false;
|
||||
if (!ret && pack_errors)
|
||||
ret = -1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int packfile_store_for_each_object(struct odb_source_packed *store,
|
||||
const struct object_info *request,
|
||||
odb_for_each_object_cb cb,
|
||||
void *cb_data,
|
||||
const struct odb_for_each_object_options *opts)
|
||||
{
|
||||
struct odb_source_packed_for_each_object_wrapper_data data = {
|
||||
.store = store,
|
||||
.request = request,
|
||||
.cb = cb,
|
||||
.cb_data = cb_data,
|
||||
};
|
||||
struct packfile_list_entry *e;
|
||||
int pack_errors = 0, ret;
|
||||
|
||||
if (opts->prefix)
|
||||
return packfile_store_for_each_prefixed_object(store, opts, &data);
|
||||
|
||||
store->skip_mru_updates = true;
|
||||
|
||||
for (e = packfile_store_get_packs(store); e; e = e->next) {
|
||||
struct packed_git *p = e->pack;
|
||||
|
||||
if ((opts->flags & ODB_FOR_EACH_OBJECT_LOCAL_ONLY) && !p->pack_local)
|
||||
continue;
|
||||
if ((opts->flags & ODB_FOR_EACH_OBJECT_PROMISOR_ONLY) &&
|
||||
!p->pack_promisor)
|
||||
continue;
|
||||
if ((opts->flags & ODB_FOR_EACH_OBJECT_SKIP_IN_CORE_KEPT_PACKS) &&
|
||||
p->pack_keep_in_core)
|
||||
continue;
|
||||
if ((opts->flags & ODB_FOR_EACH_OBJECT_SKIP_ON_DISK_KEPT_PACKS) &&
|
||||
p->pack_keep)
|
||||
continue;
|
||||
if (open_pack_index(p)) {
|
||||
pack_errors = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
ret = for_each_object_in_pack(p, packfile_store_for_each_object_wrapper,
|
||||
&data, opts->flags);
|
||||
if (ret)
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
|
||||
out:
|
||||
store->skip_mru_updates = false;
|
||||
|
||||
if (!ret && pack_errors)
|
||||
ret = -1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int extend_abbrev_len(const struct object_id *a,
|
||||
const struct object_id *b,
|
||||
unsigned *out)
|
||||
|
||||
17
packfile.h
17
packfile.h
@@ -227,21 +227,6 @@ int for_each_object_in_pack(struct packed_git *p,
|
||||
each_packed_object_fn, void *data,
|
||||
enum odb_for_each_object_flags flags);
|
||||
|
||||
/*
|
||||
* Iterate through all packed objects in the given packfile store and invoke
|
||||
* the callback function for each of them. If an object info request is given,
|
||||
* then the object info will be read for every individual object and passed to
|
||||
* the callback as if `packfile_store_read_object_info()` was called for the
|
||||
* object.
|
||||
*
|
||||
* The flags parameter is a combination of `odb_for_each_object_flags`.
|
||||
*/
|
||||
int packfile_store_for_each_object(struct odb_source_packed *store,
|
||||
const struct object_info *request,
|
||||
odb_for_each_object_cb cb,
|
||||
void *cb_data,
|
||||
const struct odb_for_each_object_options *opts);
|
||||
|
||||
int packfile_store_find_abbrev_len(struct odb_source_packed *store,
|
||||
const struct object_id *oid,
|
||||
unsigned min_len,
|
||||
@@ -354,6 +339,8 @@ extern int do_check_packed_object_crc;
|
||||
*/
|
||||
int packed_object_info(struct packed_git *pack,
|
||||
off_t offset, struct object_info *);
|
||||
int packed_object_info_with_index_pos(struct packed_git *p, off_t obj_offset,
|
||||
uint32_t *maybe_index_pos, struct object_info *oi);
|
||||
|
||||
void mark_bad_packed_object(struct packed_git *, const struct object_id *);
|
||||
const struct packed_git *has_packed_and_bad(struct repository *, const struct object_id *);
|
||||
|
||||
Reference in New Issue
Block a user