summaryrefslogtreecommitdiff
path: root/odb/transaction.c
AgeCommit message (Collapse)AuthorFilesLines
13 daysMerge branch 'jt/receive-pack-pluggable-writes'Junio C Hamano1-0/+21
The 'git receive-pack' command has been updated to use a new ODB transaction interface for writing incoming packfiles, making it more backend-agnostic. * jt/receive-pack-pluggable-writes: odb/transaction: add transaction interface to write packfiles odb: return temporary ODB source when set builtin/receive-pack: explicitly pass packfile fd builtin/receive-pack: report unpack errors via strbuf builtin/receive-pack: lift global state out of unpack() builtin/receive-pack: read unpack limit config lazily builtin/receive-pack: pass shallow file explicitly odb/transaction: add transaction finalize interface builtin/receive-pack: properly clean up keep files
2026-08-20odb/transaction: add transaction interface to write packfilesJustin Tobler1-0/+7
In git-receive-pack(1), the incoming packfile is written to the ODB via `unpack()`, which spawns git-index-pack(1) or git-unpack-objects(1) directly. With pluggable object databases, an alternative backend may need to handle writing packfile data differently though. Introduce `odb_transaction_write_pack()` as a generic interface to handle writing a packfile to a transaction and use the logic from `unpack()` as the "files" backend implementation. Note that when storing the objects as a packfile, git-index-pack(1) also writes a ".keep" lockfile next to it to prevent a concurrent repack from removing the new pack prior to reference updates being performed. The "files" transaction backend is responsible for managing these ".keep" files and removes them post-commit once the transaction is finalized. Call sites in git-receive-pack(1) are updated accordingly. Signed-off-by: Justin Tobler <jltobler@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-08-20odb/transaction: add transaction finalize interfaceJustin Tobler1-0/+14
When committing an ODB transaction via `odb_transaction_commit()`, the staged objects are made visible and the underlying transaction is freed at the same time. Coupling these two steps does not leave room for any post-commit transaction operations to be introduced though. Such a capability is useful if an ODB transaction backend needs to hold on to lockfiles after transaction commit until references are updated, as is the case with the existing "files" backend in git-receive-pack(1). Stop freeing the transaction in `odb_transaction_commit()` and introduce `odb_transaction_finalize()` to explicitly clean up the transaction accordingly. Note that the finalize interface also provides an optional callback for any backend-specific deferred cleanup. In a subsequent commit, the "files" transaction backend will use this to remove ".keep" files generated for packfiles received via git-receive-pack(1) after references have been updated. In preparation for this, the `odb_transaction_finalize()` call site in git-receive-pack(1) is made after the reference updates are finished. All other callers commit a transaction and immediately finalize it without any work happening in between those two operations. Consequently, they cannot meaningfully recover in case either of them would fail, and spelling out these two separate steps with proper error handling would be quite repetitive and pointless. Introduce a helper `odb_transaction_commit_and_finalize_or_die()` for those call sites and update them accordingly. Signed-off-by: Justin Tobler <jltobler@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-08-05odb/streaming: consolidate read and write streamsPatrick Steinhardt1-1/+1
The `struct odb_read_stream` and `struct odb_write_stream` both provide the same functionality: they allow a caller to read object data from an arbitrary source. Historically, the only difference was that the read stream was used to read data out of the object database, whereas the write stream was used to write data into the object database, but the interfaces were mostly the same. Over the preceding commits we have refactored the write stream to have almost exactly the same interface as the read stream. With these refactorings we can now easily merge those two streams into a single interface that's used for both use cases. While most of the changes are mechanical, there are two sites that need special mention: - "builtin/unpack-objects.c" creates a write stream from compressed object data. - "odb/streaming.c" creates a write stream from a file descriptor. Adapting these sites to yield the new stream type requires a couple more changes. Most importantly, instead of embedding the pointer to the data in `struct odb_write_stream`, we now allocate a structure that wraps the new `struct odb_stream` base. Other than that though, the changes are rather straight forward. Some of the structures and functions are now somewhat misnamed. These will be fixed in subsequent commits. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-08-05odb/streaming: track write stream size in the structurePatrick Steinhardt1-2/+2
When passing around a `struct odb_write_stream` we typically also have to pass the number of bytes that the stream will yield. This is required because the object header itself contains that size, and consequently we cannot write the header without that information. Move this information into the stream itself so that it becomes self- describing. In addition to that, this also brings the `struct odb_write_stream` a bit closer to the `struct odb_read_stream` so that we can eventually merge both stream types. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-07-10odb/transaction: introduce ODB transaction flagsJustin Tobler1-2/+3
The temporary directory used by git-receive-pack(1) to write objects is managed slightly differently than how it is done via ODB transactions: - The temporary directory is eagerly created upfront, instead of waiting for the first object write. - The prefix name of the temporary directory is "incoming" instead of "bulk-fsync". In a subsequent commit, git-receive-pack(1) will use ODB transactions instead of `tmp_objdir` directly. To provide a means to configure the same transaction behavior, introduce `enum odb_transaction_flags` and the ODB_TRANSACTION_RECEIVE flag intended as a signal for ODB transactions using the "files" backend to be set up for git-receive-pack(1). Transaction call sites are updated accordingly to provide the required flag parameter. Signed-off-by: Justin Tobler <jltobler@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-07-10odb/transaction: add transaction env interfaceJustin Tobler1-0/+8
The ODB transaction backend is responsible for creating/managing its own staging area for writing objects. Other child processes spawned by Git may need access to uncommitted objects or write new objects in the staging area though. Introduce `odb_transaction_env()` which is expected to provide the set of environment variables needed by a child process to access the transaction's staging area. Signed-off-by: Justin Tobler <jltobler@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-07-10odb/transaction: propagate commit errorsJustin Tobler1-3/+7
When `odb_transaction_commit()` is invoked, the return value of the backend commit callback is silently discarded. A backend has no way to signal that committing failed, such as when the "files" backend cannot migrate its temporary object directory into the permanent ODB. In a subsequent commit, git-receive-pack(1) starts using ODB transaction to stage objects and consequently cares about such failures so it can handle the error appropriately. Change the commit callback signature to return an int error code and have `odb_transaction_commit()` forward it accordingly. Signed-off-by: Justin Tobler <jltobler@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-07-10odb/transaction: propagate begin errorsJustin Tobler1-4/+10
When `odb_transaction_begin()` is invoked, the function returns the transaction pointer directly. There is no way for the backend to signal that it failed to set up its state, such as when creating the temporary object directory backing the transaction. In a subsequent commit, git-receive-pack(1) starts using ODB transactions and needs to be able to report such failures rather than silently ignore them. Refactor `odb_transaction_begin()` to return an int error code and write the resulting transaction into an out parameter. Also introduce `odb_transaction_begin_or_die()` as a convenience for callsites that do not need to handle errors explicitly. Note that `odb_transaction_begin()` now returns an error when the ODB already has an inflight transaction pending. ODB transaction call sites that may encounter an inflight transaction are updated to explicitly handle this case. Signed-off-by: Justin Tobler <jltobler@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-05-15odb/transaction: make `write_object_stream()` pluggableJustin Tobler1-0/+7
How an ODB transaction handles writing objects is expected to vary between implementations. Introduce a new `write_object_stream()` callback in `struct odb_transaction` to make this function pluggable. Rename `index_blob_packfile_transaction()` to `odb_transaction_files_write_object_stream()` and wire it up for use with `struct odb_transaction_files` accordingly. Signed-off-by: Justin Tobler <jltobler@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-05-15odb/transaction: use pluggable `begin_transaction()`Justin Tobler1-2/+2
Each ODB source is expected to provide an ODB transaction implementation that should be used when starting a transaction. With d6fc6fe6f8 (odb/source: make `begin_transaction()` function pluggable, 2026-03-05), the `struct odb_source` now provides a pluggable callback for beginning transactions. Use the callback provided by the ODB source accordingly. Signed-off-by: Justin Tobler <jltobler@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-05-15odb: split `struct odb_transaction` into separate headerJustin Tobler1-0/+28
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>