From 30bc6f0e8c2aef5f9280468fa2ca7c170209603f Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Fri, 7 Aug 2026 05:34:27 +0200 Subject: [PATCH] setup: handle ODB-related environment variables in `odb_new()` When initializing a repository's object database we have to respect the GIT_OBJECT_DIRECTORY and GIT_ALTERNATE_OBJECT_DIRECTORIES environment variables, which can be set by the user to override the default location of where we write objects to and read objects from. This is handled in `apply_repository_format()`, which is fine. But in a subsequent commit we'll have to defer constructing the object database to a later point in some cases, and that will require a second site where we call `odb_new()`. And of course, that second site would have to handle those environment variables, as well. It would be somewhat awkward to duplicate the logic though. But there's a better alternative: instead of handling this logic in "setup.c", we can easily handle environment variables in `odb_new()` itself. This ensures that object database creation is neatly self-contained, and we don't have to duplicate any of the logic. Another benefit is that in a future patch series we plan to move handling of alternates into the backends themselves [1], and that will require us to also handle those environment variables in the "files" backend itself. So moving the logic into the ODB level already gets us one step closer to that goal. Refactor the logic accordingly. [1]: https://lore.kernel.org/git/amLgMqkqxR8mKIbT@pks.im/ Signed-off-by: Patrick Steinhardt Signed-off-by: Junio C Hamano --- odb.c | 21 ++++++++++++--------- odb.h | 17 +++++++++++++++-- setup.c | 11 ++++------- t/unit-tests/u-odb-inmemory.c | 2 +- 4 files changed, 32 insertions(+), 19 deletions(-) diff --git a/odb.c b/odb.c index cf6e7938c0..ed1d63f4bd 100644 --- a/odb.c +++ b/odb.c @@ -1004,26 +1004,29 @@ int odb_write_object_stream(struct object_database *odb, } struct object_database *odb_new(struct repository *repo, - const char *primary_source, - const char *secondary_sources) + enum odb_new_flags flags) { - struct object_database *o = xmalloc(sizeof(*o)); - char *to_free = NULL; + char *primary_source = NULL, *secondary_sources = NULL; + struct object_database *o; - memset(o, 0, sizeof(*o)); + CALLOC_ARRAY(o, 1); o->repo = repo; pthread_mutex_init(&o->replace_mutex, NULL); string_list_init_dup(&o->submodule_source_paths); + if (flags & ODB_NEW_HONOR_ENV) { + primary_source = xstrdup_or_null(getenv(DB_ENVIRONMENT)); + secondary_sources = xstrdup_or_null(getenv(ALTERNATE_DB_ENVIRONMENT)); + } if (!primary_source) - primary_source = to_free = xstrfmt("%s/objects", repo->commondir); + primary_source = xstrfmt("%s/objects", repo->commondir); + o->sources = odb_source_new(o, primary_source, true); o->sources_tail = &o->sources->next; - o->alternate_db = xstrdup_or_null(secondary_sources); + o->alternate_db = secondary_sources; o->inmemory_objects = &odb_source_inmemory_new(o)->base; - free(to_free); - + free(primary_source); return o; } diff --git a/odb.h b/odb.h index 7995bed97b..8ec335c7f7 100644 --- a/odb.h +++ b/odb.h @@ -100,6 +100,20 @@ struct object_database { struct string_list submodule_source_paths; }; +enum odb_new_flags { + /* + * Honor environment variables when constructing the object database + * sources. This makes us respect the following environment variables: + * + * - GIT_OBJECT_DIRECTORY to override the primary object directory. + * + * - GIT_ALTERNATE_OBJECT_DIRECTORIES to override alternates. + * + * Environment variables may be backend-specific. + */ + ODB_NEW_HONOR_ENV = (1 << 0), +}; + /* * Create a new object database for the given repository. * @@ -112,8 +126,7 @@ struct object_database { * Returns the newly created object database. */ struct object_database *odb_new(struct repository *repo, - const char *primary_source, - const char *alternate_sources); + enum odb_new_flags flags); /* Free the object database and release all resources. */ void odb_free(struct object_database *o); diff --git a/setup.c b/setup.c index 825572f5f1..5dfab3e79e 100644 --- a/setup.c +++ b/setup.c @@ -1765,7 +1765,7 @@ int apply_repository_format(struct repository *repo, enum apply_repository_format_flags flags, struct strbuf *err) { - char *object_directory = NULL, *alternate_object_directories = NULL; + enum odb_new_flags odb_new_flags = 0; if (verify_repository_format(format, err) < 0) return -1; @@ -1779,8 +1779,6 @@ int apply_repository_format(struct repository *repo, if (flags & APPLY_REPOSITORY_FORMAT_HONOR_ENV) { const char *shallow_file; - object_directory = xstrdup_or_null(getenv(DB_ENVIRONMENT)); - alternate_object_directories = xstrdup_or_null(getenv(ALTERNATE_DB_ENVIRONMENT)); shallow_file = getenv(GIT_SHALLOW_FILE_ENVIRONMENT); if (shallow_file) set_alternate_shallow_file(repo, shallow_file); @@ -1803,11 +1801,10 @@ int apply_repository_format(struct repository *repo, repo->repository_format_precious_objects = format->precious_objects; - repo->objects = odb_new(repo, object_directory, - alternate_object_directories); + if (flags & APPLY_REPOSITORY_FORMAT_HONOR_ENV) + odb_new_flags |= ODB_NEW_HONOR_ENV; + repo->objects = odb_new(repo, odb_new_flags); - free(alternate_object_directories); - free(object_directory); return 0; } diff --git a/t/unit-tests/u-odb-inmemory.c b/t/unit-tests/u-odb-inmemory.c index 6844bfc37c..db323e10fd 100644 --- a/t/unit-tests/u-odb-inmemory.c +++ b/t/unit-tests/u-odb-inmemory.c @@ -38,7 +38,7 @@ static void cl_assert_object_info(struct odb_source_inmemory *source, void test_odb_inmemory__initialize(void) { - odb = odb_new(&repo, "", ""); + odb = odb_new(&repo, 0); } void test_odb_inmemory__cleanup(void)