3 #include "pack-revindex.h"
7 const unsigned char *sha1
;
11 static int compare_entries(const void *e1
, const void *e2
)
13 const struct idx_entry
*entry1
= e1
;
14 const struct idx_entry
*entry2
= e2
;
15 if (entry1
->offset
< entry2
->offset
)
17 if (entry1
->offset
> entry2
->offset
)
22 static int verify_packfile(struct packed_git
*p
,
23 struct pack_window
**w_curs
)
25 off_t index_size
= p
->index_size
;
26 const unsigned char *index_base
= p
->index_data
;
28 unsigned char sha1
[20], *pack_sig
;
29 off_t offset
= 0, pack_sig_ofs
= p
->pack_size
- 20;
30 uint32_t nr_objects
, i
;
32 struct idx_entry
*entries
;
34 /* Note that the pack header checks are actually performed by
35 * use_pack when it first opens the pack file. If anything
36 * goes wrong during those checks then the call will die out
41 while (offset
< pack_sig_ofs
) {
42 unsigned int remaining
;
43 unsigned char *in
= use_pack(p
, w_curs
, offset
, &remaining
);
45 if (offset
> pack_sig_ofs
)
46 remaining
-= (unsigned int)(offset
- pack_sig_ofs
);
47 SHA1_Update(&ctx
, in
, remaining
);
49 SHA1_Final(sha1
, &ctx
);
50 pack_sig
= use_pack(p
, w_curs
, pack_sig_ofs
, NULL
);
51 if (hashcmp(sha1
, pack_sig
))
52 err
= error("%s SHA1 checksum mismatch",
54 if (hashcmp(index_base
+ index_size
- 40, pack_sig
))
55 err
= error("%s SHA1 does not match its inddex",
59 /* Make sure everything reachable from idx is valid. Since we
60 * have verified that nr_objects matches between idx and pack,
61 * we do not do scan-streaming check on the pack file.
63 nr_objects
= p
->num_objects
;
64 entries
= xmalloc(nr_objects
* sizeof(*entries
));
65 /* first sort entries by pack offset, since unpacking them is more efficient that way */
66 for (i
= 0; i
< nr_objects
; i
++) {
67 entries
[i
].sha1
= nth_packed_object_sha1(p
, i
);
69 die("internal error pack-check nth-packed-object");
70 entries
[i
].offset
= find_pack_entry_one(entries
[i
].sha1
, p
);
71 if (!entries
[i
].offset
)
72 die("internal error pack-check find-pack-entry-one");
74 qsort(entries
, nr_objects
, sizeof(*entries
), compare_entries
);
76 for (i
= 0; i
< nr_objects
; i
++) {
78 enum object_type type
;
81 data
= unpack_entry(p
, entries
[i
].offset
, &type
, &size
);
83 err
= error("cannot unpack %s from %s at offset %"PRIuMAX
"",
84 sha1_to_hex(entries
[i
].sha1
), p
->pack_name
,
85 (uintmax_t)entries
[i
].offset
);
88 if (check_sha1_signature(entries
[i
].sha1
, data
, size
, typename(type
))) {
89 err
= error("packed %s from %s is corrupt",
90 sha1_to_hex(entries
[i
].sha1
), p
->pack_name
);
104 static void show_pack_info(struct packed_git
*p
)
106 uint32_t nr_objects
, i
, chain_histogram
[MAX_CHAIN
+1];
108 nr_objects
= p
->num_objects
;
109 memset(chain_histogram
, 0, sizeof(chain_histogram
));
111 for (i
= 0; i
< nr_objects
; i
++) {
112 const unsigned char *sha1
;
113 unsigned char base_sha1
[20];
116 unsigned long store_size
;
118 unsigned int delta_chain_length
;
120 sha1
= nth_packed_object_sha1(p
, i
);
122 die("internal error pack-check nth-packed-object");
123 offset
= find_pack_entry_one(sha1
, p
);
125 die("internal error pack-check find-pack-entry-one");
127 type
= packed_object_info_detail(p
, offset
, &size
, &store_size
,
130 printf("%s ", sha1_to_hex(sha1
));
131 if (!delta_chain_length
)
132 printf("%-6s %lu %lu %"PRIuMAX
"\n",
133 type
, size
, store_size
, (uintmax_t)offset
);
135 printf("%-6s %lu %lu %"PRIuMAX
" %u %s\n",
136 type
, size
, store_size
, (uintmax_t)offset
,
137 delta_chain_length
, sha1_to_hex(base_sha1
));
138 if (delta_chain_length
<= MAX_CHAIN
)
139 chain_histogram
[delta_chain_length
]++;
141 chain_histogram
[0]++;
145 for (i
= 0; i
<= MAX_CHAIN
; i
++) {
146 if (!chain_histogram
[i
])
148 printf("chain length = %d: %d object%s\n", i
,
149 chain_histogram
[i
], chain_histogram
[i
] > 1 ? "s" : "");
151 if (chain_histogram
[0])
152 printf("chain length > %d: %d object%s\n", MAX_CHAIN
,
153 chain_histogram
[0], chain_histogram
[0] > 1 ? "s" : "");
156 int verify_pack(struct packed_git
*p
, int verbose
)
159 const unsigned char *index_base
;
161 unsigned char sha1
[20];
163 struct pack_window
*w_curs
= NULL
;
165 if (open_pack_index(p
))
166 return error("packfile %s index not opened", p
->pack_name
);
167 index_size
= p
->index_size
;
168 index_base
= p
->index_data
;
170 /* Verify SHA1 sum of the index file */
172 SHA1_Update(&ctx
, index_base
, (unsigned int)(index_size
- 20));
173 SHA1_Final(sha1
, &ctx
);
174 if (hashcmp(sha1
, index_base
+ index_size
- 20))
175 err
= error("Packfile index for %s SHA1 mismatch",
178 /* Verify pack file */
179 err
|= verify_packfile(p
, &w_curs
);
184 printf("%s: bad\n", p
->pack_name
);
187 printf("%s: ok\n", p
->pack_name
);