1397
}
1398
1399
/* Lazily create backing packfile for the state */
1400
-static void prepare_packfile_transaction(struct odb_transaction_files *transaction,
1401
- unsigned flags)
1400
+static void prepare_packfile_transaction(struct odb_transaction_files *transaction)
1401
{
1402
struct transaction_packfile *state = &transaction->packfile;
1404
- if (!(flags & INDEX_WRITE_OBJECT) || state->f)
1403
+ if (state->f)
1404
return;
1405
1406
state->f = create_tmp_packfile(transaction->base.source->odb->repo,
1413
die_errno("unable to write pack header");
1414
}
1415
1416
+static int hash_blob_stream(struct odb_write_stream *stream,
1417
+ const struct git_hash_algo *hash_algo,
1418
+ struct object_id *result_oid, size_t size)
1419
+{
1420
+ unsigned char buf[16384];
1421
+ struct git_hash_ctx ctx;
1422
+ unsigned header_len;
1423
+ size_t bytes_hashed = 0;
1424
+
1425
+ header_len = format_object_header((char *)buf, sizeof(buf),
1426
+ OBJ_BLOB, size);
1427
+ hash_algo->init_fn(&ctx);
1428
+ git_hash_update(&ctx, buf, header_len);
1429
+
1430
+ while (!stream->is_finished) {
1431
+ ssize_t read_result = odb_write_stream_read(stream, buf,
1432
+ sizeof(buf));
1433
+
1434
+ if (read_result < 0)
1435
+ return -1;
1436
+
1437
+ git_hash_update(&ctx, buf, read_result);
1438
+ bytes_hashed += read_result;
1439
+ }
1440
+
1441
+ if (bytes_hashed != size)
1442
+ return -1;
1443
+
1444
+ git_hash_final_oid(result_oid, &ctx);
1445
+
1446
+ return 0;
1447
+}
1448
+
1449
/*
1450
* Read the contents from fd for size bytes, streaming it to the
1451
* packfile in state while updating the hash in ctx. Signal a failure
1463
*/
1464
static int stream_blob_to_pack(struct transaction_packfile *state,
1465
struct git_hash_ctx *ctx, off_t *already_hashed_to,
1434
- int fd, size_t size, const char *path,
1435
- unsigned flags)
1466
+ int fd, size_t size, const char *path)
1467
{
1468
git_zstream s;
1469
unsigned char ibuf[16384];
1470
unsigned char obuf[16384];
1471
unsigned hdrlen;
1472
int status = Z_OK;
1442
- int write_object = (flags & INDEX_WRITE_OBJECT);
1473
off_t offset = 0;
1474
1475
git_deflate_init(&s, pack_compression_level);
1504
status = git_deflate(&s, size ? 0 : Z_FINISH);
1505
1506
if (!s.avail_out || status == Z_STREAM_END) {
1477
- if (write_object) {
1478
- size_t written = s.next_out - obuf;
1479
-
1480
- /* would we bust the size limit? */
1481
- if (state->nr_written &&
1482
- pack_size_limit_cfg &&
1483
- pack_size_limit_cfg < state->offset + written) {
1484
- git_deflate_abort(&s);
1485
- return -1;
1486
- }
1487
-
1488
- hashwrite(state->f, obuf, written);
1489
- state->offset += written;
1507
+ size_t written = s.next_out - obuf;
1508
+
1509
+ /* would we bust the size limit? */
1510
+ if (state->nr_written &&
1511
+ pack_size_limit_cfg &&
1512
+ pack_size_limit_cfg < state->offset + written) {
1513
+ git_deflate_abort(&s);
1514
+ return -1;
1515
}
1516
+
1517
+ hashwrite(state->f, obuf, written);
1518
+ state->offset += written;
1519
s.next_out = obuf;
1520
s.avail_out = sizeof(obuf);
1521
}
1603
*/
1604
static int index_blob_packfile_transaction(struct odb_transaction_files *transaction,
1605
struct object_id *result_oid, int fd,
1578
- size_t size, const char *path,
1579
- unsigned flags)
1606
+ size_t size, const char *path)
1607
{
1608
struct transaction_packfile *state = &transaction->packfile;
1609
off_t seekback, already_hashed_to;
1611
unsigned char obuf[16384];
1612
unsigned header_len;
1613
struct hashfile_checkpoint checkpoint;
1587
- struct pack_idx_entry *idx = NULL;
1614
+ struct pack_idx_entry *idx;
1615
1616
seekback = lseek(fd, 0, SEEK_CUR);
1617
if (seekback == (off_t)-1)
1622
transaction->base.source->odb->repo->hash_algo->init_fn(&ctx);
1623
git_hash_update(&ctx, obuf, header_len);
1624
1598
- /* Note: idx is non-NULL when we are writing */
1599
- if ((flags & INDEX_WRITE_OBJECT) != 0) {
1600
- CALLOC_ARRAY(idx, 1);
1601
-
1602
- prepare_packfile_transaction(transaction, flags);
1603
- hashfile_checkpoint_init(state->f, &checkpoint);
1604
- }
1625
+ CALLOC_ARRAY(idx, 1);
1626
+ prepare_packfile_transaction(transaction);
1627
+ hashfile_checkpoint_init(state->f, &checkpoint);
1628
1629
already_hashed_to = 0;
1630
1631
while (1) {
1609
- prepare_packfile_transaction(transaction, flags);
1610
- if (idx) {
1611
- hashfile_checkpoint(state->f, &checkpoint);
1612
- idx->offset = state->offset;
1613
- crc32_begin(state->f);
1614
- }
1632
+ prepare_packfile_transaction(transaction);
1633
+ hashfile_checkpoint(state->f, &checkpoint);
1634
+ idx->offset = state->offset;
1635
+ crc32_begin(state->f);
1636
+
1637
if (!stream_blob_to_pack(state, &ctx, &already_hashed_to,
1616
- fd, size, path, flags))
1638
+ fd, size, path))
1639
break;
1640
/*
1641
* Writing this object to the current pack will make
1642
* it too big; we need to truncate it, start a new
1643
* pack, and write into it.
1644
*/
1623
- if (!idx)
1624
- BUG("should not happen");
1645
hashfile_truncate(state->f, &checkpoint);
1646
state->offset = checkpoint.offset;
1647
flush_packfile_transaction(transaction);
1649
return error("cannot seek back");
1650
}
1651
git_hash_final_oid(result_oid, &ctx);
1632
- if (!idx)
1633
- return 0;
1652
1653
idx->crc32 = crc32_end(state->f);
1654
if (already_written(transaction, result_oid)) {
1686
ret = index_core(istate, oid, fd, xsize_t(st->st_size),
1687
type, path, flags);
1688
} else {
1671
- struct object_database *odb = the_repository->objects;
1672
- struct odb_transaction_files *files_transaction;
1673
- struct odb_transaction *transaction;
1674
-
1675
- transaction = odb_transaction_begin(odb);
1676
- files_transaction = container_of(odb->transaction,
1677
- struct odb_transaction_files,
1678
- base);
1679
- ret = index_blob_packfile_transaction(files_transaction, oid, fd,
1680
- xsize_t(st->st_size),
1681
- path, flags);
1682
- odb_transaction_commit(transaction);
1689
+ struct odb_write_stream stream;
1690
+ odb_write_stream_from_fd(&stream, fd, xsize_t(st->st_size));
1691
+
1692
+ if (flags & INDEX_WRITE_OBJECT) {
1693
+ struct object_database *odb = the_repository->objects;
1694
+ struct odb_transaction_files *files_transaction;
1695
+ struct odb_transaction *transaction;
1696
+
1697
+ transaction = odb_transaction_begin(odb);
1698
+ files_transaction = container_of(odb->transaction,
1699
+ struct odb_transaction_files,
1700
+ base);
1701
+ ret = index_blob_packfile_transaction(files_transaction, oid, fd,
1702
+ xsize_t(st->st_size), path);
1703
+ odb_transaction_commit(transaction);
1704
+ } else {
1705
+ ret = hash_blob_stream(&stream,
1706
+ the_repository->hash_algo, oid,
1707
+ xsize_t(st->st_size));
1708
+ }
1709
+
1710
+ odb_write_stream_release(&stream);
1711
}
1712
1713
close(fd);