Add `git svn blame' command
[gitweb.git] / builtin-pack-objects.c
index a39cb82c9beb5c44f59c459bfc6ac384b42b6b3c..acb05554d499598677bc1f0cec3b6ff37e796d88 100644 (file)
@@ -68,7 +68,7 @@ static int allow_ofs_delta;
 static const char *base_name;
 static int progress = 1;
 static int window = 10;
-static uint32_t pack_size_limit;
+static uint32_t pack_size_limit, pack_size_limit_cfg;
 static int depth = 50;
 static int delta_search_threads = 1;
 static int pack_to_stdout;
@@ -445,7 +445,7 @@ static unsigned long write_object(struct sha1file *f,
                        /* nothing */;
                deflateEnd(&stream);
                datalen = stream.total_out;
-               deflateEnd(&stream);
+
                /*
                 * The object header is a byte of 'type' followed by zero or
                 * more bytes of length.
@@ -1464,7 +1464,7 @@ static unsigned int check_delta_limit(struct object_entry *me, unsigned int n)
        return m;
 }
 
-static unsigned long free_unpacked(struct unpacked *n)
+static unsigned long free_unpacked_data(struct unpacked *n)
 {
        unsigned long freed_mem = sizeof_delta_index(n->index);
        free_delta_index(n->index);
@@ -1474,6 +1474,12 @@ static unsigned long free_unpacked(struct unpacked *n)
                free(n->data);
                n->data = NULL;
        }
+       return freed_mem;
+}
+
+static unsigned long free_unpacked(struct unpacked *n)
+{
+       unsigned long freed_mem = free_unpacked_data(n);
        n->entry = NULL;
        n->depth = 0;
        return freed_mem;
@@ -1514,7 +1520,7 @@ static void find_deltas(struct object_entry **list, unsigned *list_size,
                       mem_usage > window_memory_limit &&
                       count > 1) {
                        uint32_t tail = (idx + window - count) % window;
-                       mem_usage -= free_unpacked(array + tail);
+                       mem_usage -= free_unpacked_data(array + tail);
                        count--;
                }
 
@@ -1547,6 +1553,9 @@ static void find_deltas(struct object_entry **list, unsigned *list_size,
                        if (!m->entry)
                                break;
                        ret = try_delta(n, m, max_depth, &mem_usage);
+                       if (window_memory_limit &&
+                           mem_usage > window_memory_limit)
+                               mem_usage -= free_unpacked_data(m);
                        if (ret < 0)
                                break;
                        else if (ret > 0)
@@ -1672,7 +1681,8 @@ static void ll_find_deltas(struct object_entry **list, unsigned list_size,
                p[i].data_ready = 0;
 
                /* try to split chunks on "path" boundaries */
-               while (sub_size < list_size && list[sub_size]->hash &&
+               while (sub_size && sub_size < list_size &&
+                      list[sub_size]->hash &&
                       list[sub_size]->hash == list[sub_size-1]->hash)
                        sub_size++;
 
@@ -1866,6 +1876,10 @@ static int git_pack_config(const char *k, const char *v)
                        die("bad pack.indexversion=%d", pack_idx_default_version);
                return 0;
        }
+       if (!strcmp(k, "pack.packsizelimit")) {
+               pack_size_limit_cfg = git_config_ulong(k, v);
+               return 0;
+       }
        return git_default_config(k, v);
 }
 
@@ -2095,6 +2109,7 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
                }
                if (!prefixcmp(arg, "--max-pack-size=")) {
                        char *end;
+                       pack_size_limit_cfg = 0;
                        pack_size_limit = strtoul(arg+16, &end, 0) * 1024 * 1024;
                        if (!arg[16] || *end)
                                usage(pack_usage);
@@ -2219,6 +2234,9 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
        if (pack_to_stdout != !base_name)
                usage(pack_usage);
 
+       if (!pack_to_stdout && !pack_size_limit)
+               pack_size_limit = pack_size_limit_cfg;
+
        if (pack_to_stdout && pack_size_limit)
                die("--max-pack-size cannot be used to build a pack for transfer.");