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

[PATCH 05/13] odb: move logic to disable ref updates into repo

From
Patrick Steinhardt <ps@pks.im>
Date
Nov 19, 2025, 07:50 UTC
Message-ID
<20251119-b4-pks-odb-creation-v1-5-2b2ed2612cb6@pks.im>
In-Reply-To
<20251119-b4-pks-odb-creation-v1-0-2b2ed2612cb6@pks.im>

Our object database sources have a field `disable_ref_updates`. This field can obviously be set to disable reference updates, but it is somewhat curious that this logic is hosted by the object database.

The reason for this is that it was primarily added to keep us from accidentally updating references while an ODB transaction is ongoing. Any objects part of the transaction have not yet been committed to disk, so new references that point to them might get corrupted in case we never end up committing the transaction. As such, whenever we create a new transaction we set up a new temporary ODB source and mark it as disabling reference updates.

This has one (and only one?) upside: once we have committed the transaction, the temporary source will be dropped and thus we clean up the disabled reference updates automatically. But other than that, it's somewhat misdesigned:

  - We can have multiple ODB sources, but only the currently active
    source inhibits reference updates.
  - We're mixing concerns of the refbd with the ODB.

Arguably, the decision of whether we can update references or not should be handled by the refdb. But that wouldn't be a great fit either, as there can be one refdb per worktree. So we'd again have the same problem that a "global" intent becomes localized to a specific instance.

Instead, move the setting into the repository. While at it, convert it into a boolean.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
---
 odb.c        | 3 ++-
 odb.h        | 7 -------
 refs.c       | 2 +-
 repository.c | 2 +-
 repository.h | 9 ++++++++-
 setup.c      | 2 +-
 6 files changed, 13 insertions(+), 12 deletions(-)
