pack-objects: pass length to check_pack_crc() without truncation
[gitweb.git] / builtin / pack-objects.c
index 4af92f113c8423aa4749d2ddb19be95e68d43c13..a3a98c57410b0a32ed85c87013f8bd682af3a75a 100644 (file)
@@ -25,8 +25,8 @@
 #include "argv-array.h"
 
 static const char *pack_usage[] = {
-       N_("git pack-objects --stdout [options...] [< ref-list | < object-list]"),
-       N_("git pack-objects [options...] base-name [< ref-list | < object-list]"),
+       N_("git pack-objects --stdout [<options>...] [< <ref-list> | < <object-list>]"),
+       N_("git pack-objects [<options>...] <base-name> [< <ref-list> | < <object-list>]"),
        NULL
 };
 
@@ -349,7 +349,7 @@ static unsigned long write_reuse_object(struct sha1file *f, struct object_entry
        struct revindex_entry *revidx;
        off_t offset;
        enum object_type type = entry->type;
-       unsigned long datalen;
+       off_t datalen;
        unsigned char header[10], dheader[10];
        unsigned hdrlen;
 
@@ -540,11 +540,11 @@ static enum write_one_status write_one(struct sha1file *f,
        return WRITE_ONE_WRITTEN;
 }
 
-static int mark_tagged(const char *path, const unsigned char *sha1, int flag,
+static int mark_tagged(const char *path, const struct object_id *oid, int flag,
                       void *cb_data)
 {
        unsigned char peeled[20];
-       struct object_entry *entry = packlist_find(&to_pack, sha1, NULL);
+       struct object_entry *entry = packlist_find(&to_pack, oid->hash, NULL);
 
        if (entry)
                entry->tagged = 1;
@@ -624,7 +624,7 @@ static struct object_entry **compute_write_order(void)
 {
        unsigned int i, wo_end, last_untagged;
 
-       struct object_entry **wo = xmalloc(to_pack.nr_objects * sizeof(*wo));
+       struct object_entry **wo;
        struct object_entry *objects = to_pack.objects;
 
        for (i = 0; i < to_pack.nr_objects; i++) {
@@ -657,6 +657,7 @@ static struct object_entry **compute_write_order(void)
         * Give the objects in the original recency order until
         * we see a tagged tip.
         */
+       ALLOC_ARRAY(wo, to_pack.nr_objects);
        for (i = wo_end = 0; i < to_pack.nr_objects; i++) {
                if (objects[i].tagged)
                        break;
@@ -758,6 +759,10 @@ static off_t write_reused_pack(struct sha1file *f)
        return reuse_packfile_offset - sizeof(struct pack_header);
 }
 
+static const char no_split_warning[] = N_(
+"disabling bitmap writing, packs are split due to pack.packSizeLimit"
+);
+
 static void write_pack_file(void)
 {
        uint32_t i = 0, j;
@@ -769,7 +774,7 @@ static void write_pack_file(void)
 
        if (progress > pack_to_stdout)
                progress_state = start_progress(_("Writing objects"), nr_result);
-       written_list = xmalloc(to_pack.nr_objects * sizeof(*written_list));
+       ALLOC_ARRAY(written_list, to_pack.nr_objects);
        write_order = compute_write_order();
 
        do {
@@ -812,7 +817,10 @@ static void write_pack_file(void)
                        fixup_pack_header_footer(fd, sha1, pack_tmp_name,
                                                 nr_written, sha1, offset);
                        close(fd);
-                       write_bitmap_index = 0;
+                       if (write_bitmap_index) {
+                               warning(_(no_split_warning));
+                               write_bitmap_index = 0;
+                       }
                }
 
                if (!pack_to_stdout) {
@@ -2097,14 +2105,14 @@ static void ll_find_deltas(struct object_entry **list, unsigned list_size,
 #define ll_find_deltas(l, s, w, d, p)  find_deltas(l, &s, w, d, p)
 #endif
 
-static int add_ref_tag(const char *path, const unsigned char *sha1, int flag, void *cb_data)
+static int add_ref_tag(const char *path, const struct object_id *oid, int flag, void *cb_data)
 {
-       unsigned char peeled[20];
+       struct object_id peeled;
 
        if (starts_with(path, "refs/tags/") && /* is a tag? */
-           !peel_ref(path, peeled)        && /* peelable? */
-           packlist_find(&to_pack, peeled, NULL))      /* object packed? */
-               add_object_entry(sha1, OBJ_TAG, NULL, 0);
+           !peel_ref(path, peeled.hash)    && /* peelable? */
+           packlist_find(&to_pack, peeled.hash, NULL))      /* object packed? */
+               add_object_entry(oid->hash, OBJ_TAG, NULL, 0);
        return 0;
 }
 
@@ -2129,7 +2137,7 @@ static void prepare_pack(int window, int depth)
        if (!to_pack.nr_objects || !window || !depth)
                return;
 
-       delta_list = xmalloc(to_pack.nr_objects * sizeof(*delta_list));
+       ALLOC_ARRAY(delta_list, to_pack.nr_objects);
        nr_deltas = n = 0;
 
        for (i = 0; i < to_pack.nr_objects; i++) {
@@ -2277,7 +2285,7 @@ static void read_object_list_from_stdin(void)
 
 static void show_commit(struct commit *commit, void *data)
 {
-       add_object_entry(commit->object.sha1, OBJ_COMMIT, NULL, 0);
+       add_object_entry(commit->object.oid.hash, OBJ_COMMIT, NULL, 0);
        commit->object.flags |= OBJECT_ADDED;
 
        if (write_bitmap_index)
@@ -2287,13 +2295,13 @@ static void show_commit(struct commit *commit, void *data)
 static void show_object(struct object *obj, const char *name, void *data)
 {
        add_preferred_base_object(name);
-       add_object_entry(obj->sha1, obj->type, name, 0);
+       add_object_entry(obj->oid.hash, obj->type, name, 0);
        obj->flags |= OBJECT_ADDED;
 }
 
 static void show_edge(struct commit *commit)
 {
-       add_preferred_base(commit->object.sha1);
+       add_preferred_base(commit->object.oid.hash);
 }
 
 struct in_pack_object {
@@ -2309,7 +2317,7 @@ struct in_pack {
 
 static void mark_in_pack_object(struct object *object, struct packed_git *p, struct in_pack *in_pack)
 {
-       in_pack->array[in_pack->nr].offset = find_pack_entry_one(object->sha1, p);
+       in_pack->array[in_pack->nr].offset = find_pack_entry_one(object->oid.hash, p);
        in_pack->array[in_pack->nr].object = object;
        in_pack->nr++;
 }
@@ -2328,7 +2336,7 @@ static int ofscmp(const void *a_, const void *b_)
        else if (a->offset > b->offset)
                return 1;
        else
-               return hashcmp(a->object->sha1, b->object->sha1);
+               return oidcmp(&a->object->oid, &b->object->oid);
 }
 
 static void add_objects_in_unpacked_packs(struct rev_info *revs)
@@ -2366,7 +2374,7 @@ static void add_objects_in_unpacked_packs(struct rev_info *revs)
                      ofscmp);
                for (i = 0; i < in_pack.nr; i++) {
                        struct object *o = in_pack.array[i].object;
-                       add_object_entry(o->sha1, o->type, "", 0);
+                       add_object_entry(o->oid.hash, o->type, "", 0);
                }
        }
        free(in_pack.array);
@@ -2473,12 +2481,12 @@ static void record_recent_object(struct object *obj,
                                 const char *name,
                                 void *data)
 {
-       sha1_array_append(&recent_objects, obj->sha1);
+       sha1_array_append(&recent_objects, obj->oid.hash);
 }
 
 static void record_recent_commit(struct commit *commit, void *data)
 {
-       sha1_array_append(&recent_objects, commit->object.sha1);
+       sha1_array_append(&recent_objects, commit->object.oid.hash);
 }
 
 static void get_object_list(int ac, const char **av)
@@ -2577,23 +2585,6 @@ static int option_parse_unpack_unreachable(const struct option *opt,
        return 0;
 }
 
-static int option_parse_ulong(const struct option *opt,
-                             const char *arg, int unset)
-{
-       if (unset)
-               die(_("option %s does not accept negative form"),
-                   opt->long_name);
-
-       if (!git_parse_ulong(arg, opt->value))
-               die(_("unable to parse value '%s' for option %s"),
-                   arg, opt->long_name);
-       return 0;
-}
-
-#define OPT_ULONG(s, l, v, h) \
-       { OPTION_CALLBACK, (s), (l), (v), "n", (h),     \
-         PARSE_OPT_NONEG, option_parse_ulong }
-
 int cmd_pack_objects(int argc, const char **argv, const char *prefix)
 {
        int use_internal_rev_list = 0;
@@ -2616,16 +2607,16 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
                { OPTION_CALLBACK, 0, "index-version", NULL, N_("version[,offset]"),
                  N_("write the pack index file in the specified idx format version"),
                  0, option_parse_index_version },
-               OPT_ULONG(0, "max-pack-size", &pack_size_limit,
-                         N_("maximum size of each output pack file")),
+               OPT_MAGNITUDE(0, "max-pack-size", &pack_size_limit,
+                             N_("maximum size of each output pack file")),
                OPT_BOOL(0, "local", &local,
                         N_("ignore borrowed objects from alternate object store")),
                OPT_BOOL(0, "incremental", &incremental,
                         N_("ignore packed objects")),
                OPT_INTEGER(0, "window", &window,
                            N_("limit pack window by objects")),
-               OPT_ULONG(0, "window-memory", &window_memory_limit,
-                         N_("limit pack window by memory in addition to object limit")),
+               OPT_MAGNITUDE(0, "window-memory", &window_memory_limit,
+                             N_("limit pack window by memory in addition to object limit")),
                OPT_INTEGER(0, "depth", &depth,
                            N_("maximum length of delta chain allowed in the resulting pack")),
                OPT_BOOL(0, "reuse-delta", &reuse_delta,