@@ -1396,11 +1396,10 @@ static int already_written(struct odb_transaction_files *transaction,
13961396}
13971397
13981398/* Lazily create backing packfile for the state */
1399- static void prepare_packfile_transaction (struct odb_transaction_files * transaction ,
1400- unsigned flags )
1399+ static void prepare_packfile_transaction (struct odb_transaction_files * transaction )
14011400{
14021401 struct transaction_packfile * state = & transaction -> packfile ;
1403- if (!( flags & INDEX_WRITE_OBJECT ) || state -> f )
1402+ if (state -> f )
14041403 return ;
14051404
14061405 state -> f = create_tmp_packfile (transaction -> base .source -> odb -> repo ,
@@ -1413,6 +1412,39 @@ static void prepare_packfile_transaction(struct odb_transaction_files *transacti
14131412 die_errno ("unable to write pack header" );
14141413}
14151414
1415+ static int hash_blob_stream (struct odb_write_stream * stream ,
1416+ const struct git_hash_algo * hash_algo ,
1417+ struct object_id * result_oid , size_t size )
1418+ {
1419+ unsigned char buf [16384 ];
1420+ struct git_hash_ctx ctx ;
1421+ unsigned header_len ;
1422+ size_t bytes_hashed = 0 ;
1423+
1424+ header_len = format_object_header ((char * )buf , sizeof (buf ),
1425+ OBJ_BLOB , size );
1426+ hash_algo -> init_fn (& ctx );
1427+ git_hash_update (& ctx , buf , header_len );
1428+
1429+ while (!stream -> is_finished ) {
1430+ ssize_t read_result = odb_write_stream_read (stream , buf ,
1431+ sizeof (buf ));
1432+
1433+ if (read_result < 0 )
1434+ return -1 ;
1435+
1436+ git_hash_update (& ctx , buf , read_result );
1437+ bytes_hashed += read_result ;
1438+ }
1439+
1440+ if (bytes_hashed != size )
1441+ return -1 ;
1442+
1443+ git_hash_final_oid (result_oid , & ctx );
1444+
1445+ return 0 ;
1446+ }
1447+
14161448/*
14171449 * Read the contents from fd for size bytes, streaming it to the
14181450 * packfile in state while updating the hash in ctx. Signal a failure
@@ -1430,15 +1462,13 @@ static void prepare_packfile_transaction(struct odb_transaction_files *transacti
14301462 */
14311463static int stream_blob_to_pack (struct transaction_packfile * state ,
14321464 struct git_hash_ctx * ctx , off_t * already_hashed_to ,
1433- int fd , size_t size , const char * path ,
1434- unsigned flags )
1465+ int fd , size_t size , const char * path )
14351466{
14361467 git_zstream s ;
14371468 unsigned char ibuf [16384 ];
14381469 unsigned char obuf [16384 ];
14391470 unsigned hdrlen ;
14401471 int status = Z_OK ;
1441- int write_object = (flags & INDEX_WRITE_OBJECT );
14421472 off_t offset = 0 ;
14431473
14441474 git_deflate_init (& s , pack_compression_level );
@@ -1473,20 +1503,18 @@ static int stream_blob_to_pack(struct transaction_packfile *state,
14731503 status = git_deflate (& s , size ? 0 : Z_FINISH );
14741504
14751505 if (!s .avail_out || status == Z_STREAM_END ) {
1476- if (write_object ) {
1477- size_t written = s .next_out - obuf ;
1478-
1479- /* would we bust the size limit? */
1480- if (state -> nr_written &&
1481- pack_size_limit_cfg &&
1482- pack_size_limit_cfg < state -> offset + written ) {
1483- git_deflate_abort (& s );
1484- return -1 ;
1485- }
1486-
1487- hashwrite (state -> f , obuf , written );
1488- state -> offset += written ;
1506+ size_t written = s .next_out - obuf ;
1507+
1508+ /* would we bust the size limit? */
1509+ if (state -> nr_written &&
1510+ pack_size_limit_cfg &&
1511+ pack_size_limit_cfg < state -> offset + written ) {
1512+ git_deflate_abort (& s );
1513+ return -1 ;
14891514 }
1515+
1516+ hashwrite (state -> f , obuf , written );
1517+ state -> offset += written ;
14901518 s .next_out = obuf ;
14911519 s .avail_out = sizeof (obuf );
14921520 }
@@ -1574,16 +1602,15 @@ static void flush_packfile_transaction(struct odb_transaction_files *transaction
15741602 */
15751603static int index_blob_packfile_transaction (struct odb_transaction_files * transaction ,
15761604 struct object_id * result_oid , int fd ,
1577- size_t size , const char * path ,
1578- unsigned flags )
1605+ size_t size , const char * path )
15791606{
15801607 struct transaction_packfile * state = & transaction -> packfile ;
15811608 off_t seekback , already_hashed_to ;
15821609 struct git_hash_ctx ctx ;
15831610 unsigned char obuf [16384 ];
15841611 unsigned header_len ;
15851612 struct hashfile_checkpoint checkpoint ;
1586- struct pack_idx_entry * idx = NULL ;
1613+ struct pack_idx_entry * idx ;
15871614
15881615 seekback = lseek (fd , 0 , SEEK_CUR );
15891616 if (seekback == (off_t )- 1 )
@@ -1594,42 +1621,33 @@ static int index_blob_packfile_transaction(struct odb_transaction_files *transac
15941621 transaction -> base .source -> odb -> repo -> hash_algo -> init_fn (& ctx );
15951622 git_hash_update (& ctx , obuf , header_len );
15961623
1597- /* Note: idx is non-NULL when we are writing */
1598- if ((flags & INDEX_WRITE_OBJECT ) != 0 ) {
1599- CALLOC_ARRAY (idx , 1 );
1600-
1601- prepare_packfile_transaction (transaction , flags );
1602- hashfile_checkpoint_init (state -> f , & checkpoint );
1603- }
1624+ CALLOC_ARRAY (idx , 1 );
1625+ prepare_packfile_transaction (transaction );
1626+ hashfile_checkpoint_init (state -> f , & checkpoint );
16041627
16051628 already_hashed_to = 0 ;
16061629
16071630 while (1 ) {
1608- prepare_packfile_transaction (transaction , flags );
1609- if (idx ) {
1610- hashfile_checkpoint (state -> f , & checkpoint );
1611- idx -> offset = state -> offset ;
1612- crc32_begin (state -> f );
1613- }
1631+ prepare_packfile_transaction (transaction );
1632+ hashfile_checkpoint (state -> f , & checkpoint );
1633+ idx -> offset = state -> offset ;
1634+ crc32_begin (state -> f );
1635+
16141636 if (!stream_blob_to_pack (state , & ctx , & already_hashed_to ,
1615- fd , size , path , flags ))
1637+ fd , size , path ))
16161638 break ;
16171639 /*
16181640 * Writing this object to the current pack will make
16191641 * it too big; we need to truncate it, start a new
16201642 * pack, and write into it.
16211643 */
1622- if (!idx )
1623- BUG ("should not happen" );
16241644 hashfile_truncate (state -> f , & checkpoint );
16251645 state -> offset = checkpoint .offset ;
16261646 flush_packfile_transaction (transaction );
16271647 if (lseek (fd , seekback , SEEK_SET ) == (off_t )- 1 )
16281648 return error ("cannot seek back" );
16291649 }
16301650 git_hash_final_oid (result_oid , & ctx );
1631- if (!idx )
1632- return 0 ;
16331651
16341652 idx -> crc32 = crc32_end (state -> f );
16351653 if (already_written (transaction , result_oid )) {
@@ -1667,18 +1685,28 @@ int index_fd(struct index_state *istate, struct object_id *oid,
16671685 ret = index_core (istate , oid , fd , xsize_t (st -> st_size ),
16681686 type , path , flags );
16691687 } else {
1670- struct object_database * odb = the_repository -> objects ;
1671- struct odb_transaction_files * files_transaction ;
1672- struct odb_transaction * transaction ;
1673-
1674- transaction = odb_transaction_begin (odb );
1675- files_transaction = container_of (odb -> transaction ,
1676- struct odb_transaction_files ,
1677- base );
1678- ret = index_blob_packfile_transaction (files_transaction , oid , fd ,
1679- xsize_t (st -> st_size ),
1680- path , flags );
1681- odb_transaction_commit (transaction );
1688+ struct odb_write_stream stream ;
1689+ odb_write_stream_from_fd (& stream , fd , xsize_t (st -> st_size ));
1690+
1691+ if (flags & INDEX_WRITE_OBJECT ) {
1692+ struct object_database * odb = the_repository -> objects ;
1693+ struct odb_transaction_files * files_transaction ;
1694+ struct odb_transaction * transaction ;
1695+
1696+ transaction = odb_transaction_begin (odb );
1697+ files_transaction = container_of (odb -> transaction ,
1698+ struct odb_transaction_files ,
1699+ base );
1700+ ret = index_blob_packfile_transaction (files_transaction , oid , fd ,
1701+ xsize_t (st -> st_size ), path );
1702+ odb_transaction_commit (transaction );
1703+ } else {
1704+ ret = hash_blob_stream (& stream ,
1705+ the_repository -> hash_algo , oid ,
1706+ xsize_t (st -> st_size ));
1707+ }
1708+
1709+ odb_write_stream_release (& stream );
16821710 }
16831711
16841712 close (fd );
0 commit comments