X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=sha1_file.c;h=445a871db31673af20017d36ff22fd106f77f510;hb=eed81838f0d0e031702473e1d427d71055134edd;hp=b0c24356ae7358561300c9bb3a3f56ba502b2a3b;hpb=bd8ff616c998da8b08bd59b47644408048b3016d;p=git.git diff --git a/sha1_file.c b/sha1_file.c index b0c24356a..445a871db 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__)) @@ -148,7 +149,7 @@ static void fill_sha1_path(char *pathbuf, const unsigned char *sha1) /* * NOTE! This returns a statically allocated buffer, so you have to be - * careful about using it. Do a "xstrdup()" if you need to save the + * careful about using it. Do an "xstrdup()" if you need to save the * filename. * * Also note that this returns the location for creating. Reading @@ -611,6 +612,22 @@ void release_pack_memory(size_t need, int fd) ; /* nothing */ } +void close_pack_windows(struct packed_git *p) +{ + while (p->windows) { + struct pack_window *w = p->windows; + + if (w->inuse_cnt) + die("pack '%s' still has open windows to it", + p->pack_name); + munmap(w->base, w->len); + pack_mapped -= w->len; + pack_open_windows--; + p->windows = w->next; + free(w); + } +} + void unuse_pack(struct pack_window **w_cursor) { struct pack_window *w = *w_cursor; @@ -1351,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: @@ -1365,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: @@ -1829,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; @@ -1838,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; } @@ -1927,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; @@ -2342,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;