@@ -312,6 +312,7 @@ static struct atom_str **atom_table;
312
312
313
313
/* The .pack file being generated */
314
314
static unsigned int pack_id ;
315
+ static struct sha1file * pack_file ;
315
316
static struct packed_git * pack_data ;
316
317
static struct packed_git * * all_packs ;
317
318
static unsigned long pack_size ;
@@ -838,11 +839,12 @@ static void start_packfile(void)
838
839
p = xcalloc (1 , sizeof (* p ) + strlen (tmpfile ) + 2 );
839
840
strcpy (p -> pack_name , tmpfile );
840
841
p -> pack_fd = pack_fd ;
842
+ pack_file = sha1fd (pack_fd , p -> pack_name );
841
843
842
844
hdr .hdr_signature = htonl (PACK_SIGNATURE );
843
845
hdr .hdr_version = htonl (2 );
844
846
hdr .hdr_entries = 0 ;
845
- write_or_die ( p -> pack_fd , & hdr , sizeof (hdr ));
847
+ sha1write ( pack_file , & hdr , sizeof (hdr ));
846
848
847
849
pack_data = p ;
848
850
pack_size = sizeof (hdr );
@@ -956,15 +958,17 @@ static void end_packfile(void)
956
958
957
959
clear_delta_base_cache ();
958
960
if (object_count ) {
961
+ unsigned char cur_pack_sha1 [20 ];
959
962
char * idx_name ;
960
963
int i ;
961
964
struct branch * b ;
962
965
struct tag * t ;
963
966
964
967
close_pack_windows (pack_data );
968
+ sha1close (pack_file , cur_pack_sha1 , 0 );
965
969
fixup_pack_header_footer (pack_data -> pack_fd , pack_data -> sha1 ,
966
970
pack_data -> pack_name , object_count ,
967
- NULL , 0 );
971
+ cur_pack_sha1 , pack_size );
968
972
close (pack_data -> pack_fd );
969
973
idx_name = keep_pack (create_index ());
970
974
@@ -1138,22 +1142,22 @@ static int store_object(
1138
1142
e -> depth = last -> depth + 1 ;
1139
1143
1140
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 );
1142
1146
pack_size += hdrlen ;
1143
1147
1144
1148
hdr [pos ] = ofs & 127 ;
1145
1149
while (ofs >>= 7 )
1146
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 );
1148
1152
pack_size += sizeof (hdr ) - pos ;
1149
1153
} else {
1150
1154
e -> depth = 0 ;
1151
1155
hdrlen = encode_header (type , dat -> len , hdr );
1152
- write_or_die ( pack_data -> pack_fd , hdr , hdrlen );
1156
+ sha1write ( pack_file , hdr , hdrlen );
1153
1157
pack_size += hdrlen ;
1154
1158
}
1155
1159
1156
- write_or_die ( pack_data -> pack_fd , out , s .total_out );
1160
+ sha1write ( pack_file , out , s .total_out );
1157
1161
pack_size += s .total_out ;
1158
1162
1159
1163
free (out );
@@ -1170,12 +1174,17 @@ static int store_object(
1170
1174
return 0 ;
1171
1175
}
1172
1176
1173
- static void truncate_pack (off_t to )
1177
+ static void truncate_pack (off_t to , git_SHA_CTX * ctx )
1174
1178
{
1175
1179
if (ftruncate (pack_data -> pack_fd , to )
1176
1180
|| lseek (pack_data -> pack_fd , to , SEEK_SET ) != to )
1177
1181
die_errno ("cannot truncate pack to skip duplicate" );
1178
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 ;
1179
1188
}
1180
1189
1181
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)
1188
1197
unsigned long hdrlen ;
1189
1198
off_t offset ;
1190
1199
git_SHA_CTX c ;
1200
+ git_SHA_CTX pack_file_ctx ;
1191
1201
z_stream s ;
1192
1202
int status = Z_OK ;
1193
1203
@@ -1198,6 +1208,10 @@ static void stream_blob(uintmax_t len, unsigned char *sha1out, uintmax_t mark)
1198
1208
1199
1209
offset = pack_size ;
1200
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
+
1201
1215
hdrlen = snprintf ((char * )out_buf , out_sz , "blob %" PRIuMAX , len ) + 1 ;
1202
1216
if (out_sz <= hdrlen )
1203
1217
die ("impossibly large object header" );
@@ -1232,7 +1246,7 @@ static void stream_blob(uintmax_t len, unsigned char *sha1out, uintmax_t mark)
1232
1246
1233
1247
if (!s .avail_out || status == Z_STREAM_END ) {
1234
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 );
1236
1250
pack_size += n ;
1237
1251
s .next_out = out_buf ;
1238
1252
s .avail_out = out_sz ;
@@ -1260,14 +1274,14 @@ static void stream_blob(uintmax_t len, unsigned char *sha1out, uintmax_t mark)
1260
1274
1261
1275
if (e -> idx .offset ) {
1262
1276
duplicate_count_by_type [OBJ_BLOB ]++ ;
1263
- truncate_pack (offset );
1277
+ truncate_pack (offset , & pack_file_ctx );
1264
1278
1265
1279
} else if (find_sha1_pack (sha1 , packed_git )) {
1266
1280
e -> type = OBJ_BLOB ;
1267
1281
e -> pack_id = MAX_PACK_ID ;
1268
1282
e -> idx .offset = 1 ; /* just not zero! */
1269
1283
duplicate_count_by_type [OBJ_BLOB ]++ ;
1270
- truncate_pack (offset );
1284
+ truncate_pack (offset , & pack_file_ctx );
1271
1285
1272
1286
} else {
1273
1287
e -> depth = 0 ;
@@ -1316,6 +1330,7 @@ static void *gfi_unpack_entry(
1316
1330
* the newly written data.
1317
1331
*/
1318
1332
close_pack_windows (p );
1333
+ sha1flush (pack_file );
1319
1334
1320
1335
/* We have to offer 20 bytes additional on the end of
1321
1336
* the packfile as the core unpacker code assumes the
0 commit comments