diff --git a/builtin/add.c b/builtin/add.c index c859f66519..3d5d9cfdb9 100644 --- a/builtin/add.c +++ b/builtin/add.c @@ -581,7 +581,7 @@ int cmd_add(int argc, string_list_clear(&only_match_skip_worktree, 0); } - transaction = odb_transaction_begin(repo->objects); + odb_transaction_begin_or_die(repo->objects, &transaction); ps_matched = xcalloc(pathspec.nr, 1); if (add_renormalize) diff --git a/builtin/unpack-objects.c b/builtin/unpack-objects.c index 59e9b8711e..1a195bf045 100644 --- a/builtin/unpack-objects.c +++ b/builtin/unpack-objects.c @@ -596,7 +596,7 @@ static void unpack_all(void) progress = start_progress(the_repository, _("Unpacking objects"), nr_objects); CALLOC_ARRAY(obj_list, nr_objects); - transaction = odb_transaction_begin(the_repository->objects); + odb_transaction_begin_or_die(the_repository->objects, &transaction); for (i = 0; i < nr_objects; i++) { unpack_one(i); display_progress(progress, i + 1); diff --git a/builtin/update-index.c b/builtin/update-index.c index 3d6646c318..17f3ea284c 100644 --- a/builtin/update-index.c +++ b/builtin/update-index.c @@ -1124,7 +1124,7 @@ int cmd_update_index(int argc, * Allow the object layer to optimize adding multiple objects in * a batch. */ - transaction = odb_transaction_begin(the_repository->objects); + odb_transaction_begin_or_die(the_repository->objects, &transaction); while (ctx.argc) { if (parseopt_state != PARSE_OPT_DONE) parseopt_state = parse_options_step(&ctx, options, diff --git a/cache-tree.c b/cache-tree.c index 184f7e2635..1a7dfed9cf 100644 --- a/cache-tree.c +++ b/cache-tree.c @@ -490,7 +490,7 @@ int cache_tree_update(struct index_state *istate, int flags) trace_performance_enter(); trace2_region_enter("cache_tree", "update", istate->repo); - transaction = odb_transaction_begin(the_repository->objects); + odb_transaction_begin_or_die(the_repository->objects, &transaction); i = update_one(istate->cache_tree, istate->cache, istate->cache_nr, "", 0, &skip, flags); odb_transaction_commit(transaction); diff --git a/object-file.c b/object-file.c index e846c4469b..85654b3fb9 100644 --- a/object-file.c +++ b/object-file.c @@ -1387,8 +1387,9 @@ int index_fd(struct index_state *istate, struct object_id *oid, if (flags & INDEX_WRITE_OBJECT) { struct object_database *odb = the_repository->objects; - struct odb_transaction *transaction = odb_transaction_begin(odb); + struct odb_transaction *transaction; + odb_transaction_begin_or_die(odb, &transaction); ret = odb_transaction_write_object_stream(odb->transaction, &stream, xsize_t(st->st_size), diff --git a/odb/transaction.c b/odb/transaction.c index b16e07aebf..d3de01db50 100644 --- a/odb/transaction.c +++ b/odb/transaction.c @@ -2,14 +2,20 @@ #include "odb/source.h" #include "odb/transaction.h" -struct odb_transaction *odb_transaction_begin(struct object_database *odb) +int odb_transaction_begin(struct object_database *odb, + struct odb_transaction **out) { - if (odb->transaction) - return NULL; + int ret; - odb_source_begin_transaction(odb->sources, &odb->transaction); + if (odb->transaction) { + *out = NULL; + return 0; + } - return odb->transaction; + ret = odb_source_begin_transaction(odb->sources, out); + odb->transaction = *out; + + return ret; } void odb_transaction_commit(struct odb_transaction *transaction) diff --git a/odb/transaction.h b/odb/transaction.h index f4c1ebfaaa..cd6d50f2e5 100644 --- a/odb/transaction.h +++ b/odb/transaction.h @@ -1,6 +1,8 @@ #ifndef ODB_TRANSACTION_H #define ODB_TRANSACTION_H +#include "git-compat-util.h" +#include "gettext.h" #include "odb.h" #include "odb/source.h" @@ -33,11 +35,20 @@ struct odb_transaction { }; /* - * Starts an ODB transaction. Subsequent objects are written to the transaction - * and not committed until odb_transaction_commit() is invoked on the - * transaction. If the ODB already has a pending transaction, NULL is returned. + * Starts an ODB transaction and returns it via `out`. Subsequent objects are + * written to the transaction and not committed until odb_transaction_commit() + * is invoked on the transaction. Returns 0 on success and a negative value on + * error. If the ODB already has a pending transaction, `out` is set to NULL. */ -struct odb_transaction *odb_transaction_begin(struct object_database *odb); +int odb_transaction_begin(struct object_database *odb, + struct odb_transaction **out); + +static inline void odb_transaction_begin_or_die(struct object_database *odb, + struct odb_transaction **out) +{ + if (odb_transaction_begin(odb, out)) + die(_("failed to start ODB transaction")); +} /* * Commits an ODB transaction making the written objects visible. If the diff --git a/read-cache.c b/read-cache.c index 21829102ae..3e629de340 100644 --- a/read-cache.c +++ b/read-cache.c @@ -4042,7 +4042,7 @@ int add_files_to_cache(struct repository *repo, const char *prefix, * This function is invoked from commands other than 'add', which * may not have their own transaction active. */ - transaction = odb_transaction_begin(repo->objects); + odb_transaction_begin_or_die(repo->objects, &transaction); run_diff_files(&rev, DIFF_RACY_IS_MODIFIED); odb_transaction_commit(transaction);