static int find_short_packed_object(int len, const unsigned char *match, unsigned char *sha1) { struct packed_git *p; unsigned char found_sha1[20]; int found = 0; prepare_packed_git(); for (p = packed_git; p && found < 2; p = p->next) { unsigned num = num_packed_objects(p); unsigned first = 0, last = num; while (first < last) { unsigned mid = (first + last) / 2; unsigned char now[20]; int cmp; nth_packed_object_sha1(p, mid, now); cmp = memcmp(match, now, 20); if (!cmp) { first = mid; break; } if (cmp > 0) { first = mid+1; continue; } last = mid; } if (first < num) { unsigned char now[20], next[20]; nth_packed_object_sha1(p, first, now); if (match_sha(len, match, now)) { if (nth_packed_object_sha1(p, first+1, next) || !match_sha(len, match, next)) { /* unique within this pack */ if (!found) { memcpy(found_sha1, now, 20); found++; } else if (memcmp(found_sha1, now, 20)) { found = 2; break; } } else { /* not even unique within this pack */ found = 2; break; } } } } if (found == 1) memcpy(sha1, found_sha1, 20); return found; }
static void show_pack_info(struct packed_git *p, unsigned int flags) { uint32_t nr_objects, i; int cnt; int stat_only = flags & VERIFY_PACK_STAT_ONLY; unsigned long chain_histogram[MAX_CHAIN+1], baseobjects; nr_objects = p->num_objects; memset(chain_histogram, 0, sizeof(chain_histogram)); baseobjects = 0; for (i = 0; i < nr_objects; i++) { const unsigned char *sha1; unsigned char base_sha1[20]; const char *type; unsigned long size; unsigned long store_size; off_t offset; unsigned int delta_chain_length; sha1 = nth_packed_object_sha1(p, i); if (!sha1) die("internal error pack-check nth-packed-object"); offset = nth_packed_object_offset(p, i); type = packed_object_info_detail(p, offset, &size, &store_size, &delta_chain_length, base_sha1); if (!stat_only) printf("%s ", sha1_to_hex(sha1)); if (!delta_chain_length) { if (!stat_only) printf("%-6s %lu %lu %"PRIuMAX"\n", type, size, store_size, (uintmax_t)offset); baseobjects++; } else { if (!stat_only) printf("%-6s %lu %lu %"PRIuMAX" %u %s\n", type, size, store_size, (uintmax_t)offset, delta_chain_length, sha1_to_hex(base_sha1)); if (delta_chain_length <= MAX_CHAIN) chain_histogram[delta_chain_length]++; else chain_histogram[0]++; } } if (baseobjects) printf("non delta: %lu object%s\n", baseobjects, baseobjects > 1 ? "s" : ""); for (cnt = 1; cnt <= MAX_CHAIN; cnt++) { if (!chain_histogram[cnt]) continue; printf("chain length = %d: %lu object%s\n", cnt, chain_histogram[cnt], chain_histogram[cnt] > 1 ? "s" : ""); } if (chain_histogram[0]) printf("chain length > %d: %lu object%s\n", MAX_CHAIN, chain_histogram[0], chain_histogram[0] > 1 ? "s" : ""); }