| 1095 | } |
| 1096 | |
| 1097 | static void write_reused_pack_one(struct packed_git *reuse_packfile, |
| 1098 | size_t pos, struct hashfile *out, |
| 1099 | off_t pack_start, |
| 1100 | struct pack_window **w_curs) |
| 1101 | { |
| 1102 | off_t offset, next, cur; |
| 1103 | enum object_type type; |
| 1104 | size_t size; |
| 1105 | |
| 1106 | offset = pack_pos_to_offset(reuse_packfile, pos); |
| 1107 | next = pack_pos_to_offset(reuse_packfile, pos + 1); |
| 1108 | |
| 1109 | record_reused_object(offset, |
| 1110 | offset - (hashfile_total(out) - pack_start)); |
| 1111 | |
| 1112 | cur = offset; |
| 1113 | type = unpack_object_header(reuse_packfile, w_curs, &cur, &size); |
| 1114 | assert(type >= 0); |
| 1115 | |
| 1116 | if (type == OBJ_OFS_DELTA) { |
| 1117 | off_t base_offset; |
| 1118 | off_t fixup; |
| 1119 | |
| 1120 | unsigned char header[MAX_PACK_OBJECT_HEADER]; |
| 1121 | unsigned len; |
| 1122 | |
| 1123 | base_offset = get_delta_base(reuse_packfile, w_curs, &cur, type, offset); |
| 1124 | assert(base_offset != 0); |
| 1125 | |
| 1126 | /* Convert to REF_DELTA if we must... */ |
| 1127 | if (!allow_ofs_delta) { |
| 1128 | uint32_t base_pos; |
| 1129 | struct object_id base_oid; |
| 1130 | |
| 1131 | if (offset_to_pack_pos(reuse_packfile, base_offset, &base_pos) < 0) |
| 1132 | die(_("expected object at offset %"PRIuMAX" " |
| 1133 | "in pack %s"), |
| 1134 | (uintmax_t)base_offset, |
| 1135 | reuse_packfile->pack_name); |
| 1136 | |
| 1137 | nth_packed_object_id(&base_oid, reuse_packfile, |
| 1138 | pack_pos_to_index(reuse_packfile, base_pos)); |
| 1139 | |
| 1140 | len = encode_in_pack_object_header(header, sizeof(header), |
| 1141 | OBJ_REF_DELTA, size); |
| 1142 | hashwrite(out, header, len); |
| 1143 | hashwrite(out, base_oid.hash, the_hash_algo->rawsz); |
| 1144 | copy_pack_data(out, reuse_packfile, w_curs, cur, next - cur); |
| 1145 | return; |
| 1146 | } |
| 1147 | |
| 1148 | /* Otherwise see if we need to rewrite the offset... */ |
| 1149 | fixup = find_reused_offset(offset) - |
| 1150 | find_reused_offset(base_offset); |
| 1151 | if (fixup) { |
| 1152 | unsigned char ofs_header[MAX_PACK_OBJECT_HEADER]; |
| 1153 | unsigned i, ofs_len; |
| 1154 | off_t ofs = offset - base_offset - fixup; |
no test coverage detected