Skip to content

Commit aa4d81b

Browse files
jltoblergitster
authored andcommitted
bulk-checkin: require transaction for index_blob_bulk_checkin()
The bulk-checkin subsystem provides a mechanism to write blobs directly to a packfile via `index_blob_bulk_checkin()`. If there is an ongoing transaction when invoked, objects written via this function are stored in the same packfile. The packfile is not flushed until the transaction itself is flushed. If there is no transaction, the single object is written to a packfile and immediately flushed. This complicates `index_blob_bulk_checkin()` as it cannot reliably use the provided transaction to get the associated repository. Update `index_blob_bulk_checkin()` to assume that a valid transaction is always provided. Callers are now expected to ensure a transaction is set up beforehand. With this simplification, `deflate_blob_bulk_checkin()` is no longer needed as a standalone internal function and is combined with `index_blob_bulk_checkin()`. The single call site in `object-file.c:index_fd()` is updated accordingly. Due to how `{begin,end}_odb_transaction()` handles nested transactions, a new transaction is only created and committed if there is not already an ongoing transaction. Signed-off-by: Justin Tobler <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent b336144 commit aa4d81b

File tree

3 files changed

+23
-32
lines changed

3 files changed

+23
-32
lines changed

bulk-checkin.c

Lines changed: 4 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -254,11 +254,11 @@ static void prepare_to_stream(struct bulk_checkin_packfile *state,
254254
die_errno("unable to write pack header");
255255
}
256256

257-
static int deflate_blob_to_pack(struct bulk_checkin_packfile *state,
258-
struct object_id *result_oid,
259-
int fd, size_t size,
260-
const char *path, unsigned flags)
257+
int index_blob_bulk_checkin(struct odb_transaction *transaction,
258+
struct object_id *result_oid, int fd, size_t size,
259+
const char *path, unsigned flags)
261260
{
261+
struct bulk_checkin_packfile *state = &transaction->packfile;
262262
off_t seekback, already_hashed_to;
263263
struct git_hash_ctx ctx;
264264
unsigned char obuf[16384];
@@ -361,25 +361,6 @@ void fsync_loose_object_bulk_checkin(struct odb_transaction *transaction,
361361
}
362362
}
363363

364-
int index_blob_bulk_checkin(struct odb_transaction *transaction,
365-
struct object_id *oid, int fd, size_t size,
366-
const char *path, unsigned flags)
367-
{
368-
int status;
369-
370-
if (transaction) {
371-
status = deflate_blob_to_pack(&transaction->packfile, oid, fd,
372-
size, path, flags);
373-
} else {
374-
struct bulk_checkin_packfile state = { 0 };
375-
376-
status = deflate_blob_to_pack(&state, oid, fd, size, path, flags);
377-
flush_bulk_checkin_packfile(&state);
378-
}
379-
380-
return status;
381-
}
382-
383364
struct odb_transaction *begin_odb_transaction(struct object_database *odb)
384365
{
385366
if (!odb->transaction) {

bulk-checkin.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,11 @@ void fsync_loose_object_bulk_checkin(struct odb_transaction *transaction,
1414
int fd, const char *filename);
1515

1616
/*
17-
* This creates one packfile per large blob unless bulk-checkin
18-
* machinery is "plugged".
17+
* This writes the specified object to a packfile. Objects written here
18+
* during the same transaction are written to the same packfile. The
19+
* packfile is not flushed until the transaction is flushed. The caller
20+
* is expected to ensure a valid transaction is setup for objects to be
21+
* recorded to.
1922
*
2023
* This also bypasses the usual "convert-to-git" dance, and that is on
2124
* purpose. We could write a streaming version of the converting

object-file.c

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1253,19 +1253,26 @@ int index_fd(struct index_state *istate, struct object_id *oid,
12531253
* Call xsize_t() only when needed to avoid potentially unnecessary
12541254
* die() for large files.
12551255
*/
1256-
if (type == OBJ_BLOB && path && would_convert_to_git_filter_fd(istate, path))
1256+
if (type == OBJ_BLOB && path && would_convert_to_git_filter_fd(istate, path)) {
12571257
ret = index_stream_convert_blob(istate, oid, fd, path, flags);
1258-
else if (!S_ISREG(st->st_mode))
1258+
} else if (!S_ISREG(st->st_mode)) {
12591259
ret = index_pipe(istate, oid, fd, type, path, flags);
1260-
else if ((st->st_size >= 0 && (size_t) st->st_size <= repo_settings_get_big_file_threshold(istate->repo)) ||
1261-
type != OBJ_BLOB ||
1262-
(path && would_convert_to_git(istate, path)))
1260+
} else if ((st->st_size >= 0 &&
1261+
(size_t)st->st_size <= repo_settings_get_big_file_threshold(istate->repo)) ||
1262+
type != OBJ_BLOB ||
1263+
(path && would_convert_to_git(istate, path))) {
12631264
ret = index_core(istate, oid, fd, xsize_t(st->st_size),
12641265
type, path, flags);
1265-
else
1266-
ret = index_blob_bulk_checkin(the_repository->objects->transaction,
1266+
} else {
1267+
struct odb_transaction *transaction;
1268+
1269+
transaction = begin_odb_transaction(the_repository->objects);
1270+
ret = index_blob_bulk_checkin(transaction,
12671271
oid, fd, xsize_t(st->st_size),
12681272
path, flags);
1273+
end_odb_transaction(transaction);
1274+
}
1275+
12691276
close(fd);
12701277
return ret;
12711278
}

0 commit comments

Comments
 (0)