http: use xmalloc with cURL
[gitweb.git] / builtin / pack-objects.c
index 15f90afc34f49ec2fa5219864e12af169c2b7e7b..93e92876aa76378883471414c2a044edfa77eca4 100644 (file)
@@ -33,6 +33,7 @@
 #include "object-store.h"
 #include "dir.h"
 #include "midx.h"
+#include "trace2.h"
 
 #define IN_PACK(obj) oe_in_pack(&to_pack, obj)
 #define SIZE(obj) oe_size(&to_pack, obj)
@@ -95,8 +96,12 @@ static off_t reuse_packfile_offset;
 
 static int use_bitmap_index_default = 1;
 static int use_bitmap_index = -1;
-static int write_bitmap_index;
-static uint16_t write_bitmap_options;
+static enum {
+       WRITE_BITMAP_FALSE = 0,
+       WRITE_BITMAP_QUIET,
+       WRITE_BITMAP_TRUE,
+} write_bitmap_index;
+static uint16_t write_bitmap_options = BITMAP_OPT_HASH_CACHE;
 
 static int exclude_promisor_objects;
 
@@ -605,12 +610,12 @@ static int mark_tagged(const char *path, const struct object_id *oid, int flag,
                       void *cb_data)
 {
        struct object_id peeled;
-       struct object_entry *entry = packlist_find(&to_pack, oid->hash, NULL);
+       struct object_entry *entry = packlist_find(&to_pack, oid, NULL);
 
        if (entry)
                entry->tagged = 1;
        if (!peel_ref(path, &peeled)) {
-               entry = packlist_find(&to_pack, peeled.hash, NULL);
+               entry = packlist_find(&to_pack, &peeled, NULL);
                if (entry)
                        entry->tagged = 1;
        }
@@ -891,7 +896,8 @@ static void write_pack_file(void)
                                                 nr_written, oid.hash, offset);
                        close(fd);
                        if (write_bitmap_index) {
-                               warning(_(no_split_warning));
+                               if (write_bitmap_index != WRITE_BITMAP_QUIET)
+                                       warning(_(no_split_warning));
                                write_bitmap_index = 0;
                        }
                }
@@ -963,6 +969,8 @@ static void write_pack_file(void)
        if (written != nr_result)
                die(_("wrote %"PRIu32" objects while expecting %"PRIu32),
                    written, nr_result);
+       trace2_data_intmax("pack-objects", the_repository,
+                          "write_pack_file/wrote", nr_result);
 }
 
 static int no_try_delta(const char *path)
