{
struct for_each_object_payload *payload = _payload;
if (oi && oi->whence == OI_PACKED)
- return payload->callback(oid, oi->u.packed.pack, oi->u.packed.offset,
+ return payload->callback(oid, oi->sourcep->u.packed.pack,
+ oi->sourcep->u.packed.offset,
payload->payload);
return payload->callback(oid, NULL, 0, payload->payload);
}
&payload, flags);
}
} else {
- struct object_info oi = { 0 };
+ struct object_info_source oi_source;
+ struct object_info oi = {
+ .sourcep = &oi_source,
+ };
for (source = the_repository->objects->sources; source; source = source->next) {
struct odb_source_files *files = odb_source_files_downcast(source);
oidset_iter_init(&outgoing_links, &iter);
while ((oid = oidset_iter_next(&iter))) {
- struct object_info info = OBJECT_INFO_INIT;
+ struct object_info_source info_source;
+ struct object_info info = {
+ .sourcep = &info_source,
+ };
+
if (odb_read_object_info_extended(the_repository->objects, oid, &info, 0))
/* Missing; assume it is a promisor object */
continue;
- if (info.whence == OI_PACKED && info.u.packed.pack->pack_promisor)
+ if (info.whence == OI_PACKED && info_source.u.packed.pack->pack_promisor)
continue;
if (!cmd.args.nr) {
void *data UNUSED)
{
if (cruft) {
- add_cruft_object_entry(oid, OBJ_NONE, oi->u.packed.pack,
- oi->u.packed.offset, NULL, *oi->mtimep);
+ add_cruft_object_entry(oid, OBJ_NONE, oi->sourcep->u.packed.pack,
+ oi->sourcep->u.packed.offset, NULL,
+ *oi->mtimep);
} else {
add_object_entry(oid, OBJ_NONE, "", 0);
}
ODB_FOR_EACH_OBJECT_SKIP_IN_CORE_KEPT_PACKS |
ODB_FOR_EACH_OBJECT_SKIP_ON_DISK_KEPT_PACKS,
};
+ struct object_info_source oi_source;
struct object_info oi = {
.mtimep = &mtime,
+ .sourcep = &oi_source,
};
odb_prepare_alternates(to_pack.repo->objects);
static int is_not_in_promisor_pack_obj(struct object *obj, void *data UNUSED)
{
- struct object_info info = OBJECT_INFO_INIT;
+ struct object_info_source info_source;
+ struct object_info info = {
+ .sourcep = &info_source,
+ };
+
if (odb_read_object_info_extended(the_repository->objects, &obj->oid, &info, 0))
BUG("should_include_obj should only be called on existing objects");
- return info.whence != OI_PACKED || !info.u.packed.pack->pack_promisor;
+ return info.whence != OI_PACKED || !info_source.u.packed.pack->pack_promisor;
}
static int is_not_in_promisor_pack(struct commit *commit, void *data) {
}
}
input_oi->whence = new_oi.whence;
- input_oi->u = new_oi.u;
+ if (input_oi->sourcep)
+ *input_oi->sourcep = *new_oi.sourcep;
return ret;
}
void *buf, size_t len, enum object_type type,
struct object_id *oid);
+/*
+ * Object information that can be used to uniquely identify an object and learn
+ * more about how exactly it is stored.
+ */
+struct object_info_source {
+ /*
+ * Backend-specific information about the specific object. This can be
+ * used for example to uniquely identify a given object in case it
+ * exists multiple times.
+ */
+ union {
+ /*
+ * struct {
+ * ... Nothing to expose in this case
+ * } cached;
+ * struct {
+ * ... Nothing to expose in this case
+ * } loose;
+ */
+ struct {
+ struct packed_git *pack;
+ off_t offset;
+ enum packed_object_type {
+ PACKED_OBJECT_TYPE_UNKNOWN,
+ PACKED_OBJECT_TYPE_FULL,
+ PACKED_OBJECT_TYPE_OFS_DELTA,
+ PACKED_OBJECT_TYPE_REF_DELTA,
+ } type;
+ } packed;
+ } u;
+};
+
struct object_info {
/* Request */
enum object_type *typep;
*/
time_t *mtimep;
+ /*
+ * Backend-specific information that tells the caller where exactly an
+ * object was looked up from. This information should help disambiguate
+ * object lookups in case the same object exists in multiple sources,
+ * or multiple times in the same source.
+ */
+ struct object_info_source *sourcep;
+
/* Response */
enum {
OI_CACHED,
OI_LOOSE,
OI_PACKED,
} whence;
- union {
- /*
- * struct {
- * ... Nothing to expose in this case
- * } cached;
- * struct {
- * ... Nothing to expose in this case
- * } loose;
- */
- struct {
- struct packed_git *pack;
- off_t offset;
- enum packed_object_type {
- PACKED_OBJECT_TYPE_UNKNOWN,
- PACKED_OBJECT_TYPE_FULL,
- PACKED_OBJECT_TYPE_OFS_DELTA,
- PACKED_OBJECT_TYPE_REF_DELTA,
- } type;
- } packed;
- } u;
};
/*
}
oi->whence = OI_PACKED;
- oi->u.packed.offset = obj_offset;
- oi->u.packed.pack = p;
- switch (type) {
- case OBJ_NONE:
- oi->u.packed.type = PACKED_OBJECT_TYPE_UNKNOWN;
- break;
- case OBJ_REF_DELTA:
- oi->u.packed.type = PACKED_OBJECT_TYPE_REF_DELTA;
- break;
- case OBJ_OFS_DELTA:
- oi->u.packed.type = PACKED_OBJECT_TYPE_OFS_DELTA;
- break;
- default:
- oi->u.packed.type = PACKED_OBJECT_TYPE_FULL;
- break;
+ if (oi->sourcep) {
+ oi->sourcep->u.packed.offset = obj_offset;
+ oi->sourcep->u.packed.pack = p;
+
+ switch (type) {
+ case OBJ_NONE:
+ oi->sourcep->u.packed.type = PACKED_OBJECT_TYPE_UNKNOWN;
+ break;
+ case OBJ_REF_DELTA:
+ oi->sourcep->u.packed.type = PACKED_OBJECT_TYPE_REF_DELTA;
+ break;
+ case OBJ_OFS_DELTA:
+ oi->sourcep->u.packed.type = PACKED_OBJECT_TYPE_OFS_DELTA;
+ break;
+ default:
+ oi->sourcep->u.packed.type = PACKED_OBJECT_TYPE_FULL;
+ break;
+ }
}
ret = 0;
add_pending_object(data->revs, obj, "");
if (data->cb) {
if (oi->whence == OI_PACKED)
- data->cb(obj, oi->u.packed.pack, oi->u.packed.offset, *oi->mtimep);
+ data->cb(obj, oi->sourcep->u.packed.pack,
+ oi->sourcep->u.packed.offset, *oi->mtimep);
else
data->cb(obj, NULL, 0, *oi->mtimep);
}
unsigned flags;
enum object_type type;
time_t mtime;
+ struct object_info_source oi_source;
struct object_info oi = {
.mtimep = &mtime,
.typep = &type,
+ .sourcep = &oi_source,
};
int r;