Skip to content

Commit 2128181

Browse files
npitregitster
authored andcommitted
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 abeb40e). Signed-off-by: Nicolas Pitre <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 3fc366b commit 2128181

File tree

1 file changed

+25
-10
lines changed

1 file changed

+25
-10
lines changed

fast-import.c

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,7 @@ static struct atom_str **atom_table;
312312

313313
/* The .pack file being generated */
314314
static unsigned int pack_id;
315+
static struct sha1file *pack_file;
315316
static struct packed_git *pack_data;
316317
static struct packed_git **all_packs;
317318
static unsigned long pack_size;
@@ -838,11 +839,12 @@ static void start_packfile(void)
838839
p = xcalloc(1, sizeof(*p) + strlen(tmpfile) + 2);
839840
strcpy(p->pack_name, tmpfile);
840841
p->pack_fd = pack_fd;
842+
pack_file = sha1fd(pack_fd, p->pack_name);
841843

842844
hdr.hdr_signature = htonl(PACK_SIGNATURE);
843845
hdr.hdr_version = htonl(2);
844846
hdr.hdr_entries = 0;
845-
write_or_die(p->pack_fd, &hdr, sizeof(hdr));
847+
sha1write(pack_file, &hdr, sizeof(hdr));
846848

847849
pack_data = p;
848850
pack_size = sizeof(hdr);
@@ -956,15 +958,17 @@ static void end_packfile(void)
956958

957959
clear_delta_base_cache();
958960
if (object_count) {
961+
unsigned char cur_pack_sha1[20];
959962
char *idx_name;
960963
int i;
961964
struct branch *b;
962965
struct tag *t;
963966

964967
close_pack_windows(pack_data);
968+
sha1close(pack_file, cur_pack_sha1, 0);
965969
fixup_pack_header_footer(pack_data->pack_fd, pack_data->sha1,
966970
pack_data->pack_name, object_count,
967-
NULL, 0);
971+
cur_pack_sha1, pack_size);
968972
close(pack_data->pack_fd);
969973
idx_name = keep_pack(create_index());
970974

@@ -1138,22 +1142,22 @@ static int store_object(
11381142
e->depth = last->depth + 1;
11391143

11401144
hdrlen = encode_header(OBJ_OFS_DELTA, deltalen, hdr);
1141-
write_or_die(pack_data->pack_fd, hdr, hdrlen);
1145+
sha1write(pack_file, hdr, hdrlen);
11421146
pack_size += hdrlen;
11431147

11441148
hdr[pos] = ofs & 127;
11451149
while (ofs >>= 7)
11461150
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);
11481152
pack_size += sizeof(hdr) - pos;
11491153
} else {
11501154
e->depth = 0;
11511155
hdrlen = encode_header(type, dat->len, hdr);
1152-
write_or_die(pack_data->pack_fd, hdr, hdrlen);
1156+
sha1write(pack_file, hdr, hdrlen);
11531157
pack_size += hdrlen;
11541158
}
11551159

1156-
write_or_die(pack_data->pack_fd, out, s.total_out);
1160+
sha1write(pack_file, out, s.total_out);
11571161
pack_size += s.total_out;
11581162

11591163
free(out);
@@ -1170,12 +1174,17 @@ static int store_object(
11701174
return 0;
11711175
}
11721176

1173-
static void truncate_pack(off_t to)
1177+
static void truncate_pack(off_t to, git_SHA_CTX *ctx)
11741178
{
11751179
if (ftruncate(pack_data->pack_fd, to)
11761180
|| lseek(pack_data->pack_fd, to, SEEK_SET) != to)
11771181
die_errno("cannot truncate pack to skip duplicate");
11781182
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;
11791188
}
11801189

11811190
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)
11881197
unsigned long hdrlen;
11891198
off_t offset;
11901199
git_SHA_CTX c;
1200+
git_SHA_CTX pack_file_ctx;
11911201
z_stream s;
11921202
int status = Z_OK;
11931203

@@ -1198,6 +1208,10 @@ static void stream_blob(uintmax_t len, unsigned char *sha1out, uintmax_t mark)
11981208

11991209
offset = pack_size;
12001210

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+
12011215
hdrlen = snprintf((char *)out_buf, out_sz, "blob %" PRIuMAX, len) + 1;
12021216
if (out_sz <= hdrlen)
12031217
die("impossibly large object header");
@@ -1232,7 +1246,7 @@ static void stream_blob(uintmax_t len, unsigned char *sha1out, uintmax_t mark)
12321246

12331247
if (!s.avail_out || status == Z_STREAM_END) {
12341248
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);
12361250
pack_size += n;
12371251
s.next_out = out_buf;
12381252
s.avail_out = out_sz;
@@ -1260,14 +1274,14 @@ static void stream_blob(uintmax_t len, unsigned char *sha1out, uintmax_t mark)
12601274

12611275
if (e->idx.offset) {
12621276
duplicate_count_by_type[OBJ_BLOB]++;
1263-
truncate_pack(offset);
1277+
truncate_pack(offset, &pack_file_ctx);
12641278

12651279
} else if (find_sha1_pack(sha1, packed_git)) {
12661280
e->type = OBJ_BLOB;
12671281
e->pack_id = MAX_PACK_ID;
12681282
e->idx.offset = 1; /* just not zero! */
12691283
duplicate_count_by_type[OBJ_BLOB]++;
1270-
truncate_pack(offset);
1284+
truncate_pack(offset, &pack_file_ctx);
12711285

12721286
} else {
12731287
e->depth = 0;
@@ -1316,6 +1330,7 @@ static void *gfi_unpack_entry(
13161330
* the newly written data.
13171331
*/
13181332
close_pack_windows(p);
1333+
sha1flush(pack_file);
13191334

13201335
/* We have to offer 20 bytes additional on the end of
13211336
* the packfile as the core unpacker code assumes the

0 commit comments

Comments
 (0)