]> git.ipfire.org Git - thirdparty/git.git/commitdiff
odb: add transaction interface
authorJustin Tobler <jltobler@gmail.com>
Tue, 16 Sep 2025 18:29:38 +0000 (13:29 -0500)
committerJunio C Hamano <gitster@pobox.com>
Tue, 16 Sep 2025 18:37:06 +0000 (11:37 -0700)
Transactions are managed via the {begin,end}_odb_transaction() function
in the object-file subsystem and its implementation is specific to the
files object source. Introduce odb_transaction_{begin,commit}() in the
odb subsystem to provide an eventual object source agnostic means to
manage transactions.

Update call sites to instead manage transactions through the odb
subsystem. Also rename {begin,end}_odb_transaction() functions to
object_file_transaction_{begin,commit}() to clarify the object source it
supports.

Signed-off-by: Justin Tobler <jltobler@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
builtin/add.c
builtin/unpack-objects.c
builtin/update-index.c
cache-tree.c
object-file.c
object-file.h
odb.c
odb.h
read-cache.c

index 8294366d68a1defb7303326f89bf80d474273d6a..bf312c40be9789cf2bda329d48d53c49c0e12470 100644 (file)
@@ -15,6 +15,7 @@
 #include "pathspec.h"
 #include "run-command.h"
 #include "object-file.h"
+#include "odb.h"
 #include "parse-options.h"
 #include "path.h"
 #include "preload-index.h"
@@ -575,7 +576,7 @@ int cmd_add(int argc,
                string_list_clear(&only_match_skip_worktree, 0);
        }
 
-       transaction = begin_odb_transaction(repo->objects);
+       transaction = odb_transaction_begin(repo->objects);
 
        ps_matched = xcalloc(pathspec.nr, 1);
        if (add_renormalize)
