odb: split `struct odb_transaction` into separate header

The current ODB transaction interface is colocated with other ODB interfaces in "odb.{c,h}". Subsequent commits will expand `struct odb_transaction` to support write operations on the transaction directly. To keep things organized and prevent "odb.{c,h}" from becoming more unwieldy, split out `struct odb_transaction` into a separate header. Signed-off-by: Justin Tobler <jltobler@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Justin Tobler committed May 14, 2026 at 13:37 UTC 5f6744d3eba6264ce78c8b507b1a1d3c0e540c37
12 files changed +74 -56
Makefile
+1
@@ -1219,6 +1219,7 @@ LIB_OBJS += odb.o
1219 LIB_OBJS += odb/source.o
1220 LIB_OBJS += odb/source-files.o
1221 LIB_OBJS += odb/streaming.o
1222 +LIB_OBJS += odb/transaction.o
1223 LIB_OBJS += oid-array.o
1224 LIB_OBJS += oidmap.o
1225 LIB_OBJS += oidset.o
builtin/add.c
+1
@@ -16,6 +16,7 @@
16 #include "run-command.h"
17 #include "object-file.h"
18 #include "odb.h"
19 +#include "odb/transaction.h"
20 #include "parse-options.h"
21 #include "path.h"
22 #include "preload-index.h"
builtin/unpack-objects.c
+1
@@ -9,6 +9,7 @@
9 #include "hex.h"
10 #include "object-file.h"
11 #include "odb.h"
12 +#include "odb/transaction.h"
13 #include "object.h"
14 #include "delta.h"
15 #include "pack.h"
builtin/update-index.c
+1
@@ -19,6 +19,7 @@
19 #include "tree-walk.h"
20 #include "object-file.h"
21 #include "odb.h"
22 +#include "odb/transaction.h"
23 #include "refs.h"
24 #include "resolve-undo.h"
25 #include "parse-options.h"
cache-tree.c
+1
@@ -10,6 +10,7 @@
10 #include "cache-tree.h"
11 #include "object-file.h"
12 #include "odb.h"
13 +#include "odb/transaction.h"
14 #include "read-cache-ll.h"
15 #include "replace-object.h"
16 #include "repository.h"
meson.build
+1
@@ -405,6 +405,7 @@ libgit_sources = [
405 'odb/source.c',
406 'odb/source-files.c',
407 'odb/streaming.c',
408 + 'odb/transaction.c',
409 'oid-array.c',
410 'oidmap.c',
411 'oidset.c',
object-file.c
+1
@@ -21,6 +21,7 @@
21 #include "object-file.h"
22 #include "odb.h"
23 #include "odb/streaming.h"
24 +#include "odb/transaction.h"
25 #include "oidtree.h"
26 #include "pack.h"
27 #include "packfile.h"
odb.c
-25
@@ -1069,28 +1069,3 @@ void odb_reprepare(struct object_database *o)
1069
1070 obj_read_unlock();
1071 }
1072 -
1073 -struct odb_transaction *odb_transaction_begin(struct object_database *odb)
1074 -{
1075 - if (odb->transaction)
1076 - return NULL;
1077 -
1078 - odb->transaction = odb_transaction_files_begin(odb->sources);
1079 -
1080 - return odb->transaction;
1081 -}
1082 -
1083 -void odb_transaction_commit(struct odb_transaction *transaction)
1084 -{
1085 - if (!transaction)
1086 - return;
1087 -
1088 - /*
1089 - * Ensure the transaction ending matches the pending transaction.
1090 - */
1091 - ASSERT(transaction == transaction->source->odb->transaction);
1092 -
1093 - transaction->commit(transaction);
1094 - transaction->source->odb->transaction = NULL;
1095 - free(transaction);
1096 -}
odb.h
-31
@@ -35,24 +35,6 @@ struct packed_git;
35 struct packfile_store;
36 struct cached_object_entry;
37
38 -/*
39 - * A transaction may be started for an object database prior to writing new
40 - * objects via odb_transaction_begin(). These objects are not committed until
41 - * odb_transaction_commit() is invoked. Only a single transaction may be pending
42 - * at a time.
43 - *
44 - * Each ODB source is expected to implement its own transaction handling.
45 - */
46 -struct odb_transaction;
47 -typedef void (*odb_transaction_commit_fn)(struct odb_transaction *transaction);
48 -struct odb_transaction {
49 - /* The ODB source the transaction is opened against. */
50 - struct odb_source *source;
51 -
52 - /* The ODB source specific callback invoked to commit a transaction. */
53 - odb_transaction_commit_fn commit;
54 -};
55 -
38 /*
39 * The object database encapsulates access to objects in a repository. It
40 * manages one or more sources that store the actual objects which are
@@ -154,19 +136,6 @@ void odb_close(struct object_database *o);
136 */
137 void odb_reprepare(struct object_database *o);
138
157 -/*
158 - * Starts an ODB transaction. Subsequent objects are written to the transaction
159 - * and not committed until odb_transaction_commit() is invoked on the
160 - * transaction. If the ODB already has a pending transaction, NULL is returned.
161 - */
162 -struct odb_transaction *odb_transaction_begin(struct object_database *odb);
163 -
164 -/*
165 - * Commits an ODB transaction making the written objects visible. If the
166 - * specified transaction is NULL, the function is a no-op.
167 - */
168 -void odb_transaction_commit(struct odb_transaction *transaction);
169 -
139 /*
140 * Find source by its object directory path. Returns a `NULL` pointer in case
141 * the source could not be found.
odb/transaction.c new
+28
@@ -0,0 +1,28 @@
1 +#include "git-compat-util.h"
2 +#include "object-file.h"
3 +#include "odb/transaction.h"
4 +
5 +struct odb_transaction *odb_transaction_begin(struct object_database *odb)
6 +{
7 + if (odb->transaction)
8 + return NULL;
9 +
10 + odb->transaction = odb_transaction_files_begin(odb->sources);
11 +
12 + return odb->transaction;
13 +}
14 +
15 +void odb_transaction_commit(struct odb_transaction *transaction)
16 +{
17 + if (!transaction)
18 + return;
19 +
20 + /*
21 + * Ensure the transaction ending matches the pending transaction.
22 + */
23 + ASSERT(transaction == transaction->source->odb->transaction);
24 +
25 + transaction->commit(transaction);
26 + transaction->source->odb->transaction = NULL;
27 + free(transaction);
28 +}
odb/transaction.h new
+38
@@ -0,0 +1,38 @@
1 +#ifndef ODB_TRANSACTION_H
2 +#define ODB_TRANSACTION_H
3 +
4 +#include "odb.h"
5 +#include "odb/source.h"
6 +
7 +/*
8 + * A transaction may be started for an object database prior to writing new
9 + * objects via odb_transaction_begin(). These objects are not committed until
10 + * odb_transaction_commit() is invoked. Only a single transaction may be pending
11 + * at a time.
12 + *
13 + * Each ODB source is expected to implement its own transaction handling.
14 + */
15 +struct odb_transaction;
16 +typedef void (*odb_transaction_commit_fn)(struct odb_transaction *transaction);
17 +struct odb_transaction {
18 + /* The ODB source the transaction is opened against. */
19 + struct odb_source *source;
20 +
21 + /* The ODB source specific callback invoked to commit a transaction. */
22 + odb_transaction_commit_fn commit;
23 +};
24 +
25 +/*
26 + * Starts an ODB transaction. Subsequent objects are written to the transaction
27 + * and not committed until odb_transaction_commit() is invoked on the
28 + * transaction. If the ODB already has a pending transaction, NULL is returned.
29 + */
30 +struct odb_transaction *odb_transaction_begin(struct object_database *odb);
31 +
32 +/*
33 + * Commits an ODB transaction making the written objects visible. If the
34 + * specified transaction is NULL, the function is a no-op.
35 + */
36 +void odb_transaction_commit(struct odb_transaction *transaction);
37 +
38 +#endif
read-cache.c
+1
@@ -20,6 +20,7 @@
20 #include "dir.h"
21 #include "object-file.h"
22 #include "odb.h"
23 +#include "odb/transaction.h"
24 #include "oid-array.h"
25 #include "tree.h"
26 #include "commit.h"