]> git.ipfire.org Git - thirdparty/git.git/commitdiff
odb: handle initialization of sources in `odb_new()`
authorPatrick Steinhardt <ps@pks.im>
Wed, 19 Nov 2025 07:50:58 +0000 (08:50 +0100)
committerJunio C Hamano <gitster@pobox.com>
Tue, 25 Nov 2025 20:16:00 +0000 (12:16 -0800)
The logic to set up a new object database is currently distributed
across two functions in "repository.c":

  - In `initialize_repository()` we initialize an empty object database.
    This object database is not fully initialized and doesn't have any
    sources attached to it.

  - The primary object database source is then created in
    `repo_set_gitdir()`.

Ideally though, the logic should be entirely self-contained so that we
can iterate more readily on how exactly the sources themselves get set
up.

Refactor `odb_new()` to handle both allocation and setup of the object
database. This ensures that the object database is always initialized
and ready for use, and it allows us to change how the sources get set up
eventually.

Note that `repo_set_gitdir()` still reaches into the sources when the
function gets called with an already-initialized object database. This
will be fixed in the next commit.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
odb.c
odb.h
repository.c

diff --git a/odb.c b/odb.c
index ccc6e999e7ae25d3d0d36379b94115cfdc731053..88b40c81c0060c022c30ce1c19672dfa5779a0f2 100644 (file)
--- a/odb.c
+++ b/odb.c
@@ -1034,15 +1034,27 @@ int odb_write_object_stream(struct object_database *odb,
        return odb_source_loose_write_stream(odb->sources, stream, len, oid);
 }
 
-struct object_database *odb_new(struct repository *repo)
+struct object_database *odb_new(struct repository *repo,
+                               const char *primary_source,
+                               const char *secondary_sources)
 {
        struct object_database *o = xmalloc(sizeof(*o));
+       char *to_free = NULL;
 
        memset(o, 0, sizeof(*o));
        o->repo = repo;
        o->packfiles = packfile_store_new(o);
        pthread_mutex_init(&o->replace_mutex, NULL);
        string_list_init_dup(&o->submodule_source_paths);
+
+       if (!primary_source)
+               primary_source = to_free = 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);
+
+       free(to_free);
+
        return o;
 }
 
diff --git a/odb.h b/odb.h
index 99c4d4897294597873461bbfd20bf9fcbb24dfa8..41b3c03027f4d833278592e1b34040f59d055971 100644 (file)
--- a/odb.h
+++ b/odb.h
@@ -159,7 +159,20 @@ struct object_database {
        struct string_list submodule_source_paths;
 };
 
-struct object_database *odb_new(struct repository *repo);
+/*
+ * Create a new object database for the given repository.
+ *
+ * If the primary source parameter is set it will override the usual primary
+ * object directory derived from the repository's common directory. The
+ * alternate sources are expected to be a PATH_SEP-separated list of secondary
+ * sources. Note that these alternate sources will be added in addition to, not
+ * instead of, the alternates identified by the primary source.
+ *
+ * Returns the newly created object database.
+ */
+struct object_database *odb_new(struct repository *repo,
+                               const char *primary_source,
+                               const char *alternate_sources);
 
 /* Free the object database and release all resources. */
 void odb_free(struct object_database *o);
index 455c2d279fb8ab7cf0edb498f65576be4f95a4e0..5975c8f341c8cb86fecf4533122f987b10ab5d5f 100644 (file)
@@ -52,7 +52,6 @@ static void set_default_hash_algo(struct repository *repo)
 
 void initialize_repository(struct repository *repo)
 {
-       repo->objects = odb_new(repo);
        repo->remote_state = remote_state_new();
        repo->parsed_objects = parsed_object_pool_new(repo);
        ALLOC_ARRAY(repo->index, 1);
@@ -160,29 +159,26 @@ void repo_set_gitdir(struct repository *repo,
         * until after xstrdup(root). Then we can free it.
         */
        char *old_gitdir = repo->gitdir;
-       char *objects_path = NULL;
 
        repo->gitdir = xstrdup(gitfile ? gitfile : root);
        free(old_gitdir);
 
        repo_set_commondir(repo, o->commondir);
-       expand_base_dir(&objects_path, o->object_dir,
-                       repo->commondir, "objects");
-
-       if (!repo->objects->sources) {
-               repo->objects->sources = odb_source_new(repo->objects,
-                                                       objects_path, true);
-               repo->objects->sources_tail = &repo->objects->sources->next;
-               free(objects_path);
+
+       if (!repo->objects) {
+               repo->objects = odb_new(repo, o->object_dir, o->alternate_db);
        } else {
+               char *objects_path = NULL;
+               expand_base_dir(&objects_path, o->object_dir,
+                               repo->commondir, "objects");
                free(repo->objects->sources->path);
                repo->objects->sources->path = objects_path;
+               free(repo->objects->alternate_db);
+               repo->objects->alternate_db = xstrdup_or_null(o->alternate_db);
        }
 
        repo->disable_ref_updates = o->disable_ref_updates;
 
-       free(repo->objects->alternate_db);
-       repo->objects->alternate_db = xstrdup_or_null(o->alternate_db);
        expand_base_dir(&repo->graft_file, o->graft_file,
                        repo->commondir, "info/grafts");
        expand_base_dir(&repo->index_file, o->index_file,