@@ -1395,11 +1395,10 @@ static int already_written(struct odb_transaction_files *transaction,
13951395}
13961396
13971397/* Lazily create backing packfile for the state */
1398- static void prepare_packfile_transaction (struct odb_transaction_files * transaction ,
1399- unsigned flags )
1398+ static void prepare_packfile_transaction (struct odb_transaction_files * transaction )
14001399{
14011400 struct transaction_packfile * state = & transaction -> packfile ;
1402- if (!( flags & INDEX_WRITE_OBJECT ) || state -> f )
1401+ if (state -> f )
14031402 return ;
14041403
14051404 state -> f = create_tmp_packfile (transaction -> base .source -> odb -> repo ,
@@ -1412,6 +1411,38 @@ static void prepare_packfile_transaction(struct odb_transaction_files *transacti
14121411 die_errno ("unable to write pack header" );
14131412}
14141413
1414+ static int hash_blob_stream (struct odb_write_stream * stream ,
1415+ const struct git_hash_algo * hash_algo ,
1416+ struct object_id * result_oid , size_t size )
1417+ {
1418+ unsigned char buf [16384 ];
1419+ struct git_hash_ctx ctx ;
1420+ unsigned header_len ;
1421+ size_t total = 0 ;
1422+
1423+ header_len = format_object_header ((char * )buf , sizeof (buf ),
1424+ OBJ_BLOB , size );
1425+ hash_algo -> init_fn (& ctx );
1426+ git_hash_update (& ctx , buf , header_len );
1427+
1428+ while (!stream -> is_finished ) {
1429+ ssize_t read_result = stream -> read (stream , buf , sizeof (buf ));
1430+
1431+ if (read_result < 0 )
1432+ return -1 ;
1433+
1434+ git_hash_update (& ctx , buf , read_result );
1435+ total += read_result ;
1436+ }
1437+
1438+ if (total != size )
1439+ return -1 ;
1440+
1441+ git_hash_final_oid (result_oid , & ctx );
1442+
1443+ return 0 ;
1444+ }
1445+
14151446/*
14161447 * Read the contents from fd for size bytes, streaming it to the
14171448 * packfile in state while updating the hash in ctx. Signal a failure
@@ -1429,15 +1460,13 @@ static void prepare_packfile_transaction(struct odb_transaction_files *transacti
14291460 */
14301461static int stream_blob_to_pack (struct transaction_packfile * state ,
14311462 struct git_hash_ctx * ctx , off_t * already_hashed_to ,
1432- int fd , size_t size , const char * path ,
1433- unsigned flags )
1463+ int fd , size_t size , const char * path )
14341464{
14351465 git_zstream s ;
14361466 unsigned char ibuf [16384 ];
14371467 unsigned char obuf [16384 ];
14381468 unsigned hdrlen ;
14391469 int status = Z_OK ;
1440- int write_object = (flags & INDEX_WRITE_OBJECT );
14411470 off_t offset = 0 ;
14421471
14431472 git_deflate_init (& s , pack_compression_level );
@@ -1472,20 +1501,18 @@ static int stream_blob_to_pack(struct transaction_packfile *state,
14721501 status = git_deflate (& s , size ? 0 : Z_FINISH );
14731502
14741503 if (!s .avail_out || status == Z_STREAM_END ) {
1475- if (write_object ) {
1476- size_t written = s .next_out - obuf ;
1477-
1478- /* would we bust the size limit? */
1479- if (state -> nr_written &&
1480- pack_size_limit_cfg &&
1481- pack_size_limit_cfg < state -> offset + written ) {
1482- git_deflate_abort (& s );
1483- return -1 ;
1484- }
1485-
1486- hashwrite (state -> f , obuf , written );
1487- state -> offset += written ;
1504+ size_t written = s .next_out - obuf ;
1505+
1506+ /* would we bust the size limit? */
1507+ if (state -> nr_written &&
1508+ pack_size_limit_cfg &&
1509+ pack_size_limit_cfg < state -> offset + written ) {
1510+ git_deflate_abort (& s );
1511+ return -1 ;
14881512 }
1513+
1514+ hashwrite (state -> f , obuf , written );
1515+ state -> offset += written ;
14891516 s .next_out = obuf ;
14901517 s .avail_out = sizeof (obuf );
14911518 }
@@ -1573,16 +1600,15 @@ static void flush_packfile_transaction(struct odb_transaction_files *transaction
15731600 */
15741601static int index_blob_packfile_transaction (struct odb_transaction_files * transaction ,
15751602 struct object_id * result_oid , int fd ,
1576- size_t size , const char * path ,
1577- unsigned flags )
1603+ size_t size , const char * path )
15781604{
15791605 struct transaction_packfile * state = & transaction -> packfile ;
15801606 off_t seekback , already_hashed_to ;
15811607 struct git_hash_ctx ctx ;
15821608 unsigned char obuf [16384 ];
15831609 unsigned header_len ;
15841610 struct hashfile_checkpoint checkpoint ;
1585- struct pack_idx_entry * idx = NULL ;
1611+ struct pack_idx_entry * idx ;
15861612
15871613 seekback = lseek (fd , 0 , SEEK_CUR );
15881614 if (seekback == (off_t )- 1 )
@@ -1593,42 +1619,33 @@ static int index_blob_packfile_transaction(struct odb_transaction_files *transac
15931619 transaction -> base .source -> odb -> repo -> hash_algo -> init_fn (& ctx );
15941620 git_hash_update (& ctx , obuf , header_len );
15951621
1596- /* Note: idx is non-NULL when we are writing */
1597- if ((flags & INDEX_WRITE_OBJECT ) != 0 ) {
1598- CALLOC_ARRAY (idx , 1 );
1599-
1600- prepare_packfile_transaction (transaction , flags );
1601- hashfile_checkpoint_init (state -> f , & checkpoint );
1602- }
1622+ CALLOC_ARRAY (idx , 1 );
1623+ prepare_packfile_transaction (transaction );
1624+ hashfile_checkpoint_init (state -> f , & checkpoint );
16031625
16041626 already_hashed_to = 0 ;
16051627
16061628 while (1 ) {
1607- prepare_packfile_transaction (transaction , flags );
1608- if (idx ) {
1609- hashfile_checkpoint (state -> f , & checkpoint );
1610- idx -> offset = state -> offset ;
1611- crc32_begin (state -> f );
1612- }
1629+ prepare_packfile_transaction (transaction );
1630+ hashfile_checkpoint (state -> f , & checkpoint );
1631+ idx -> offset = state -> offset ;
1632+ crc32_begin (state -> f );
1633+
16131634 if (!stream_blob_to_pack (state , & ctx , & already_hashed_to ,
1614- fd , size , path , flags ))
1635+ fd , size , path ))
16151636 break ;
16161637 /*
16171638 * Writing this object to the current pack will make
16181639 * it too big; we need to truncate it, start a new
16191640 * pack, and write into it.
16201641 */
1621- if (!idx )
1622- BUG ("should not happen" );
16231642 hashfile_truncate (state -> f , & checkpoint );
16241643 state -> offset = checkpoint .offset ;
16251644 flush_packfile_transaction (transaction );
16261645 if (lseek (fd , seekback , SEEK_SET ) == (off_t )- 1 )
16271646 return error ("cannot seek back" );
16281647 }
16291648 git_hash_final_oid (result_oid , & ctx );
1630- if (!idx )
1631- return 0 ;
16321649
16331650 idx -> crc32 = crc32_end (state -> f );
16341651 if (already_written (transaction , result_oid )) {
@@ -1666,18 +1683,28 @@ int index_fd(struct index_state *istate, struct object_id *oid,
16661683 ret = index_core (istate , oid , fd , xsize_t (st -> st_size ),
16671684 type , path , flags );
16681685 } else {
1669- struct object_database * odb = the_repository -> objects ;
1670- struct odb_transaction_files * files_transaction ;
1671- struct odb_transaction * transaction ;
1672-
1673- transaction = odb_transaction_begin (odb );
1674- files_transaction = container_of (odb -> transaction ,
1675- struct odb_transaction_files ,
1676- base );
1677- ret = index_blob_packfile_transaction (files_transaction , oid , fd ,
1678- xsize_t (st -> st_size ),
1679- path , flags );
1680- odb_transaction_commit (transaction );
1686+ struct odb_write_stream stream = { 0 };
1687+ odb_write_stream_from_fd (& stream , fd , xsize_t (st -> st_size ));
1688+
1689+ if (flags & INDEX_WRITE_OBJECT ) {
1690+ struct object_database * odb = the_repository -> objects ;
1691+ struct odb_transaction_files * files_transaction ;
1692+ struct odb_transaction * transaction ;
1693+
1694+ transaction = odb_transaction_begin (odb );
1695+ files_transaction = container_of (odb -> transaction ,
1696+ struct odb_transaction_files ,
1697+ base );
1698+ ret = index_blob_packfile_transaction (files_transaction , oid , fd ,
1699+ xsize_t (st -> st_size ), path );
1700+ odb_transaction_commit (transaction );
1701+ } else {
1702+ ret = hash_blob_stream (& stream ,
1703+ the_repository -> hash_algo , oid ,
1704+ xsize_t (st -> st_size ));
1705+ }
1706+
1707+ free (stream .data );
16811708 }
16821709
16831710 close (fd );
0 commit comments