diff --git a/odb.c b/odb.c
index 29cf6496c5..ccc6e999e7 100644
--- a/odb.c
+++ b/odb.c
@@ -360,7 +360,7 @@ struct odb_source *odb_set_temporary_primary_source(struct object_database *odb,
 	 * Disable ref updates while a temporary odb is active, since
 	 * the objects in the database may roll back.
 	 */
-	source->disable_ref_updates = 1;
+	odb->repo->disable_ref_updates = true;
 	source->will_destroy = will_destroy;
 	source->next = odb->sources;
 	odb->sources = source;
@@ -387,6 +387,7 @@ void odb_restore_primary_source(struct object_database *odb,
 	if (cur_source->next != restore_source)
 		BUG("we expect the old primary object store to be the first alternate");
 
+	odb->repo->disable_ref_updates = false;
 	odb->sources = restore_source;
 	odb_source_free(cur_source);
 }
diff --git a/odb.h b/odb.h
index 77b313b784..99c4d48972 100644
--- a/odb.h
+++ b/odb.h
@@ -66,13 +66,6 @@ struct odb_source {
 	 */
 	bool local;
 
-	/*
-	 * This is a temporary object store created by the tmp_objdir
-	 * facility. Disable ref updates since the objects in the store
-	 * might be discarded on rollback.
-	 */
-	int disable_ref_updates;
-
 	/*
 	 * This object store is ephemeral, so there is no need to fsync.
 	 */
diff --git a/refs.c b/refs.c
index 965381367e..6c7283d9eb 100644
--- a/refs.c
+++ b/refs.c
@@ -2491,7 +2491,7 @@ int ref_transaction_prepare(struct ref_transaction *transaction,
 		break;
 	}
 
-	if (refs->repo->objects->sources->disable_ref_updates) {
+	if (refs->repo->disable_ref_updates) {
 		strbuf_addstr(err,
 			      _("ref updates forbidden inside quarantine environment"));
 		return -1;
diff --git a/repository.c b/repository.c
index 3c8b3813b0..455c2d279f 100644
--- a/repository.c
+++ b/repository.c
@@ -179,7 +179,7 @@ void repo_set_gitdir(struct repository *repo,
 		repo->objects->sources->path = objects_path;
 	}
 
-	repo->objects->sources->disable_ref_updates = o->disable_ref_updates;
+	repo->disable_ref_updates = o->disable_ref_updates;
 
 	free(repo->objects->alternate_db);
 	repo->objects->alternate_db = xstrdup_or_null(o->alternate_db);
diff --git a/repository.h b/repository.h
index 5808a5d610..614649413b 100644
--- a/repository.h
+++ b/repository.h
@@ -71,6 +71,13 @@ struct repository {
 	 */
 	struct ref_store *refs_private;
 
+	/*
+	 * Disable ref updates. This is especially used in contexts where
+	 * transactions may still be rolled back so that we don't start to
+	 * reference objects that may vanish.
+	 */
+	bool disable_ref_updates;
+
 	/*
 	 * A strmap of ref_stores, stored by submodule name, accessible via
 	 * `repo_get_submodule_ref_store()`.
@@ -187,7 +194,7 @@ struct set_gitdir_args {
 	const char *graft_file;
 	const char *index_file;
 	const char *alternate_db;
-	int disable_ref_updates;
+	bool disable_ref_updates;
 };
 
 void repo_set_gitdir(struct repository *repo, const char *root,
diff --git a/setup.c b/setup.c
index 8bf52df716..a752e9fc84 100644
--- a/setup.c
+++ b/setup.c
@@ -1682,7 +1682,7 @@ void setup_git_env(const char *git_dir)
 	args.index_file = getenv_safe(&to_free, INDEX_ENVIRONMENT);
 	args.alternate_db = getenv_safe(&to_free, ALTERNATE_DB_ENVIRONMENT);
 	if (getenv(GIT_QUARANTINE_ENVIRONMENT)) {
-		args.disable_ref_updates = 1;
+		args.disable_ref_updates = true;
 	}
 
 	repo_set_gitdir(the_repository, git_dir, &args);
-- 
2.52.0.rc2.482.gaa765fefd0.dirty
Previous: Patrick SteinhardtNext: Junio C Hamano
Message 6 of 21 in “Centralize management of object database sources”
  1. 00/13 Centralize management of object database sourcesPatrick Steinhardt, Nov 19, 2025
  2. 01/13 path: move `enter_repo()` into "setup.c"Patrick Steinhardt, Nov 19, 2025
  3. 02/13 setup: convert `set_git_dir()` to have file scopePatrick Steinhardt, Nov 19, 2025
  4. 03/13 odb: adopt logic to close object databasesPatrick Steinhardt, Nov 19, 2025
  5. 04/13 odb: refactor `odb_clear()` to `odb_free()`Patrick Steinhardt, Nov 19, 2025
  6. 05/13 odb: move logic to disable ref updates into repoPatrick Steinhardt, Nov 19, 2025
  7. Junio C HamanoNov 19, 2025
  8. Patrick SteinhardtNov 21, 2025
  9. 06/13 oidset: introduce `oidset_equal()`Patrick Steinhardt, Nov 19, 2025
  10. Junio C HamanoNov 19, 2025
  11. 07/13 builtin/index-pack: fix deferred fsck outside reposPatrick Steinhardt, Nov 19, 2025
  12. Junio C HamanoNov 19, 2025
  13. Patrick SteinhardtNov 21, 2025
  14. 08/13 t/helper: stop setting up `the_repository` repeatedlyPatrick Steinhardt, Nov 19, 2025
  15. 09/13 http-push: stop setting up `the_repository` for each referencePatrick Steinhardt, Nov 19, 2025
  16. 10/13 odb: handle initialization of sources in `odb_new()`Patrick Steinhardt, Nov 19, 2025
  17. 11/13 chdir-notify: add function to unregister listenersPatrick Steinhardt, Nov 19, 2025
  18. 12/13 odb: handle changing a repository's commondirPatrick Steinhardt, Nov 19, 2025
  19. Junio C HamanoNov 20, 2025
  20. Patrick SteinhardtNov 21, 2025
  21. 13/13 odb: handle recreation of quarantine directoriesPatrick Steinhardt, Nov 19, 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.