branch: fix segfault when resolving an invalid HEAD
[gitweb.git] / pack-redundant.c
index 92a09ed36281b293a8c9002a33ab80f740949a37..40e579b2d9788bb0867b345c3596b1ad1539272a 100644 (file)
@@ -17,7 +17,7 @@ static int load_all_packs, verbose, alt_odb;
 
 struct llist_item {
        struct llist_item *next;
-       unsigned char *sha1;
+       const unsigned char *sha1;
 };
 static struct llist {
        struct llist_item *front;
@@ -104,9 +104,9 @@ static struct llist * llist_copy(struct llist *list)
        return ret;
 }
 
-static inline struct llist_item * llist_insert(struct llist *list,
-                                              struct llist_item *after,
-                                              unsigned char *sha1)
+static inline struct llist_item *llist_insert(struct llist *list,
+                                             struct llist_item *after,
+                                              const unsigned char *sha1)
 {
        struct llist_item *new = llist_item_get();
        new->sha1 = sha1;
@@ -128,18 +128,20 @@ static inline struct llist_item * llist_insert(struct llist *list,
        return new;
 }
 
-static inline struct llist_item *llist_insert_back(struct llist *list, unsigned char *sha1)
+static inline struct llist_item *llist_insert_back(struct llist *list,
+                                                  const unsigned char *sha1)
 {
        return llist_insert(list, list->back, sha1);
 }
 
-static inline struct llist_item *llist_insert_sorted_unique(struct llist *list, unsigned char *sha1, struct llist_item *hint)
+static inline struct llist_item *llist_insert_sorted_unique(struct llist *list,
+                       const unsigned char *sha1, struct llist_item *hint)
 {
        struct llist_item *prev = NULL, *l;
 
        l = (hint == NULL) ? list->front : hint;
        while (l) {
-               int cmp = memcmp(l->sha1, sha1, 20);
+               int cmp = hashcmp(l->sha1, sha1);
                if (cmp > 0) { /* we insert before this entry */
                        return llist_insert(list, prev, sha1);
                }
@@ -162,7 +164,7 @@ static inline struct llist_item * llist_sorted_remove(struct llist *list, const
        l = (hint == NULL) ? list->front : hint;
        prev = NULL;
        while (l) {
-               int cmp = memcmp(l->sha1, sha1, 20);
+               int cmp = hashcmp(l->sha1, sha1);
                if (cmp > 0) /* not in list, since sorted */
                        return prev;
                if(!cmp) { /* found */
@@ -246,17 +248,17 @@ 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 char *p1_base, *p2_base;
+       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 = (unsigned char *) p1->pack->index_base;
-       p2_base = (unsigned char *) p2->pack->index_base;
+       p1_base = p1->pack->index_data;
+       p2_base = p2->pack->index_data;
 
        while (p1_off <= p1->pack->index_size - 3 * 20 &&
               p2_off <= p2->pack->index_size - 3 * 20)
        {
-               int cmp = memcmp(p1_base + p1_off, p2_base + p2_off, 20);
+               int cmp = hashcmp(p1_base + p1_off, p2_base + p2_off);
                /* cmp ~ p1 - p2 */
                if (cmp == 0) {
                        p1_hint = llist_sorted_remove(p1->unique_objects,
@@ -351,16 +353,16 @@ static size_t sizeof_union(struct packed_git *p1, struct packed_git *p2)
 {
        size_t ret = 0;
        int p1_off, p2_off;
-       char *p1_base, *p2_base;
+       const unsigned char *p1_base, *p2_base;
 
        p1_off = p2_off = 256 * 4 + 4;
-       p1_base = (char *)p1->index_base;
-       p2_base = (char *)p2->index_base;
+       p1_base = p1->index_data;
+       p2_base = p2->index_data;
 
        while (p1_off <= p1->index_size - 3 * 20 &&
               p2_off <= p2->index_size - 3 * 20)
        {
-               int cmp = memcmp(p1_base + p1_off, p2_base + p2_off, 20);
+               int cmp = hashcmp(p1_base + p1_off, p2_base + p2_off);
                /* cmp ~ p1 - p2 */
                if (cmp == 0) {
                        ret++;
@@ -396,9 +398,9 @@ static size_t get_pack_redundancy(struct pack_list *pl)
        return ret;
 }
 
-static inline size_t pack_set_bytecount(struct pack_list *pl)
+static inline off_t pack_set_bytecount(struct pack_list *pl)
 {
-       size_t ret = 0;
+       off_t ret = 0;
        while (pl) {
                ret += pl->pack->pack_size;
                ret += pl->pack->index_size;
@@ -413,7 +415,7 @@ static void minimize(struct pack_list **min)
                *non_unique = NULL, *min_perm = NULL;
        struct pll *perm, *perm_all, *perm_ok = NULL, *new_perm;
        struct llist *missing;
-       size_t min_perm_size = (size_t)-1, perm_size;
+       off_t min_perm_size = 0, perm_size;
        int n;
 
        pl = local_packs;
@@ -461,7 +463,7 @@ static void minimize(struct pack_list **min)
        perm = perm_ok;
        while (perm) {
                perm_size = pack_set_bytecount(perm->pl);
-               if (min_perm_size > perm_size) {
+               if (!min_perm_size || min_perm_size > perm_size) {
                        min_perm_size = perm_size;
                        min_perm = perm->pl;
                }
@@ -534,7 +536,7 @@ static struct pack_list * add_pack(struct packed_git *p)
 {
        struct pack_list l;
        size_t off;
-       unsigned char *base;
+       const unsigned char *base;
 
        if (!p->pack_local && !(alt_odb || verbose))
                return NULL;
@@ -543,7 +545,7 @@ static struct pack_list * add_pack(struct packed_git *p)
        llist_init(&l.all_objects);
 
        off = 256 * 4 + 4;
-       base = (unsigned char *)p->index_base;
+       base = p->index_data;
        while (off <= p->index_size - 3 * 20) {
                llist_insert_back(l.all_objects, base + off);
                off += 24;