odb: add transaction interface
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>
Justin Tobler committed
Sep 16, 2025 at 13:29 UTC
ce1661f9da70ea2ffcb54f7b544410fad26e965d
9 files changed
+46
-19
builtin/add.c
+3
-2
@@ -15,6 +15,7 @@
15
#include "pathspec.h"
16
#include "run-command.h"
17
#include "object-file.h"
18
+#include "odb.h"
19
#include "parse-options.h"
20
#include "path.h"
21
#include "preload-index.h"
@@ -575,7 +576,7 @@ int cmd_add(int argc,
576
string_list_clear(&only_match_skip_worktree, 0);
577
}
578
578
- transaction = begin_odb_transaction(repo->objects);
579
+ transaction = odb_transaction_begin(repo->objects);
580
581
ps_matched = xcalloc(pathspec.nr, 1);
582
if (add_renormalize)
@@ -594,7 +595,7 @@ int cmd_add(int argc,
595
596
if (chmod_arg && pathspec.nr)
597
exit_status |= chmod_pathspec(repo, &pathspec, chmod_arg[0], show_only);
597
- end_odb_transaction(transaction);
598
+ odb_transaction_commit(transaction);
599
600
finish:
601
if (write_locked_index(repo->index, &lock_file,
builtin/unpack-objects.c
+2
-2
@@ -599,12 +599,12 @@ static void unpack_all(void)
599
progress = start_progress(the_repository,
600
_("Unpacking objects"), nr_objects);
601
CALLOC_ARRAY(obj_list, nr_objects);
602
- transaction = begin_odb_transaction(the_repository->objects);
602
+ transaction = odb_transaction_begin(the_repository->objects);
603
for (i = 0; i < nr_objects; i++) {
604
unpack_one(i);
605
display_progress(progress, i + 1);
606
}
607
- end_odb_transaction(transaction);
607
+ odb_transaction_commit(transaction);
608
stop_progress(&progress);
609
610
if (delta_list)
builtin/update-index.c
+4
-3
@@ -18,6 +18,7 @@
18
#include "cache-tree.h"
19
#include "tree-walk.h"
20
#include "object-file.h"
21
+#include "odb.h"
22
#include "refs.h"
23
#include "resolve-undo.h"
24
#include "parse-options.h"
@@ -1122,7 +1123,7 @@ int cmd_update_index(int argc,
1123
* Allow the object layer to optimize adding multiple objects in
1124
* a batch.
1125
*/
1125
- transaction = begin_odb_transaction(the_repository->objects);
1126
+ transaction = odb_transaction_begin(the_repository->objects);
1127
while (ctx.argc) {
1128
if (parseopt_state != PARSE_OPT_DONE)
1129
parseopt_state = parse_options_step(&ctx, options,
@@ -1152,7 +1153,7 @@ int cmd_update_index(int argc,
1153
* a transaction.
1154
*/
1155
if (transaction && verbose) {
1155
- end_odb_transaction(transaction);
1156
+ odb_transaction_commit(transaction);
1157
transaction = NULL;
1158
}
1159
@@ -1220,7 +1221,7 @@ int cmd_update_index(int argc,
1221
/*
1222
* By now we have added all of the new objects
1223
*/
1223
- end_odb_transaction(transaction);
1224
+ odb_transaction_commit(transaction);
1225
1226
if (split_index > 0) {
1227
if (repo_config_get_split_index(the_repository) == 0)
cache-tree.c
+2
-2
@@ -489,10 +489,10 @@ int cache_tree_update(struct index_state *istate, int flags)
489
490
trace_performance_enter();
491
trace2_region_enter("cache_tree", "update", the_repository);
492
- transaction = begin_odb_transaction(the_repository->objects);
492
+ transaction = odb_transaction_begin(the_repository->objects);
493
i = update_one(istate->cache_tree, istate->cache, istate->cache_nr,
494
"", 0, &skip, flags);
495
- end_odb_transaction(transaction);
495
+ odb_transaction_commit(transaction);
496
trace2_region_leave("cache_tree", "update", the_repository);
497
trace_performance_leave("cache_tree_update");
498
if (i < 0)
object-file.c
+7
-5
@@ -691,7 +691,7 @@ static void prepare_loose_object_transaction(struct odb_transaction *transaction
691
* We lazily create the temporary object directory
692
* the first time an object might be added, since
693
* callers may not know whether any objects will be
694
- * added at the time they call begin_odb_transaction.
694
+ * added at the time they call object_file_transaction_begin.
695
*/
696
if (!transaction || transaction->objdir)
697
return;
@@ -1622,12 +1622,12 @@ int index_fd(struct index_state *istate, struct object_id *oid,
1622
} else {
1623
struct odb_transaction *transaction;
1624
1625
- transaction = begin_odb_transaction(the_repository->objects);
1625
+ transaction = odb_transaction_begin(the_repository->objects);
1626
ret = index_blob_packfile_transaction(the_repository->objects->transaction,
1627
oid, fd,
1628
xsize_t(st->st_size),
1629
path, flags);
1630
- end_odb_transaction(transaction);
1630
+ odb_transaction_commit(transaction);
1631
}
1632
1633
close(fd);
@@ -1967,8 +1967,10 @@ out:
1967
return ret;
1968
}
1969
1970
-struct odb_transaction *begin_odb_transaction(struct object_database *odb)
1970
+struct odb_transaction *object_file_transaction_begin(struct odb_source *source)
1971
{
1972
+ struct object_database *odb = source->odb;
1973
+
1974
if (odb->transaction)
1975
return NULL;
1976
@@ -1978,7 +1980,7 @@ struct odb_transaction *begin_odb_transaction(struct object_database *odb)
1980
return odb->transaction;
1981
}
1982
1981
-void end_odb_transaction(struct odb_transaction *transaction)
1983
+void object_file_transaction_commit(struct odb_transaction *transaction)
1984
{
1985
if (!transaction)
1986
return;
object-file.h
+3
-3
@@ -222,16 +222,16 @@ struct odb_transaction;
222
223
/*
224
* Tell the object database to optimize for adding
225
- * multiple objects. end_odb_transaction must be called
225
+ * multiple objects. object_file_transaction_commit must be called
226
* to make new objects visible. If a transaction is already
227
* pending, NULL is returned.
228
*/
229
-struct odb_transaction *begin_odb_transaction(struct object_database *odb);
229
+struct odb_transaction *object_file_transaction_begin(struct odb_source *source);
230
231
/*
232
* Tell the object database to make any objects from the
233
* current transaction visible.
234
*/
235
-void end_odb_transaction(struct odb_transaction *transaction);
235
+void object_file_transaction_commit(struct odb_transaction *transaction);
236
237
#endif /* OBJECT_FILE_H */
odb.c
+10
@@ -1051,3 +1051,13 @@ void odb_clear(struct object_database *o)
1051
hashmap_clear(&o->pack_map);
1052
string_list_clear(&o->submodule_source_paths, 0);
1053
}
1054
+
1055
+struct odb_transaction *odb_transaction_begin(struct object_database *odb)
1056
+{
1057
+ return object_file_transaction_begin(odb->sources);
1058
+}
1059
+
1060
+void odb_transaction_commit(struct odb_transaction *transaction)
1061
+{
1062
+ object_file_transaction_commit(transaction);
1063
+}
odb.h
+13
@@ -185,6 +185,19 @@ struct object_database {
185
struct object_database *odb_new(struct repository *repo);
186
void odb_clear(struct object_database *o);
187
188
+/*
189
+ * Starts an ODB transaction. Subsequent objects are written to the transaction
190
+ * and not committed until odb_transaction_commit() is invoked on the
191
+ * transaction. If the ODB already has a pending transaction, NULL is returned.
192
+ */
193
+struct odb_transaction *odb_transaction_begin(struct object_database *odb);
194
+
195
+/*
196
+ * Commits an ODB transaction making the written objects visible. If the
197
+ * specified transaction is NULL, the function is a no-op.
198
+ */
199
+void odb_transaction_commit(struct odb_transaction *transaction);
200
+
201
/*
202
* Find source by its object directory path. Dies in case the source couldn't
203
* be found.
read-cache.c
+2
-2
@@ -3972,9 +3972,9 @@ int add_files_to_cache(struct repository *repo, const char *prefix,
3972
* This function is invoked from commands other than 'add', which
3973
* may not have their own transaction active.
3974
*/
3975
- transaction = begin_odb_transaction(repo->objects);
3975
+ transaction = odb_transaction_begin(repo->objects);
3976
run_diff_files(&rev, DIFF_RACY_IS_MODIFIED);
3977
- end_odb_transaction(transaction);
3977
+ odb_transaction_commit(transaction);
3978
3979
release_revisions(&rev);
3980
return !!data.add_errors;