@@ -993,7 +1001,7 @@ static int have_duplicate_entry(const struct object_id *oid,
 {
        struct object_entry *entry;
 
-       entry = packlist_find(&to_pack, oid->hash, index_pos);
+       entry = packlist_find(&to_pack, oid, index_pos);
        if (!entry)
                return 0;
 
@@ -1077,7 +1085,7 @@ static int want_object_in_pack(const struct object_id *oid,
 
        for (m = get_multi_pack_index(the_repository); m; m = m->next) {
                struct pack_entry e;
-               if (fill_midx_entry(oid, &e, m)) {
+               if (fill_midx_entry(the_repository, oid, &e, m)) {
                        struct packed_git *p = e.p;
                        off_t offset;
 
@@ -1173,7 +1181,8 @@ static int add_object_entry(const struct object_id *oid, enum object_type type,
        if (!want_object_in_pack(oid, exclude, &found_pack, &found_offset)) {
                /* The pack is missing an object, so it will not have closure */
                if (write_bitmap_index) {
-                       warning(_(no_closure_warning));
+                       if (write_bitmap_index != WRITE_BITMAP_QUIET)
+                               warning(_(no_closure_warning));
                        write_bitmap_index = 0;
                }
                return 0;
@@ -1425,7 +1434,8 @@ static void add_preferred_base(struct object_id *oid)
        if (window <= num_preferred_base++)
                return;
 
-       data = read_object_with_reference(oid, tree_type, &size, &tree_oid);
+       data = read_object_with_reference(the_repository, oid,
+                                         tree_type, &size, &tree_oid);
        if (!data)
                return;
 
@@ -1486,15 +1496,18 @@ static int can_reuse_delta(const unsigned char *base_sha1,
                           struct object_entry **base_out)
 {
        struct object_entry *base;
+       struct object_id base_oid;
 
        if (!base_sha1)
                return 0;
 
+       oidread(&base_oid, base_sha1);
+
        /*
         * First see if we're already sending the base (or it's explicitly in
         * our "excluded" list).
         */
-       base = packlist_find(&to_pack, base_sha1, NULL);
+       base = packlist_find(&to_pack, &base_oid, NULL);
        if (base) {
                if (!in_same_island(&delta->idx.oid, &base->idx.oid))
                        return 0;
@@ -1507,10 +1520,8 @@ static int can_reuse_delta(const unsigned char *base_sha1,
         * even if it was buried too deep in history to make it into the
         * packing list.
         */
-       if (thin && bitmap_has_sha1_in_uninteresting(bitmap_git, base_sha1)) {
+       if (thin && bitmap_has_oid_in_uninteresting(bitmap_git, &base_oid)) {
                if (use_delta_islands) {
-                       struct object_id base_oid;
-                       hashcpy(base_oid.hash, base_sha1);
                        if (!in_same_island(&delta->idx.oid, &base_oid))
                                return 0;
                }
@@ -2331,15 +2342,6 @@ static void find_deltas(struct object_entry **list, unsigned *list_size,
        free(array);
 }
 
-static void try_to_free_from_threads(size_t size)
-{
-       packing_data_lock(&to_pack);
-       release_pack_memory(size);
-       packing_data_unlock(&to_pack);
-}
-
-static try_to_free_t old_try_to_free_routine;
-
 /*
  * The main object list is split into smaller lists, each is handed to
  * one worker.
@@ -2380,12 +2382,10 @@ static void init_threaded_search(void)
        pthread_mutex_init(&cache_mutex, NULL);
        pthread_mutex_init(&progress_mutex, NULL);
        pthread_cond_init(&progress_cond, NULL);
-       old_try_to_free_routine = set_try_to_free_routine(try_to_free_from_threads);
 }
 
 static void cleanup_threaded_search(void)
 {
-       set_try_to_free_routine(old_try_to_free_routine);
        pthread_cond_destroy(&progress_cond);
        pthread_mutex_destroy(&cache_mutex);
        pthread_mutex_destroy(&progress_mutex);
@@ -2568,7 +2568,7 @@ static void add_tag_chain(const struct object_id *oid)
         * it was included via bitmaps, we would not have parsed it
         * previously).
         */
-       if (packlist_find(&to_pack, oid->hash, NULL))
+       if (packlist_find(&to_pack, oid, NULL))
                return;
 
        tag = lookup_tag(the_repository, oid);
@@ -2592,7 +2592,7 @@ static int add_ref_tag(const char *path, const struct object_id *oid, int flag,
 
        if (starts_with(path, "refs/tags/") && /* is a tag? */
            !peel_ref(path, &peeled)    && /* peelable? */
-           packlist_find(&to_pack, peeled.hash, NULL))      /* object packed? */
+           packlist_find(&to_pack, &peeled, NULL))      /* object packed? */
                add_tag_chain(oid);
        return 0;
 }
@@ -2792,7 +2792,7 @@ static void show_object(struct object *obj, const char *name, void *data)
                for (p = strchr(name, '/'); p; p = strchr(p + 1, '/'))
                        depth++;
 
-               ent = packlist_find(&to_pack, obj->oid.hash, NULL);
+               ent = packlist_find(&to_pack, &obj->oid, NULL);
                if (ent && depth > oe_tree_depth(&to_pack, ent))
                        oe_set_tree_depth(&to_pack, ent, depth);
        }
@@ -2896,7 +2896,7 @@ static int ofscmp(const void *a_, const void *b_)
                return oidcmp(&a->object->oid, &b->object->oid);
 }
 
-static void add_objects_in_unpacked_packs(struct rev_info *revs)
+static void add_objects_in_unpacked_packs(void)
 {
        struct packed_git *p;
        struct in_pack in_pack;
@@ -2919,7 +2919,7 @@ static void add_objects_in_unpacked_packs(struct rev_info *revs)
 
                for (i = 0; i < p->num_objects; i++) {
                        nth_packed_object_oid(&oid, p, i);
-                       o = lookup_unknown_object(oid.hash);
+                       o = lookup_unknown_object(&oid);
                        if (!(o->flags & OBJECT_ADDED))
                                mark_in_pack_object(o, p, &in_pack);
                        o->flags |= OBJECT_ADDED;
@@ -3008,7 +3008,7 @@ static int loosened_object_can_be_discarded(const struct object_id *oid,
        return 1;
 }
 
-static void loosen_unused_packed_objects(struct rev_info *revs)
+static void loosen_unused_packed_objects(void)
 {
        struct packed_git *p;
        uint32_t i;
@@ -3023,7 +3023,7 @@ static void loosen_unused_packed_objects(struct rev_info *revs)
 
                for (i = 0; i < p->num_objects; i++) {
                        nth_packed_object_oid(&oid, p, i);
-                       if (!packlist_find(&to_pack, oid.hash, NULL) &&
+                       if (!packlist_find(&to_pack, &oid, NULL) &&
                            !has_sha1_pack_kept_or_nonlocal(&oid) &&
                            !loosened_object_can_be_discarded(&oid, p->mtime))
                                if (force_object_loose(&oid, p->mtime))
@@ -3155,11 +3155,11 @@ static void get_object_list(int ac, const char **av)
        }
 
        if (keep_unreachable)
-               add_objects_in_unpacked_packs(&revs);
+               add_objects_in_unpacked_packs();
        if (pack_loose_unreachable)
                add_unreachable_loose_objects();
        if (unpack_unreachable)
-               loosen_unused_packed_objects(&revs);
+               loosen_unused_packed_objects();
 
        oid_array_clear(&recent_objects);
 }
@@ -3308,8 +3308,13 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
                            N_("do not hide commits by grafts"), 0),
                OPT_BOOL(0, "use-bitmap-index", &use_bitmap_index,
                         N_("use a bitmap index if available to speed up counting objects")),
-               OPT_BOOL(0, "write-bitmap-index", &write_bitmap_index,
-                        N_("write a bitmap index together with the pack index")),
+               OPT_SET_INT(0, "write-bitmap-index", &write_bitmap_index,
+                           N_("write a bitmap index together with the pack index"),
+                           WRITE_BITMAP_TRUE),
+               OPT_SET_INT_F(0, "write-bitmap-index-quiet",
+                             &write_bitmap_index,
+                             N_("write a bitmap index if possible"),
+                             WRITE_BITMAP_QUIET, PARSE_OPT_HIDDEN),
                OPT_PARSE_LIST_OBJECTS_FILTER(&filter_options),
                { OPTION_CALLBACK, 0, "missing", NULL, N_("action"),
                  N_("handling for missing objects"), PARSE_OPT_NONEG,
@@ -3473,6 +3478,8 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
                }
        }
 
+       trace2_region_enter("pack-objects", "enumerate-objects",
+                           the_repository);
        prepare_packing_data(the_repository, &to_pack);
 
        if (progress)
@@ -3487,12 +3494,23 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
        if (include_tag && nr_result)
                for_each_ref(add_ref_tag, NULL);
        stop_progress(&progress_state);
+       trace2_region_leave("pack-objects", "enumerate-objects",
+                           the_repository);
 
        if (non_empty && !nr_result)
                return 0;
-       if (nr_result)
+       if (nr_result) {
+               trace2_region_enter("pack-objects", "prepare-pack",
+                                   the_repository);
                prepare_pack(window, depth);
+               trace2_region_leave("pack-objects", "prepare-pack",
+                                   the_repository);
+       }
+
+       trace2_region_enter("pack-objects", "write-pack-file", the_repository);
        write_pack_file();
+       trace2_region_leave("pack-objects", "write-pack-file", the_repository);
+
        if (progress)
                fprintf_ln(stderr,
                           _("Total %"PRIu32" (delta %"PRIu32"),"