diff options
Diffstat (limited to 'sha1_file.c')
-rw-r--r-- | sha1_file.c | 27 |
1 files changed, 22 insertions, 5 deletions
diff --git a/sha1_file.c b/sha1_file.c index 66a4e00fa8..445a871db3 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -14,6 +14,7 @@ #include "tag.h" #include "tree.h" #include "refs.h" +#include "pack-revindex.h" #ifndef O_NOATIME #if defined(__linux__) && (defined(__i386__) || defined(__PPC__)) @@ -1367,11 +1368,15 @@ const char *packed_object_info_detail(struct packed_git *p, unsigned long dummy; unsigned char *next_sha1; enum object_type type; + struct revindex_entry *revidx; *delta_chain_length = 0; curpos = obj_offset; type = unpack_object_header(p, &w_curs, &curpos, size); + revidx = find_pack_revindex(p, obj_offset); + *store_size = revidx[1].offset - obj_offset; + for (;;) { switch (type) { default: @@ -1381,14 +1386,13 @@ const char *packed_object_info_detail(struct packed_git *p, case OBJ_TREE: case OBJ_BLOB: case OBJ_TAG: - *store_size = 0; /* notyet */ unuse_pack(&w_curs); return typename(type); case OBJ_OFS_DELTA: obj_offset = get_delta_base(p, &w_curs, &curpos, type, obj_offset); if (*delta_chain_length == 0) { - /* TODO: find base_sha1 as pointed by curpos */ - hashclr(base_sha1); + revidx = find_pack_revindex(p, obj_offset); + hashcpy(base_sha1, nth_packed_object_sha1(p, revidx->nr)); } break; case OBJ_REF_DELTA: @@ -1845,6 +1849,15 @@ static struct cached_object { } *cached_objects; static int cached_object_nr, cached_object_alloc; +static struct cached_object empty_tree = { + /* empty tree sha1: 4b825dc642cb6eb9a060e54bf8d69288fbee4904 */ + "\x4b\x82\x5d\xc6\x42\xcb\x6e\xb9\xa0\x60" + "\xe5\x4b\xf8\xd6\x92\x88\xfb\xee\x49\x04", + OBJ_TREE, + "", + 0 +}; + static struct cached_object *find_cached_object(const unsigned char *sha1) { int i; @@ -1854,6 +1867,8 @@ static struct cached_object *find_cached_object(const unsigned char *sha1) if (!hashcmp(co->sha1, sha1)) return co; } + if (!hashcmp(sha1, empty_tree.sha1)) + return &empty_tree; return NULL; } @@ -1943,7 +1958,8 @@ void *read_object_with_reference(const unsigned char *sha1, } ref_length = strlen(ref_type); - if (memcmp(buffer, ref_type, ref_length) || + if (ref_length + 40 > isize || + memcmp(buffer, ref_type, ref_length) || get_sha1_hex((char *) buffer + ref_length, actual_sha1)) { free(buffer); return NULL; @@ -2358,7 +2374,8 @@ int index_fd(unsigned char *sha1, int fd, struct stat *st, int write_object, if ((type == OBJ_BLOB) && S_ISREG(st->st_mode)) { struct strbuf nbuf; strbuf_init(&nbuf, 0); - if (convert_to_git(path, buf, size, &nbuf)) { + if (convert_to_git(path, buf, size, &nbuf, + write_object ? safe_crlf : 0)) { munmap(buf, size); buf = strbuf_detach(&nbuf, &size); re_allocated = 1; |