git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH v2 6/6] odb: add transaction interface

From
Justin Tobler <jltobler@gmail.com>
Date
Sep 15, 2025, 20:29 UTC
Message-ID
<20250915202956.3784935-7-jltobler@gmail.com>
In-Reply-To
<20250915202956.3784935-1-jltobler@gmail.com>

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>
---
 builtin/add.c            |  5 +++--
 builtin/unpack-objects.c |  4 ++--
 builtin/update-index.c   |  7 ++++---
 cache-tree.c             |  4 ++--
 object-file.c            | 12 +++++++-----
 object-file.h            |  6 +++---
 odb.c                    | 10 ++++++++++
 odb.h                    | 14 ++++++++++++++
 read-cache.c             |  4 ++--
 9 files changed, 47 insertions(+), 19 deletions(-)
diff --git a/builtin/add.c b/builtin/add.c
index 8294366d68..bf312c40be 100644
--- a/builtin/add.c
+++ b/builtin/add.c
@@ -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,
diff --git a/builtin/unpack-objects.c b/builtin/unpack-objects.c
index 4596fff0da..ef79e43715 100644
--- a/builtin/unpack-objects.c
+++ b/builtin/unpack-objects.c
@@ -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)
diff --git a/builtin/update-index.c b/builtin/update-index.c
index ee01c4e423..8a5907767b 100644
--- a/builtin/update-index.c
+++ b/builtin/update-index.c
@@ -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)
diff --git a/cache-tree.c b/cache-tree.c
index 7ad3225a71..f4a8753e27 100644
--- a/cache-tree.c
+++ b/cache-tree.c
@@ -491,12 +491,12 @@ int cache_tree_update(struct index_state *istate, int flags)
 	trace2_region_enter("cache_tree", "update", the_repository);
 
 	if (!the_repository->objects->transaction)
-		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");
diff --git a/object-file.c b/object-file.c
index 63195da2e8..0fc24b48da 100644
--- a/object-file.c
+++ b/object-file.c
@@ -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;
@@ -1623,14 +1623,14 @@ int index_fd(struct index_state *istate, struct object_id *oid,
 		struct odb_transaction *transaction = NULL;
 
 		if (!the_repository->objects->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);
@@ -1970,8 +1970,10 @@ int read_loose_object(struct repository *repo,
 	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)
 		BUG("ODB transaction already started");
 
@@ -1981,7 +1983,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;
diff --git a/object-file.h b/object-file.h
index 5925563f83..965f437ada 100644
--- a/object-file.h
+++ b/object-file.h
@@ -222,17 +222,17 @@ 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. Only a single transaction
  * can be pending at a time and must be ended before
  * beginning another.
  */
-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 2a92a018c4..af9534bfe1 100644
--- 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 a89b214390..48621f9402 100644
--- a/odb.h
+++ b/odb.h
@@ -185,6 +185,20 @@ 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. Caller are responsible to ensure there is only a single ODB
+ * transaction pending at a time.
+ */
+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.
diff --git a/read-cache.c b/read-cache.c
index 00acd8c858..e9a0ddfeb1 100644
--- a/read-cache.c
+++ b/read-cache.c
@@ -3973,11 +3973,11 @@ int add_files_to_cache(struct repository *repo, const char *prefix,
 	 * may not have their own transaction active.
 	 */
 	if (!repo->objects->transaction)
-		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;
-- 
2.51.0.193.g4975ec3473b
Previous: Justin ToblerNext: Justin Tobler
Message 31 of 38 in “odb: add transaction interfaces to ODB subsystem”
  1. 0/6 odb: add transaction interfaces to ODB subsystemJustin Tobler, Sep 9, 2025
  2. 1/6 bulk-checkin: remove ODB transaction nestingJustin Tobler, Sep 9, 2025
  3. Patrick SteinhardtSep 11, 2025
  4. Justin ToblerSep 11, 2025
  5. Taylor BlauSep 15, 2025
  6. Justin ToblerSep 16, 2025
  7. Junio C HamanoSep 16, 2025
  8. Justin ToblerSep 16, 2025
  9. 2/6 builtin/update-index: end ODB transaction when --verbose is specifiedJustin Tobler, Sep 9, 2025
  10. Patrick SteinhardtSep 11, 2025
  11. Justin ToblerSep 11, 2025
  12. Patrick SteinhardtSep 15, 2025
  13. Justin ToblerSep 15, 2025
  14. Justin ToblerSep 15, 2025
  15. 3/6 bulk-checkin: drop flush_odb_transaction()Justin Tobler, Sep 9, 2025
  16. 4/6 object-file: relocate ODB transaction codeJustin Tobler, Sep 9, 2025
  17. 5/6 object-file: update naming from bulk-checkinJustin Tobler, Sep 9, 2025
  18. 6/6 odb: add transaction interfaceJustin Tobler, Sep 9, 2025
  19. Patrick SteinhardtSep 11, 2025
  20. Justin ToblerSep 11, 2025
  21. 0/6 odb: add transaction interfaces to ODB subsystemJustin Tobler, Sep 15, 2025
  22. 1/6 bulk-checkin: remove ODB transaction nestingJustin Tobler, Sep 15, 2025
  23. Karthik NayakSep 16, 2025
  24. Justin ToblerSep 16, 2025
  25. 2/6 builtin/update-index: end ODB transaction when --verbose is specifiedJustin Tobler, Sep 15, 2025
  26. Karthik NayakSep 16, 2025
  27. Justin ToblerSep 16, 2025
  28. 3/6 bulk-checkin: drop flush_odb_transaction()Justin Tobler, Sep 15, 2025
  29. 4/6 object-file: relocate ODB transaction codeJustin Tobler, Sep 15, 2025
  30. 5/6 object-file: update naming from bulk-checkinJustin Tobler, Sep 15, 2025
  31. 6/6 odb: add transaction interfaceJustin Tobler, Sep 15, 2025
  32. 0/6 odb: add transaction interfaces to ODB subsystemJustin Tobler, Sep 16, 2025
  33. 2/6 builtin/update-index: end ODB transaction when --verbose is specifiedJustin Tobler, Sep 16, 2025
  34. 1/6 bulk-checkin: remove ODB transaction nestingJustin Tobler, Sep 16, 2025
  35. 3/6 bulk-checkin: drop flush_odb_transaction()Justin Tobler, Sep 16, 2025
  36. 4/6 object-file: relocate ODB transaction codeJustin Tobler, Sep 16, 2025
  37. 5/6 object-file: update naming from bulk-checkinJustin Tobler, Sep 16, 2025
  38. 6/6 odb: add transaction interfaceJustin Tobler, Sep 16, 2025

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.