Skip to content

Commit a8a773c

Browse files
committed
Merge branch 'jt/index-fd-wo-repo-regression-fix-maint' into HEAD
* jt/index-fd-wo-repo-regression-fix-maint: object-file: avoid ODB transaction when not writing objects
2 parents 1adf5bc + 7d8727f commit a8a773c

File tree

2 files changed

+53
-12
lines changed

2 files changed

+53
-12
lines changed

object-file.c

Lines changed: 45 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1640,6 +1640,34 @@ static int index_blob_packfile_transaction(struct odb_transaction_files *transac
16401640
return 0;
16411641
}
16421642

1643+
static int hash_blob_stream(const struct git_hash_algo *hash_algo,
1644+
struct object_id *result_oid, int fd, size_t size)
1645+
{
1646+
unsigned char buf[16384];
1647+
struct git_hash_ctx ctx;
1648+
unsigned header_len;
1649+
1650+
header_len = format_object_header((char *)buf, sizeof(buf),
1651+
OBJ_BLOB, size);
1652+
hash_algo->init_fn(&ctx);
1653+
git_hash_update(&ctx, buf, header_len);
1654+
1655+
while (size) {
1656+
size_t rsize = size < sizeof(buf) ? size : sizeof(buf);
1657+
ssize_t read_result = read_in_full(fd, buf, rsize);
1658+
1659+
if ((read_result < 0) || ((size_t)read_result != rsize))
1660+
return -1;
1661+
1662+
git_hash_update(&ctx, buf, rsize);
1663+
size -= read_result;
1664+
}
1665+
1666+
git_hash_final_oid(result_oid, &ctx);
1667+
1668+
return 0;
1669+
}
1670+
16431671
int index_fd(struct index_state *istate, struct object_id *oid,
16441672
int fd, struct stat *st,
16451673
enum object_type type, const char *path, unsigned flags)
@@ -1661,18 +1689,23 @@ int index_fd(struct index_state *istate, struct object_id *oid,
16611689
ret = index_core(istate, oid, fd, xsize_t(st->st_size),
16621690
type, path, flags);
16631691
} else {
1664-
struct object_database *odb = the_repository->objects;
1665-
struct odb_transaction_files *files_transaction;
1666-
struct odb_transaction *transaction;
1667-
1668-
transaction = odb_transaction_begin(odb);
1669-
files_transaction = container_of(odb->transaction,
1670-
struct odb_transaction_files,
1671-
base);
1672-
ret = index_blob_packfile_transaction(files_transaction, oid, fd,
1673-
xsize_t(st->st_size),
1674-
path, flags);
1675-
odb_transaction_commit(transaction);
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),
1703+
path, flags);
1704+
odb_transaction_commit(transaction);
1705+
} else {
1706+
ret = hash_blob_stream(the_repository->hash_algo, oid,
1707+
fd, xsize_t(st->st_size));
1708+
}
16761709
}
16771710

16781711
close(fd);

t/t1517-outside-repo.sh

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,14 @@ test_expect_success 'diff outside repository' '
9393
test_cmp expect actual
9494
'
9595

96+
test_expect_success 'hash object exceeding bigFileThreshold outside repository' '
97+
(
98+
cd non-repo &&
99+
echo foo >foo &&
100+
git -c core.bigFileThreshold=1 hash-object --stdin <foo
101+
)
102+
'
103+
96104
test_expect_success 'stripspace outside repository' '
97105
nongit git stripspace -s </dev/null
98106
'

0 commit comments

Comments
 (0)