+ qsort(sorted_by_pos, n, sizeof(*sorted_by_pos), delta_pos_compare);
+
+ for (i = 0; i < n; i++) {
+ struct delta_entry *d = sorted_by_pos[i];
+ void *data;
+ unsigned long size;
+ char type[10];
+ enum object_type obj_type;
+ int j, first, last;
+
+ if (objects[d->obj_no].real_type != OBJ_REF_DELTA)
+ continue;
+ data = read_sha1_file(d->base.sha1, type, &size);
+ if (!data)
+ continue;
+ if (!strcmp(type, blob_type)) obj_type = OBJ_BLOB;
+ else if (!strcmp(type, tree_type)) obj_type = OBJ_TREE;
+ else if (!strcmp(type, commit_type)) obj_type = OBJ_COMMIT;
+ else if (!strcmp(type, tag_type)) obj_type = OBJ_TAG;
+ else die("base object %s is of type '%s'",
+ sha1_to_hex(d->base.sha1), type);
+
+ find_delta_childs(&d->base, &first, &last);
+ for (j = first; j <= last; j++) {
+ struct object_entry *child = objects + deltas[j].obj_no;
+ if (child->real_type == OBJ_REF_DELTA)
+ resolve_delta(child, data, size, obj_type);
+ }
+
+ append_obj_to_pack(data, size, obj_type);
+ free(data);
+ }
+ free(sorted_by_pos);
+}
+
+static void readjust_pack_header_and_sha1(unsigned char *sha1)
+{
+ struct pack_header hdr;
+ SHA_CTX ctx;
+ int size;
+
+ /* Rewrite pack header with updated object number */
+ if (lseek(output_fd, 0, SEEK_SET) != 0)
+ die("cannot seek back: %s", strerror(errno));
+ if (xread(output_fd, &hdr, sizeof(hdr)) != sizeof(hdr))
+ die("cannot read pack header back: %s", strerror(errno));
+ hdr.hdr_entries = htonl(nr_objects);
+ if (lseek(output_fd, 0, SEEK_SET) != 0)
+ die("cannot seek back: %s", strerror(errno));
+ write_or_die(output_fd, &hdr, sizeof(hdr));
+ if (lseek(output_fd, 0, SEEK_SET) != 0)
+ die("cannot seek back: %s", strerror(errno));
+
+ /* Recompute and store the new pack's SHA1 */
+ SHA1_Init(&ctx);
+ do {
+ unsigned char *buf[4096];
+ size = xread(output_fd, buf, sizeof(buf));
+ if (size < 0)
+ die("cannot read pack data back: %s", strerror(errno));
+ SHA1_Update(&ctx, buf, size);
+ } while (size > 0);
+ SHA1_Final(sha1, &ctx);
+ write_or_die(output_fd, sha1, 20);