The original interface for sha1_object_info() takes an object name and gives back a type and its size (the latter is given only when it was asked). The new interface wraps its implementation and exposes a bit more pieces of information that the interface used to discard, namely: - where the object is stored (loose? cached? packed?) - if packed, where in which packfile? Signed-off-by: Junio C Hamano <gitster@xxxxxxxxx> --- cache.h | 29 +++++++++++++++++++++++++++++ sha1_file.c | 46 +++++++++++++++++++++++++++++++++++++++------- 2 files changed, 68 insertions(+), 7 deletions(-) diff --git a/cache.h b/cache.h index cdb5112..dfd2d61 100644 --- a/cache.h +++ b/cache.h @@ -1022,6 +1022,35 @@ extern unsigned long unpack_object_header_buffer(const unsigned char *buf, unsig extern unsigned long get_size_from_delta(struct packed_git *, struct pack_window **, off_t); extern int packed_object_info_detail(struct packed_git *, off_t, unsigned long *, unsigned long *, unsigned int *, unsigned char *); +struct object_info { + /* Request */ + unsigned long *sizep; + int want_deltainfo; + + /* 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 { + off_t offset; + unsigned int delta; + struct packed_git *pack; + } packed; + } u; +}; +extern int sha1_object_info_extended(const unsigned char *, struct object_info *); + /* Dumb servers support */ extern int update_server_info(int); diff --git a/sha1_file.c b/sha1_file.c index 4f96eb1..9b16cd8 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -2093,7 +2093,8 @@ static int sha1_loose_object_info(const unsigned char *sha1, unsigned long *size return status; } -int sha1_object_info(const unsigned char *sha1, unsigned long *sizep) +/* returns enum object_type or negative */ +int sha1_object_info_extended(const unsigned char *sha1, struct object_info *oi) { struct cached_object *co; struct pack_entry e; @@ -2101,16 +2102,19 @@ int sha1_object_info(const unsigned char *sha1, unsigned long *sizep) co = find_cached_object(sha1); if (co) { - if (sizep) - *sizep = co->size; + if (oi->sizep) + *(oi->sizep) = co->size; + oi->whence = OI_CACHED; return co->type; } if (!find_pack_entry(sha1, &e)) { /* Most likely it's a loose object. */ - status = sha1_loose_object_info(sha1, sizep); - if (status >= 0) + status = sha1_loose_object_info(sha1, oi->sizep); + if (status >= 0) { + oi->whence = OI_LOOSE; return status; + } /* Not a loose object; someone else may have just packed it. */ reprepare_packed_git(); @@ -2118,15 +2122,43 @@ int sha1_object_info(const unsigned char *sha1, unsigned long *sizep) return status; } - status = packed_object_info(e.p, e.offset, sizep); + if (!oi->want_deltainfo) { + status = packed_object_info(e.p, e.offset, oi->sizep); + } else { + unsigned long size, store_size; + unsigned int delta_chain_length; + unsigned char base_sha1[20]; + status = packed_object_info_detail(e.p, e.offset, + &size, &store_size, + &delta_chain_length, + base_sha1); + if (0 <= status) { + if (oi->sizep) + *oi->sizep = size; + oi->u.packed.delta = delta_chain_length; + } + } if (status < 0) { mark_bad_packed_object(e.p, sha1); - status = sha1_object_info(sha1, sizep); + status = sha1_object_info_extended(sha1, oi); + } else { + oi->whence = OI_PACKED; + oi->u.packed.offset = e.offset; + oi->u.packed.pack = e.p; } return status; } +int sha1_object_info(const unsigned char *sha1, unsigned long *sizep) +{ + struct object_info oi; + + oi.sizep = sizep; + oi.want_deltainfo = 0; + return sha1_object_info_extended(sha1, &oi); +} + static void *read_packed_sha1(const unsigned char *sha1, enum object_type *type, unsigned long *size) { -- 1.7.5.1.365.g32b65 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html