fast-import: use sha1write() for pack data
This is in preparation for using write_idx_file(). Also, by using sha1write() we get some buffering to reduces the number of write syscalls, and the written data is SHA1 summed which allows for the extra data integrity validation check performed in fixup_pack_header_footer() (details on this in commit abeb40e5aa). Signed-off-by: Nicolas Pitre <nico@fluxnic.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Nicolas Pitre committed
Feb 17, 2010 at 14:05 UTC
212818160d588fae403dfc823250e95ffbac76e5
1 file changed
+25
-10
fast-import.c
+25
-10
@@ -312,6 +312,7 @@ static struct atom_str **atom_table;
312
313
/* The .pack file being generated */
314
static unsigned int pack_id;
315
+static struct sha1file *pack_file;
316
static struct packed_git *pack_data;
317
static struct packed_git **all_packs;
318
static unsigned long pack_size;
@@ -838,11 +839,12 @@ static void start_packfile(void)
839
p = xcalloc(1, sizeof(*p) + strlen(tmpfile) + 2);
840
strcpy(p->pack_name, tmpfile);
841
p->pack_fd = pack_fd;
842
+ pack_file = sha1fd(pack_fd, p->pack_name);
843
844
hdr.hdr_signature = htonl(PACK_SIGNATURE);
845
hdr.hdr_version = htonl(2);
846
hdr.hdr_entries = 0;
845
- write_or_die(p->pack_fd, &hdr, sizeof(hdr));
847
+ sha1write(pack_file, &hdr, sizeof(hdr));
848
849
pack_data = p;
850
pack_size = sizeof(hdr);
@@ -956,15 +958,17 @@ static void end_packfile(void)
958
959
clear_delta_base_cache();
960
if (object_count) {
961
+ unsigned char cur_pack_sha1[20];
962
char *idx_name;
963
int i;
964
struct branch *b;
965
struct tag *t;
966
967
close_pack_windows(pack_data);
968
+ sha1close(pack_file, cur_pack_sha1, 0);
969
fixup_pack_header_footer(pack_data->pack_fd, pack_data->sha1,
970
pack_data->pack_name, object_count,
967
- NULL, 0);
971
+ cur_pack_sha1, pack_size);
972
close(pack_data->pack_fd);
973
idx_name = keep_pack(create_index());
974
@@ -1138,22 +1142,22 @@ static int store_object(
1142
e->depth = last->depth + 1;
1143
1144
hdrlen = encode_header(OBJ_OFS_DELTA, deltalen, hdr);
1141
- write_or_die(pack_data->pack_fd, hdr, hdrlen);
1145
+ sha1write(pack_file, hdr, hdrlen);
1146
pack_size += hdrlen;
1147
1148
hdr[pos] = ofs & 127;
1149
while (ofs >>= 7)
1150
hdr[--pos] = 128 | (--ofs & 127);
1147
- write_or_die(pack_data->pack_fd, hdr + pos, sizeof(hdr) - pos);
1151
+ sha1write(pack_file, hdr + pos, sizeof(hdr) - pos);
1152
pack_size += sizeof(hdr) - pos;
1153
} else {
1154
e->depth = 0;
1155
hdrlen = encode_header(type, dat->len, hdr);
1152
- write_or_die(pack_data->pack_fd, hdr, hdrlen);
1156
+ sha1write(pack_file, hdr, hdrlen);
1157
pack_size += hdrlen;
1158
}
1159
1156
- write_or_die(pack_data->pack_fd, out, s.total_out);
1160
+ sha1write(pack_file, out, s.total_out);
1161
pack_size += s.total_out;
1162
1163
free(out);
@@ -1170,12 +1174,17 @@ static int store_object(
1174
return 0;
1175
}
1176
1173
-static void truncate_pack(off_t to)
1177
+static void truncate_pack(off_t to, git_SHA_CTX *ctx)
1178
{
1179
if (ftruncate(pack_data->pack_fd, to)
1180
|| lseek(pack_data->pack_fd, to, SEEK_SET) != to)
1181
die_errno("cannot truncate pack to skip duplicate");
1182
pack_size = to;
1183
+
1184
+ /* yes this is a layering violation */
1185
+ pack_file->total = to;
1186
+ pack_file->offset = 0;
1187
+ pack_file->ctx = *ctx;
1188
}
1189
1190
static void stream_blob(uintmax_t len, unsigned char *sha1out, uintmax_t mark)
@@ -1188,6 +1197,7 @@ static void stream_blob(uintmax_t len, unsigned char *sha1out, uintmax_t mark)
1197
unsigned long hdrlen;
1198
off_t offset;
1199
git_SHA_CTX c;
1200
+ git_SHA_CTX pack_file_ctx;
1201
z_stream s;
1202
int status = Z_OK;
1203
@@ -1198,6 +1208,10 @@ static void stream_blob(uintmax_t len, unsigned char *sha1out, uintmax_t mark)
1208
1209
offset = pack_size;
1210
1211
+ /* preserve the pack_file SHA1 ctx in case we have to truncate later */
1212
+ sha1flush(pack_file);
1213
+ pack_file_ctx = pack_file->ctx;
1214
+
1215
hdrlen = snprintf((char *)out_buf, out_sz, "blob %" PRIuMAX, len) + 1;
1216
if (out_sz <= hdrlen)
1217
die("impossibly large object header");
@@ -1232,7 +1246,7 @@ static void stream_blob(uintmax_t len, unsigned char *sha1out, uintmax_t mark)
1246
1247
if (!s.avail_out || status == Z_STREAM_END) {
1248
size_t n = s.next_out - out_buf;
1235
- write_or_die(pack_data->pack_fd, out_buf, n);
1249
+ sha1write(pack_file, out_buf, n);
1250
pack_size += n;
1251
s.next_out = out_buf;
1252
s.avail_out = out_sz;
@@ -1260,14 +1274,14 @@ static void stream_blob(uintmax_t len, unsigned char *sha1out, uintmax_t mark)
1274
1275
if (e->idx.offset) {
1276
duplicate_count_by_type[OBJ_BLOB]++;
1263
- truncate_pack(offset);
1277
+ truncate_pack(offset, &pack_file_ctx);
1278
1279
} else if (find_sha1_pack(sha1, packed_git)) {
1280
e->type = OBJ_BLOB;
1281
e->pack_id = MAX_PACK_ID;
1282
e->idx.offset = 1; /* just not zero! */
1283
duplicate_count_by_type[OBJ_BLOB]++;
1270
- truncate_pack(offset);
1284
+ truncate_pack(offset, &pack_file_ctx);
1285
1286
} else {
1287
e->depth = 0;
@@ -1316,6 +1330,7 @@ static void *gfi_unpack_entry(
1330
* the newly written data.
1331
*/
1332
close_pack_windows(p);
1333
+ sha1flush(pack_file);
1334
1335
/* We have to offer 20 bytes additional on the end of
1336
* the packfile as the core unpacker code assumes the