X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=builtin-pack-objects.c;h=45ac3e482acc1c0f8f2bad043f1ba50019dec505;hb=f48fd68887a03756658a46486a5dd1301c5a655f;hp=b5ed9ce2c89daab7a69d399a6599e203dc04971a;hpb=cc58fc0684396c5298b21c97f00a568e46224258;p=git.git diff --git a/builtin-pack-objects.c b/builtin-pack-objects.c index b5ed9ce2c..45ac3e482 100644 --- a/builtin-pack-objects.c +++ b/builtin-pack-objects.c @@ -23,7 +23,7 @@ git-pack-objects [{ -q | --progress | --all-progress }] \n\ struct object_entry { unsigned char sha1[20]; unsigned long size; /* uncompressed size */ - unsigned long offset; /* offset into the final pack file; + off_t offset; /* offset into the final pack file; * nonzero if already written. */ unsigned int depth; /* delta depth */ @@ -35,7 +35,7 @@ struct object_entry { #define in_pack_header_size delta_size /* only when reusing pack data */ struct object_entry *delta; /* delta base object */ struct packed_git *in_pack; /* already in pack */ - unsigned int in_pack_offset; + off_t in_pack_offset; struct object_entry *delta_child; /* deltified objects who bases me */ struct object_entry *delta_sibling; /* other deltified objects who * uses the same base as me @@ -68,7 +68,7 @@ static int allow_ofs_delta; static struct object_entry **sorted_by_sha, **sorted_by_type; static struct object_entry *objects; -static int nr_objects, nr_alloc, nr_result; +static uint32_t nr_objects, nr_alloc, nr_result; static const char *base_name; static unsigned char pack_file_sha1[20]; static int progress = 1; @@ -101,7 +101,7 @@ static int object_ix_hashsz; * get the object sha1 from the main index. */ struct revindex_entry { - unsigned int offset; + off_t offset; unsigned int nr; }; struct pack_revindex { @@ -114,10 +114,8 @@ static int pack_revindex_hashsz; /* * stats */ -static int written; -static int written_delta; -static int reused; -static int reused_delta; +static uint32_t written, written_delta; +static uint32_t reused, reused_delta; static int pack_revindex_ix(struct packed_git *p) { @@ -168,11 +166,12 @@ static void prepare_pack_revindex(struct pack_revindex *rix) struct packed_git *p = rix->p; int num_ent = num_packed_objects(p); int i; - void *index = p->index_base + 256; + const char *index = p->index_data; + index += 4 * 256; rix->revindex = xmalloc(sizeof(*rix->revindex) * (num_ent + 1)); for (i = 0; i < num_ent; i++) { - unsigned int hl = *((unsigned int *)((char *) index + 24*i)); + uint32_t hl = *((uint32_t *)(index + 24 * i)); rix->revindex[i].offset = ntohl(hl); rix->revindex[i].nr = i; } @@ -185,7 +184,7 @@ static void prepare_pack_revindex(struct pack_revindex *rix) } static struct revindex_entry * find_packed_object(struct packed_git *p, - unsigned int ofs) + off_t ofs) { int num; int lo, hi; @@ -213,25 +212,24 @@ static struct revindex_entry * find_packed_object(struct packed_git *p, die("internal error: pack revindex corrupt"); } -static unsigned long find_packed_object_size(struct packed_git *p, - unsigned long ofs) +static off_t find_packed_object_size(struct packed_git *p, off_t ofs) { struct revindex_entry *entry = find_packed_object(p, ofs); return entry[1].offset - ofs; } -static unsigned char *find_packed_object_name(struct packed_git *p, - unsigned long ofs) +static const unsigned char *find_packed_object_name(struct packed_git *p, + off_t ofs) { struct revindex_entry *entry = find_packed_object(p, ofs); - return (unsigned char *)(p->index_base + 256) + 24 * entry->nr + 4; + return nth_packed_object_sha1(p, entry->nr); } static void *delta_against(void *buf, unsigned long size, struct object_entry *entry) { unsigned long othersize, delta_size; - char type[10]; - void *otherbuf = read_sha1_file(entry->delta->sha1, type, &othersize); + enum object_type type; + void *otherbuf = read_sha1_file(entry->delta->sha1, &type, &othersize); void *delta_buf; if (!otherbuf) @@ -278,8 +276,8 @@ static int encode_header(enum object_type type, unsigned long size, unsigned cha */ static int check_pack_inflate(struct packed_git *p, struct pack_window **w_curs, - unsigned long offset, - unsigned long len, + off_t offset, + off_t len, unsigned long expect) { z_stream stream; @@ -305,8 +303,8 @@ static int check_pack_inflate(struct packed_git *p, static void copy_pack_data(struct sha1file *f, struct packed_git *p, struct pack_window **w_curs, - unsigned long offset, - unsigned long len) + off_t offset, + off_t len) { unsigned char *in; unsigned int avail; @@ -314,7 +312,7 @@ static void copy_pack_data(struct sha1file *f, while (len) { in = use_pack(p, w_curs, offset, &avail); if (avail > len) - avail = len; + avail = (unsigned int)len; sha1write(f, in, avail); offset += avail; len -= avail; @@ -371,14 +369,15 @@ static int revalidate_loose_object(struct object_entry *entry, return check_loose_inflate(map, mapsize, size); } -static unsigned long write_object(struct sha1file *f, +static off_t write_object(struct sha1file *f, struct object_entry *entry) { unsigned long size; - char type[10]; + enum object_type type; void *buf; unsigned char header[10]; - unsigned hdrlen, datalen; + unsigned hdrlen; + off_t datalen; enum object_type obj_type; int to_reuse = 0; @@ -416,7 +415,7 @@ static unsigned long write_object(struct sha1file *f, } if (!to_reuse) { - buf = read_sha1_file(entry->sha1, type, &size); + buf = read_sha1_file(entry->sha1, &type, &size); if (!buf) die("unable to read %s", sha1_to_hex(entry->sha1)); if (size != entry->size) @@ -441,7 +440,7 @@ static unsigned long write_object(struct sha1file *f, * encoding of the relative offset for the delta * base from this object's position in the pack. */ - unsigned long ofs = entry->offset - entry->delta->offset; + off_t ofs = entry->offset - entry->delta->offset; unsigned pos = sizeof(header) - 1; header[pos] = ofs & 127; while (ofs >>= 7) @@ -462,7 +461,7 @@ static unsigned long write_object(struct sha1file *f, else { struct packed_git *p = entry->in_pack; struct pack_window *w_curs = NULL; - unsigned long offset; + off_t offset; if (entry->delta) { obj_type = (allow_ofs_delta && entry->delta->offset) ? @@ -472,7 +471,7 @@ static unsigned long write_object(struct sha1file *f, hdrlen = encode_header(obj_type, entry->size, header); sha1write(f, header, hdrlen); if (obj_type == OBJ_OFS_DELTA) { - unsigned long ofs = entry->offset - entry->delta->offset; + off_t ofs = entry->offset - entry->delta->offset; unsigned pos = sizeof(header) - 1; header[pos] = ofs & 127; while (ofs >>= 7) @@ -500,9 +499,9 @@ static unsigned long write_object(struct sha1file *f, return hdrlen + datalen; } -static unsigned long write_one(struct sha1file *f, +static off_t write_one(struct sha1file *f, struct object_entry *e, - unsigned long offset) + off_t offset) { if (e->offset || e->preferred_base) /* offset starts from header size and cannot be zero @@ -518,9 +517,9 @@ static unsigned long write_one(struct sha1file *f, static void write_pack_file(void) { - int i; + uint32_t i; struct sha1file *f; - unsigned long offset; + off_t offset; struct pack_header hdr; unsigned last_percent = 999; int do_progress = progress; @@ -533,7 +532,7 @@ static void write_pack_file(void) f = sha1create("%s-%s.%s", base_name, sha1_to_hex(object_list_sha1), "pack"); if (do_progress) - fprintf(stderr, "Writing %d objects.\n", nr_result); + fprintf(stderr, "Writing %u objects.\n", nr_result); hdr.hdr_signature = htonl(PACK_SIGNATURE); hdr.hdr_version = htonl(PACK_VERSION); @@ -558,13 +557,13 @@ static void write_pack_file(void) fputc('\n', stderr); done: if (written != nr_result) - die("wrote %d objects while expecting %d", written, nr_result); + die("wrote %u objects while expecting %u", written, nr_result); sha1close(f, pack_file_sha1, 1); } static void write_index_file(void) { - int i; + uint32_t i; struct sha1file *f = sha1create("%s-%s.%s", base_name, sha1_to_hex(object_list_sha1), "idx"); struct object_entry **list = sorted_by_sha; @@ -633,7 +632,7 @@ static struct object_entry *locate_object_entry(const unsigned char *sha1) static void rehash_objects(void) { - int i; + uint32_t i; struct object_entry *oe; object_ix_hashsz = nr_objects * 3; @@ -670,16 +669,16 @@ static unsigned name_hash(const char *name) static int add_object_entry(const unsigned char *sha1, unsigned hash, int exclude) { - unsigned int idx = nr_objects; + uint32_t idx = nr_objects; struct object_entry *entry; struct packed_git *p; - unsigned int found_offset = 0; + off_t found_offset = 0; struct packed_git *found_pack = NULL; int ix, status = 0; if (!exclude) { for (p = packed_git; p; p = p->next) { - unsigned long offset = find_pack_entry_one(sha1, p); + off_t offset = find_pack_entry_one(sha1, p); if (offset) { if (incremental) return 0; @@ -696,9 +695,8 @@ static int add_object_entry(const unsigned char *sha1, unsigned hash, int exclud goto already_added; if (idx >= nr_alloc) { - unsigned int needed = (idx + 1024) * 3 / 2; - objects = xrealloc(objects, needed * sizeof(*entry)); - nr_alloc = needed; + nr_alloc = (idx + 1024) * 3 / 2; + objects = xrealloc(objects, nr_alloc * sizeof(*entry)); } entry = objects + idx; nr_objects = idx + 1; @@ -718,7 +716,7 @@ static int add_object_entry(const unsigned char *sha1, unsigned hash, int exclud already_added: if (progress_update) { - fprintf(stderr, "Counting objects...%d\r", nr_objects); + fprintf(stderr, "Counting objects...%u\r", nr_objects); progress_update = 0; } if (exclude) @@ -765,7 +763,7 @@ static struct pbase_tree_cache *pbase_tree_get(const unsigned char *sha1) struct pbase_tree_cache *ent, *nent; void *data; unsigned long size; - char type[20]; + enum object_type type; int neigh; int my_ix = pbase_tree_cache_ix(sha1); int available_ix = -1; @@ -792,10 +790,10 @@ static struct pbase_tree_cache *pbase_tree_get(const unsigned char *sha1) /* Did not find one. Either we got a bogus request or * we need to read and perhaps cache. */ - data = read_sha1_file(sha1, type, &size); + data = read_sha1_file(sha1, &type, &size); if (!data) return NULL; - if (strcmp(type, tree_type)) { + if (type != OBJ_TREE) { free(data); return NULL; } @@ -854,19 +852,19 @@ static void add_pbase_object(struct tree_desc *tree, while (tree_entry(tree,&entry)) { unsigned long size; - char type[20]; + enum object_type type; - if (entry.pathlen != cmplen || + if (tree_entry_len(entry.path, entry.sha1) != cmplen || memcmp(entry.path, name, cmplen) || !has_sha1_file(entry.sha1) || - sha1_object_info(entry.sha1, type, &size)) + (type = sha1_object_info(entry.sha1, &size)) < 0) continue; if (name[cmplen] != '/') { unsigned hash = name_hash(fullname); add_object_entry(entry.sha1, hash, 1); return; } - if (!strcmp(type, tree_type)) { + if (type == OBJ_TREE) { struct tree_desc sub; struct pbase_tree_cache *tree; const char *down = name+cmplen+1; @@ -875,8 +873,7 @@ static void add_pbase_object(struct tree_desc *tree, tree = pbase_tree_get(entry.sha1); if (!tree) return; - sub.buf = tree->tree_data; - sub.size = tree->tree_size; + init_tree_desc(&sub, tree->tree_data, tree->tree_size); add_pbase_object(&sub, down, downlen, fullname); pbase_tree_put(tree); @@ -939,8 +936,7 @@ static void add_preferred_base_object(const char *name, unsigned hash) } else { struct tree_desc tree; - tree.buf = it->pcache.tree_data; - tree.size = it->pcache.tree_size; + init_tree_desc(&tree, it->pcache.tree_data, it->pcache.tree_size); add_pbase_object(&tree, name, cmplen, name); } } @@ -978,22 +974,20 @@ static void add_preferred_base(unsigned char *sha1) static void check_object(struct object_entry *entry) { - char type[20]; - if (entry->in_pack && !entry->preferred_base) { struct packed_git *p = entry->in_pack; struct pack_window *w_curs = NULL; - unsigned long left = p->pack_size - entry->in_pack_offset; unsigned long size, used; + unsigned int avail; unsigned char *buf; struct object_entry *base_entry = NULL; - buf = use_pack(p, &w_curs, entry->in_pack_offset, NULL); + buf = use_pack(p, &w_curs, entry->in_pack_offset, &avail); /* We want in_pack_type even if we do not reuse delta. * There is no point not reusing non-delta representations. */ - used = unpack_object_header_gently(buf, left, + used = unpack_object_header_gently(buf, avail, &entry->in_pack_type, &size); /* Check if it is delta, and the base is also an object @@ -1001,8 +995,9 @@ static void check_object(struct object_entry *entry) * delta. */ if (!no_reuse_delta) { - unsigned char c, *base_name; - unsigned long ofs; + unsigned char c; + const unsigned char *base_name; + off_t ofs; unsigned long used_0; /* there is at least 20 bytes left in the pack */ switch (entry->in_pack_type) { @@ -1062,21 +1057,10 @@ static void check_object(struct object_entry *entry) /* Otherwise we would do the usual */ } - if (sha1_object_info(entry->sha1, type, &entry->size)) + entry->type = sha1_object_info(entry->sha1, &entry->size); + if (entry->type < 0) die("unable to get type of object %s", sha1_to_hex(entry->sha1)); - - if (!strcmp(type, commit_type)) { - entry->type = OBJ_COMMIT; - } else if (!strcmp(type, tree_type)) { - entry->type = OBJ_TREE; - } else if (!strcmp(type, blob_type)) { - entry->type = OBJ_BLOB; - } else if (!strcmp(type, tag_type)) { - entry->type = OBJ_TAG; - } else - die("unable to pack object %s of type %s", - sha1_to_hex(entry->sha1), type); } static unsigned int check_delta_limit(struct object_entry *me, unsigned int n) @@ -1094,7 +1078,7 @@ static unsigned int check_delta_limit(struct object_entry *me, unsigned int n) static void get_object_details(void) { - int i; + uint32_t i; struct object_entry *entry; prepare_pack_ix(); @@ -1133,7 +1117,7 @@ static int sort_comparator(const void *_a, const void *_b) static struct object_entry **create_sorted_list(entry_sort_t sort) { struct object_entry **list = xmalloc(nr_objects * sizeof(struct object_entry *)); - int i; + uint32_t i; for (i = 0; i < nr_objects; i++) list[i] = objects + i; @@ -1150,7 +1134,7 @@ static int sha1_sort(const struct object_entry *a, const struct object_entry *b) static struct object_entry **create_final_object_list(void) { struct object_entry **list; - int i, j; + uint32_t i, j; for (i = nr_result = 0; i < nr_objects; i++) if (!objects[i].preferred_base) @@ -1206,7 +1190,7 @@ static int try_delta(struct unpacked *trg, struct unpacked *src, struct object_entry *trg_entry = trg->entry; struct object_entry *src_entry = src->entry; unsigned long trg_size, src_size, delta_size, sizediff, max_size, sz; - char type[10]; + enum object_type type; void *delta_buf; /* Don't bother doing diffs between different types */ @@ -1257,13 +1241,13 @@ static int try_delta(struct unpacked *trg, struct unpacked *src, /* Load data if not already done */ if (!trg->data) { - trg->data = read_sha1_file(trg_entry->sha1, type, &sz); + trg->data = read_sha1_file(trg_entry->sha1, &type, &sz); if (sz != trg_size) die("object %s inconsistent object length (%lu vs %lu)", sha1_to_hex(trg_entry->sha1), sz, trg_size); } if (!src->data) { - src->data = read_sha1_file(src_entry->sha1, type, &sz); + src->data = read_sha1_file(src_entry->sha1, &type, &sz); if (sz != src_size) die("object %s inconsistent object length (%lu vs %lu)", sha1_to_hex(src_entry->sha1), sz, src_size); @@ -1292,20 +1276,20 @@ static void progress_interval(int signum) static void find_deltas(struct object_entry **list, int window, int depth) { - int i, idx; + uint32_t i = nr_objects, idx = 0, processed = 0; unsigned int array_size = window * sizeof(struct unpacked); - struct unpacked *array = xmalloc(array_size); - unsigned processed = 0; + struct unpacked *array; unsigned last_percent = 999; + if (!nr_objects) + return; + array = xmalloc(array_size); memset(array, 0, array_size); - i = nr_objects; - idx = 0; if (progress) - fprintf(stderr, "Deltifying %d objects.\n", nr_result); + fprintf(stderr, "Deltifying %u objects.\n", nr_result); - while (--i >= 0) { - struct object_entry *entry = list[i]; + do { + struct object_entry *entry = list[--i]; struct unpacked *n = array + idx; int j; @@ -1338,7 +1322,7 @@ static void find_deltas(struct object_entry **list, int window, int depth) j = window; while (--j > 0) { - unsigned int other_idx = idx + j; + uint32_t other_idx = idx + j; struct unpacked *m; if (other_idx >= window) other_idx -= window; @@ -1358,7 +1342,7 @@ static void find_deltas(struct object_entry **list, int window, int depth) idx++; if (idx >= window) idx = 0; - } + } while (i > 0); if (progress) fputc('\n', stderr); @@ -1399,7 +1383,7 @@ static int reuse_cached_pack(unsigned char *sha1) } if (progress) - fprintf(stderr, "Reusing %d objects pack %s\n", nr_objects, + fprintf(stderr, "Reusing %u objects pack %s\n", nr_objects, sha1_to_hex(sha1)); if (pack_to_stdout) { @@ -1550,10 +1534,13 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix) struct object_entry **list; int use_internal_rev_list = 0; int thin = 0; - int i; - const char *rp_av[64]; + uint32_t i; + const char **rp_av; + int rp_ac_alloc = 64; int rp_ac; + rp_av = xcalloc(rp_ac_alloc, sizeof(*rp_av)); + rp_av[0] = "pack-objects"; rp_av[1] = "--objects"; /* --thin will make it --objects-edge */ rp_ac = 2; @@ -1626,8 +1613,11 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix) !strcmp("--reflog", arg) || !strcmp("--all", arg)) { use_internal_rev_list = 1; - if (ARRAY_SIZE(rp_av) - 1 <= rp_ac) - die("too many internal rev-list options"); + if (rp_ac >= rp_ac_alloc - 1) { + rp_ac_alloc = alloc_nr(rp_ac_alloc); + rp_av = xrealloc(rp_av, + rp_ac_alloc * sizeof(*rp_av)); + } rp_av[rp_ac++] = arg; continue; } @@ -1677,7 +1667,7 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix) } if (progress) - fprintf(stderr, "Done counting %d objects.\n", nr_objects); + fprintf(stderr, "Done counting %u objects.\n", nr_objects); sorted_by_sha = create_final_object_list(); if (non_empty && !nr_result) return 0; @@ -1690,7 +1680,7 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix) } SHA1_Final(object_list_sha1, &ctx); if (progress && (nr_objects != nr_result)) - fprintf(stderr, "Result has %d objects.\n", nr_result); + fprintf(stderr, "Result has %u objects.\n", nr_result); if (reuse_cached_pack(object_list_sha1)) ; @@ -1711,7 +1701,7 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix) } } if (progress) - fprintf(stderr, "Total %d (delta %d), reused %d (delta %d)\n", + fprintf(stderr, "Total %u (delta %u), reused %u (delta %u)\n", written, written_delta, reused, reused_delta); return 0; }