@@ -594,7 +595,7 @@ int cmd_add(int argc,
 
        if (chmod_arg && pathspec.nr)
                exit_status |= chmod_pathspec(repo, &pathspec, chmod_arg[0], show_only);
-       end_odb_transaction(transaction);
+       odb_transaction_commit(transaction);
 
 finish:
        if (write_locked_index(repo->index, &lock_file,
index 4596fff0dad58eb327ae4a548cbbbbc1b51a3023..ef79e43715d362d2907c23b5613d6fdaf9a96c80 100644 (file)
@@ -599,12 +599,12 @@ static void unpack_all(void)
                progress = start_progress(the_repository,
                                          _("Unpacking objects"), nr_objects);
        CALLOC_ARRAY(obj_list, nr_objects);
-       transaction = begin_odb_transaction(the_repository->objects);
+       transaction = odb_transaction_begin(the_repository->objects);
        for (i = 0; i < nr_objects; i++) {
                unpack_one(i);
                display_progress(progress, i + 1);
        }
-       end_odb_transaction(transaction);
+       odb_transaction_commit(transaction);
        stop_progress(&progress);
 
        if (delta_list)
index ee01c4e423da43c4c952389940da938ef11ea5f1..8a5907767bf297eefcb0c6de5441cabd567536fd 100644 (file)
@@ -18,6 +18,7 @@
 #include "cache-tree.h"
 #include "tree-walk.h"
 #include "object-file.h"
+#include "odb.h"
 #include "refs.h"
 #include "resolve-undo.h"
 #include "parse-options.h"
@@ -1122,7 +1123,7 @@ int cmd_update_index(int argc,
         * Allow the object layer to optimize adding multiple objects in
         * a batch.
         */
-       transaction = begin_odb_transaction(the_repository->objects);
+       transaction = odb_transaction_begin(the_repository->objects);
        while (ctx.argc) {
                if (parseopt_state != PARSE_OPT_DONE)
                        parseopt_state = parse_options_step(&ctx, options,
@@ -1152,7 +1153,7 @@ int cmd_update_index(int argc,
                         * a transaction.
                         */
                        if (transaction && verbose) {
-                               end_odb_transaction(transaction);
+                               odb_transaction_commit(transaction);
                                transaction = NULL;
                        }
 
@@ -1220,7 +1221,7 @@ int cmd_update_index(int argc,
        /*
         * By now we have added all of the new objects
         */
-       end_odb_transaction(transaction);
+       odb_transaction_commit(transaction);
 
        if (split_index > 0) {
                if (repo_config_get_split_index(the_repository) == 0)
index 79ddf6b72780fd06f9febbfb3ed4e4082238e27b..2aba47060e95d49463a5de78fc29fd601ae0c281 100644 (file)
@@ -489,10 +489,10 @@ int cache_tree_update(struct index_state *istate, int flags)
 
        trace_performance_enter();
        trace2_region_enter("cache_tree", "update", the_repository);
-       transaction = begin_odb_transaction(the_repository->objects);
+       transaction = odb_transaction_begin(the_repository->objects);
        i = update_one(istate->cache_tree, istate->cache, istate->cache_nr,
                       "", 0, &skip, flags);
-       end_odb_transaction(transaction);
+       odb_transaction_commit(transaction);
        trace2_region_leave("cache_tree", "update", the_repository);
        trace_performance_leave("cache_tree_update");
        if (i < 0)
index 8103a2bf413e56fd3e0dc04b7e1022464bdd61dd..17a236d2fe121bc447f73138c9db4a651b07ca22 100644 (file)
@@ -691,7 +691,7 @@ static void prepare_loose_object_transaction(struct odb_transaction *transaction
         * We lazily create the temporary object directory
         * the first time an object might be added, since
         * callers may not know whether any objects will be
-        * added at the time they call begin_odb_transaction.
+        * added at the time they call object_file_transaction_begin.
         */
        if (!transaction || transaction->objdir)
                return;
@@ -1622,12 +1622,12 @@ int index_fd(struct index_state *istate, struct object_id *oid,
        } else {
                struct odb_transaction *transaction;
 
-               transaction = begin_odb_transaction(the_repository->objects);
+               transaction = odb_transaction_begin(the_repository->objects);
                ret = index_blob_packfile_transaction(the_repository->objects->transaction,
                                                      oid, fd,
                                                      xsize_t(st->st_size),
                                                      path, flags);
-               end_odb_transaction(transaction);
+               odb_transaction_commit(transaction);
        }
 
        close(fd);
@@ -1967,8 +1967,10 @@ out:
        return ret;
 }
 
-struct odb_transaction *begin_odb_transaction(struct object_database *odb)
+struct odb_transaction *object_file_transaction_begin(struct odb_source *source)
 {
+       struct object_database *odb = source->odb;
+
        if (odb->transaction)
                return NULL;
 
@@ -1978,7 +1980,7 @@ struct odb_transaction *begin_odb_transaction(struct object_database *odb)
        return odb->transaction;
 }
 
-void end_odb_transaction(struct odb_transaction *transaction)
+void object_file_transaction_commit(struct odb_transaction *transaction)
 {
        if (!transaction)
                return;
index 6323d2e63c00ab3f24880a36c8a6e190ac4d8304..3fd48dcafbf1dc797efabd489e68720e521a38d2 100644 (file)
@@ -222,16 +222,16 @@ struct odb_transaction;
 
 /*
  * Tell the object database to optimize for adding
- * multiple objects. end_odb_transaction must be called
+ * multiple objects. object_file_transaction_commit must be called
  * to make new objects visible. If a transaction is already
  * pending, NULL is returned.
  */
-struct odb_transaction *begin_odb_transaction(struct object_database *odb);
+struct odb_transaction *object_file_transaction_begin(struct odb_source *source);
 
 /*
  * Tell the object database to make any objects from the
  * current transaction visible.
  */
-void end_odb_transaction(struct odb_transaction *transaction);
+void object_file_transaction_commit(struct odb_transaction *transaction);
 
 #endif /* OBJECT_FILE_H */
diff --git a/odb.c b/odb.c
index 2a92a018c42940f131edd4e7cacd3454e66ee370..af9534bfe1cdf548edb87e25d196ec89a453fac4 100644 (file)
--- a/odb.c
+++ b/odb.c
@@ -1051,3 +1051,13 @@ void odb_clear(struct object_database *o)
        hashmap_clear(&o->pack_map);
        string_list_clear(&o->submodule_source_paths, 0);
 }
+
+struct odb_transaction *odb_transaction_begin(struct object_database *odb)
+{
+       return object_file_transaction_begin(odb->sources);
+}
+
+void odb_transaction_commit(struct odb_transaction *transaction)
+{
+       object_file_transaction_commit(transaction);
+}
diff --git a/odb.h b/odb.h
index a89b2143909920881f5d4916cf5ae81f95f24958..82093753c84ca6125101eb2a7b9762aa30a92369 100644 (file)
--- a/odb.h
+++ b/odb.h
@@ -185,6 +185,19 @@ struct object_database {
 struct object_database *odb_new(struct repository *repo);
 void odb_clear(struct object_database *o);
 
+/*
+ * 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.
+ */
+struct odb_transaction *odb_transaction_begin(struct object_database *odb);
+
+/*
+ * Commits an ODB transaction making the written objects visible. If the
+ * specified transaction is NULL, the function is a no-op.
+ */
+void odb_transaction_commit(struct odb_transaction *transaction);
+
 /*
  * Find source by its object directory path. Dies in case the source couldn't
  * be found.
index 80591eecedc2076b12a81fc601be1ed9688ae1e4..94098a3861403c400ff45eb87c51ba8cbfcafeab 100644 (file)
@@ -3972,9 +3972,9 @@ 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 = begin_odb_transaction(repo->objects);
+       transaction = odb_transaction_begin(repo->objects);
        run_diff_files(&rev, DIFF_RACY_IS_MODIFIED);
-       end_odb_transaction(transaction);
+       odb_transaction_commit(transaction);
 
        release_revisions(&rev);
        return !!data.add_errors;