am -i, git-svn: use "git var GIT_PAGER"
[gitweb.git] / pack-redundant.c
index 40e579b2d9788bb0867b345c3596b1ad1539272a..69a7ab2e27d39ecabca5c0cc25c4e372caafb46c 100644 (file)
@@ -7,11 +7,12 @@
 */
 
 #include "cache.h"
+#include "exec_cmd.h"
 
 #define BLKSIZE 512
 
 static const char pack_redundant_usage[] =
-"git-pack-redundant [ --verbose ] [ --alt-odb ] < --all | <.pack filename> ...>";
+"git pack-redundant [ --verbose ] [ --alt-odb ] < --all | <.pack filename> ...>";
 
 static int load_all_packs, verbose, alt_odb;
 
@@ -54,16 +55,15 @@ static inline struct llist_item *llist_item_get(void)
        } else {
                int i = 1;
                new = xmalloc(sizeof(struct llist_item) * BLKSIZE);
-               for(;i < BLKSIZE; i++) {
+               for (; i < BLKSIZE; i++)
                        llist_item_put(&new[i]);
-               }
        }
        return new;
 }
 
 static void llist_free(struct llist *list)
 {
-       while((list->back = list->front)) {
+       while ((list->back = list->front)) {
                list->front = list->front->next;
                llist_item_put(list->back);
        }
@@ -81,7 +81,7 @@ static struct llist * llist_copy(struct llist *list)
 {
        struct llist *ret;
        struct llist_item *new, *old, *prev;
-       
+
        llist_init(&ret);
 
        if ((ret->size = list->size) == 0)
@@ -100,7 +100,7 @@ static struct llist * llist_copy(struct llist *list)
        }
        new->next = NULL;
        ret->back = new;
-       
+
        return ret;
 }
 
@@ -145,7 +145,7 @@ static inline struct llist_item *llist_insert_sorted_unique(struct llist *list,
                if (cmp > 0) { /* we insert before this entry */
                        return llist_insert(list, prev, sha1);
                }
-               if(!cmp) { /* already exists */
+               if (!cmp) { /* already exists */
                        return l;
                }
                prev = l;
@@ -167,7 +167,7 @@ static inline struct llist_item * llist_sorted_remove(struct llist *list, const
                int cmp = hashcmp(l->sha1, sha1);
                if (cmp > 0) /* not in list, since sorted */
                        return prev;
-               if(!cmp) { /* found */
+               if (!cmp) { /* found */
                        if (prev == NULL) {
                                if (hint != NULL && hint != list->front) {
                                        /* we don't know the previous element */
@@ -217,7 +217,7 @@ static inline struct pack_list * pack_list_insert(struct pack_list **pl,
 static inline size_t pack_list_size(struct pack_list *pl)
 {
        size_t ret = 0;
-       while(pl) {
+       while (pl) {
                ret++;
                pl = pl->next;
        }
@@ -247,16 +247,19 @@ static struct pack_list * pack_list_difference(const struct pack_list *A,
 
 static void cmp_two_packs(struct pack_list *p1, struct pack_list *p2)
 {
-       int p1_off, p2_off;
+       unsigned long p1_off = 0, p2_off = 0, p1_step, p2_step;
        const unsigned char *p1_base, *p2_base;
        struct llist_item *p1_hint = NULL, *p2_hint = NULL;
 
-       p1_off = p2_off = 256 * 4 + 4;
        p1_base = p1->pack->index_data;
        p2_base = p2->pack->index_data;
+       p1_base += 256 * 4 + ((p1->pack->index_version < 2) ? 4 : 8);
+       p2_base += 256 * 4 + ((p2->pack->index_version < 2) ? 4 : 8);
+       p1_step = (p1->pack->index_version < 2) ? 24 : 20;
+       p2_step = (p2->pack->index_version < 2) ? 24 : 20;
 
-       while (p1_off <= p1->pack->index_size - 3 * 20 &&
-              p2_off <= p2->pack->index_size - 3 * 20)
+       while (p1_off < p1->pack->num_objects * p1_step &&
+              p2_off < p2->pack->num_objects * p2_step)
        {
                int cmp = hashcmp(p1_base + p1_off, p2_base + p2_off);
                /* cmp ~ p1 - p2 */
@@ -265,14 +268,14 @@ static void cmp_two_packs(struct pack_list *p1, struct pack_list *p2)
                                        p1_base + p1_off, p1_hint);
                        p2_hint = llist_sorted_remove(p2->unique_objects,
                                        p1_base + p1_off, p2_hint);
-                       p1_off+=24;
-                       p2_off+=24;
+                       p1_off += p1_step;
+                       p2_off += p2_step;
                        continue;
                }
                if (cmp < 0) { /* p1 has the object, p2 doesn't */
-                       p1_off+=24;
+                       p1_off += p1_step;
                } else { /* p2 has the object, p1 doesn't */
-                       p2_off+=24;
+                       p2_off += p2_step;
                }
        }
 }
@@ -352,28 +355,31 @@ static int is_superset(struct pack_list *pl, struct llist *list)
 static size_t sizeof_union(struct packed_git *p1, struct packed_git *p2)
 {
        size_t ret = 0;
-       int p1_off, p2_off;
+       unsigned long p1_off = 0, p2_off = 0, p1_step, p2_step;
        const unsigned char *p1_base, *p2_base;
 
-       p1_off = p2_off = 256 * 4 + 4;
        p1_base = p1->index_data;
        p2_base = p2->index_data;
+       p1_base += 256 * 4 + ((p1->index_version < 2) ? 4 : 8);
+       p2_base += 256 * 4 + ((p2->index_version < 2) ? 4 : 8);
+       p1_step = (p1->index_version < 2) ? 24 : 20;
+       p2_step = (p2->index_version < 2) ? 24 : 20;
 
-       while (p1_off <= p1->index_size - 3 * 20 &&
-              p2_off <= p2->index_size - 3 * 20)
+       while (p1_off < p1->num_objects * p1_step &&
+              p2_off < p2->num_objects * p2_step)
        {
                int cmp = hashcmp(p1_base + p1_off, p2_base + p2_off);
                /* cmp ~ p1 - p2 */
                if (cmp == 0) {
                        ret++;
-                       p1_off+=24;
-                       p2_off+=24;
+                       p1_off += p1_step;
+                       p2_off += p2_step;
                        continue;
                }
                if (cmp < 0) { /* p1 has the object, p2 doesn't */
-                       p1_off+=24;
+                       p1_off += p1_step;
                } else { /* p2 has the object, p1 doesn't */
-                       p2_off+=24;
+                       p2_off += p2_step;
                }
        }
        return ret;
@@ -389,7 +395,7 @@ static size_t get_pack_redundancy(struct pack_list *pl)
                return 0;
 
        while ((subset = pl->next)) {
-               while(subset) {
+               while (subset) {
                        ret += sizeof_union(pl->pack, subset->pack);
                        subset = subset->next;
                }
@@ -420,7 +426,7 @@ static void minimize(struct pack_list **min)
 
        pl = local_packs;
        while (pl) {
-               if(pl->unique_objects->size)
+               if (pl->unique_objects->size)
                        pack_list_insert(&unique, pl);
                else
                        pack_list_insert(&non_unique, pl);
@@ -457,7 +463,7 @@ static void minimize(struct pack_list **min)
                pll_free(perm_all);
        }
        if (perm_ok == NULL)
-               die("Internal error: No complete sets found!\n");
+               die("Internal error: No complete sets found!");
 
        /* find the permutation with the smallest size */
        perm = perm_ok;
@@ -472,7 +478,7 @@ static void minimize(struct pack_list **min)
        *min = min_perm;
        /* add the unique packs to the list */
        pl = unique;
-       while(pl) {
+       while (pl) {
                pack_list_insert(min, pl);
                pl = pl->next;
        }
@@ -509,7 +515,7 @@ static void cmp_local_packs(void)
        struct pack_list *subset, *pl = local_packs;
 
        while ((subset = pl)) {
-               while((subset = subset->next))
+               while ((subset = subset->next))
                        cmp_two_packs(pl, subset);
                pl = pl->next;
        }
@@ -535,7 +541,7 @@ static void scan_alt_odb_packs(void)
 static struct pack_list * add_pack(struct packed_git *p)
 {
        struct pack_list l;
-       size_t off;
+       unsigned long off = 0, step;
        const unsigned char *base;
 
        if (!p->pack_local && !(alt_odb || verbose))
@@ -544,11 +550,15 @@ static struct pack_list * add_pack(struct packed_git *p)
        l.pack = p;
        llist_init(&l.all_objects);
 
-       off = 256 * 4 + 4;
+       if (open_pack_index(p))
+               return NULL;
+
        base = p->index_data;
-       while (off <= p->index_size - 3 * 20) {
+       base += 256 * 4 + ((p->index_version < 2) ? 4 : 8);
+       step = (p->index_version < 2) ? 24 : 20;
+       while (off < p->num_objects * step) {
                llist_insert_back(l.all_objects, base + off);
-               off += 24;
+               off += step;
        }
        /* this list will be pruned in cmp_two_packs later */
        l.unique_objects = llist_copy(l.all_objects);
@@ -563,14 +573,14 @@ static struct pack_list * add_pack_file(char *filename)
        struct packed_git *p = packed_git;
 
        if (strlen(filename) < 40)
-               die("Bad pack filename: %s\n", filename);
+               die("Bad pack filename: %s", filename);
 
        while (p) {
                if (strstr(p->pack_name, filename))
                        return add_pack(p);
                p = p->next;
        }
-       die("Filename %s not found in packed_git\n", filename);
+       die("Filename %s not found in packed_git", filename);
 }
 
 static void load_all(void)
@@ -591,27 +601,29 @@ int main(int argc, char **argv)
        unsigned char *sha1;
        char buf[42]; /* 40 byte sha1 + \n + \0 */
 
+       git_extract_argv0_path(argv[0]);
+
        setup_git_directory();
 
        for (i = 1; i < argc; i++) {
                const char *arg = argv[i];
-               if(!strcmp(arg, "--")) {
+               if (!strcmp(arg, "--")) {
                        i++;
                        break;
                }
-               if(!strcmp(arg, "--all")) {
+               if (!strcmp(arg, "--all")) {
                        load_all_packs = 1;
                        continue;
                }
-               if(!strcmp(arg, "--verbose")) {
+               if (!strcmp(arg, "--verbose")) {
                        verbose = 1;
                        continue;
                }
-               if(!strcmp(arg, "--alt-odb")) {
+               if (!strcmp(arg, "--alt-odb")) {
                        alt_odb = 1;
                        continue;
                }
-               if(*arg == '-')
+               if (*arg == '-')
                        usage(pack_redundant_usage);
                else
                        break;
@@ -626,7 +638,7 @@ int main(int argc, char **argv)
                        add_pack_file(*(argv + i++));
 
        if (local_packs == NULL)
-               die("Zero packs found!\n");
+               die("Zero packs found!");
 
        load_all_objects();