* First pass: * - find locations of all objects; * - calculate SHA1 of all non-delta objects; * - remember base (SHA1 or offset) for all deltas. */
| 1248 | * - remember base (SHA1 or offset) for all deltas. |
| 1249 | */ |
| 1250 | static void parse_pack_objects(unsigned char *hash) |
| 1251 | { |
| 1252 | int i, nr_delays = 0; |
| 1253 | struct ofs_delta_entry *ofs_delta = ofs_deltas; |
| 1254 | struct object_id ref_delta_oid; |
| 1255 | struct stat st; |
| 1256 | struct git_hash_ctx tmp_ctx; |
| 1257 | |
| 1258 | if (verbose) |
| 1259 | progress = start_progress( |
| 1260 | the_repository, |
| 1261 | progress_title ? progress_title : |
| 1262 | from_stdin ? _("Receiving objects") : _("Indexing objects"), |
| 1263 | nr_objects); |
| 1264 | for (i = 0; i < nr_objects; i++) { |
| 1265 | struct object_entry *obj = &objects[i]; |
| 1266 | void *data = unpack_raw_entry(obj, &ofs_delta->offset, |
| 1267 | &ref_delta_oid, |
| 1268 | &obj->idx.oid); |
| 1269 | obj->real_type = obj->type; |
| 1270 | if (obj->type == OBJ_OFS_DELTA) { |
| 1271 | nr_ofs_deltas++; |
| 1272 | ofs_delta->obj_no = i; |
| 1273 | ofs_delta++; |
| 1274 | } else if (obj->type == OBJ_REF_DELTA) { |
| 1275 | ALLOC_GROW(ref_deltas, nr_ref_deltas + 1, ref_deltas_alloc); |
| 1276 | oidcpy(&ref_deltas[nr_ref_deltas].oid, &ref_delta_oid); |
| 1277 | ref_deltas[nr_ref_deltas].obj_no = i; |
| 1278 | nr_ref_deltas++; |
| 1279 | } else if (!data) { |
| 1280 | /* large blobs, check later */ |
| 1281 | obj->real_type = OBJ_BAD; |
| 1282 | nr_delays++; |
| 1283 | } else |
| 1284 | sha1_object(data, NULL, obj->size, obj->type, |
| 1285 | &obj->idx.oid); |
| 1286 | free(data); |
| 1287 | display_progress(progress, i+1); |
| 1288 | } |
| 1289 | objects[i].idx.offset = consumed_bytes; |
| 1290 | stop_progress(&progress); |
| 1291 | |
| 1292 | /* Check pack integrity */ |
| 1293 | flush(); |
| 1294 | the_hash_algo->init_fn(&tmp_ctx); |
| 1295 | git_hash_clone(&tmp_ctx, &input_ctx); |
| 1296 | git_hash_final(hash, &tmp_ctx); |
| 1297 | if (!hasheq(fill(the_hash_algo->rawsz), hash, the_repository->hash_algo)) |
| 1298 | die(_("pack is corrupted (SHA1 mismatch)")); |
| 1299 | use(the_hash_algo->rawsz); |
| 1300 | |
| 1301 | /* If input_fd is a file, we should have reached its end now. */ |
| 1302 | if (fstat(input_fd, &st)) |
| 1303 | die_errno(_("cannot fstat packfile")); |
| 1304 | if (S_ISREG(st.st_mode) && |
| 1305 | lseek(input_fd, 0, SEEK_CUR) - input_len != st.st_size) |
| 1306 | die(_("pack has junk at the end")); |
| 1307 |
no test coverage detected