]> git.ipfire.org Git - thirdparty/git.git/commitdiff
setup: detangle loading of loose object maps
authorPatrick Steinhardt <ps@pks.im>
Fri, 24 Jul 2026 03:48:41 +0000 (05:48 +0200)
committerJunio C Hamano <gitster@pobox.com>
Fri, 24 Jul 2026 17:21:44 +0000 (10:21 -0700)
When a repository is configured to use a compatibility hash function
then we load the loose object map when we initialize the repository.
This object map provides the mappings between the canonical object hash
and the compatibility object hash.

Loading the object map happens in `repo_set_compat_hash_algo()`, which
calls `repo_read_loose_object_map()` in case the compatibility object
hash is non-zero. This setup sequence has two major downsides:

  - We assume that the primary object database is the "files" object
    database so that we can extract its "loose" backend. This stops
    working with pluggable object databases.

  - We require the object database to already have been initialized when
    configuring the object database. This means that we must intermix
    configuration of the repository and initialization of its
    sub-structures in a weird way.

Refactor the logic so that we instead load the loose object map via the
"loose" backend, which fixes both of the above issues.

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

diff --git a/loose.c b/loose.c
index 9dad75373b80806e2c534fdcda4a2ac99f8a6c0b..a3b2dcedc23607ebe5ca17bf843477a77e53bdc9 100644 (file)
--- a/loose.c
+++ b/loose.c
@@ -61,7 +61,7 @@ static int insert_loose_map(struct odb_source_loose *loose,
        return inserted;
 }
 
-static int load_one_loose_object_map(struct odb_source_loose *loose)
+int loose_object_map_load(struct odb_source_loose *loose)
 {
        struct repository *repo = loose->base.odb->repo;
        struct strbuf buf = STRBUF_INIT;
@@ -69,6 +69,9 @@ static int load_one_loose_object_map(struct odb_source_loose *loose)
        FILE *fp;
        int ret = -1;
 
+       if (!should_use_loose_object_map(repo))
+               return 0;
+
        if (!loose->map)
                loose_object_map_init(&loose->map);
        if (!loose->cache) {
@@ -112,14 +115,10 @@ int repo_read_loose_object_map(struct repository *repo)
 {
        struct odb_source *source;
 
-       if (!should_use_loose_object_map(repo))
-               return 0;
-
        odb_prepare_alternates(repo->objects);
-
        for (source = repo->objects->sources; source; source = source->next) {
                struct odb_source_files *files = odb_source_files_downcast(source);
-               if (load_one_loose_object_map(files->loose) < 0)
+               if (loose_object_map_load(files->loose) < 0)
                        return -1;
        }
 
diff --git a/loose.h b/loose.h
index 6c9b3f4571602f1a5798bb38ab9dc728d1a630de..ed663ac550fbb7f2a392139976862e90e49f67e2 100644 (file)
--- a/loose.h
+++ b/loose.h
@@ -13,6 +13,7 @@ struct loose_object_map {
 
 void loose_object_map_init(struct loose_object_map **map);
 void loose_object_map_clear(struct loose_object_map **map);
+int loose_object_map_load(struct odb_source_loose *loose);
 int repo_loose_object_map_oid(struct repository *repo,
                              const struct object_id *src,
                              const struct git_hash_algo *dest_algo,
index 3f7d04a56e36ce520e102fe686e1742b212288bd..812ca1c1381bab11718eb3bd4fc1ea79c1c7efdc 100644 (file)
@@ -727,5 +727,7 @@ struct odb_source_loose *odb_source_loose_new(struct object_database *odb,
        if (!is_absolute_path(loose->base.path))
                chdir_notify_register(NULL, odb_source_loose_reparent, loose);
 
+       loose_object_map_load(loose);
+
        return loose;
 }
index 2ef0778846bcf193abc5b4deaaa31ca5cebc9ef3..6d633002b4e3c4b4231b5833e548afdf392b4ac4 100644 (file)
@@ -201,8 +201,6 @@ void repo_set_compat_hash_algo(struct repository *repo MAYBE_UNUSED, uint32_t al
        if (hash_algo_by_ptr(repo->hash_algo) == algo)
                BUG("hash_algo and compat_hash_algo match");
        repo->compat_hash_algo = algo ? &hash_algos[algo] : NULL;
-       if (repo->compat_hash_algo)
-               repo_read_loose_object_map(repo);
 #else
        if (algo)
                die(_("compatibility hash algorithm support requires Rust"));
diff --git a/setup.c b/setup.c
index d31808130b47fcb610a6f1c90cff58c9ccfc492b..825572f5f1ad067d6fde1e6547e04062d516468b 100644 (file)
--- a/setup.c
+++ b/setup.c
@@ -1788,8 +1788,6 @@ int apply_repository_format(struct repository *repo,
 
        repo->bare_cfg = format->is_bare;
        repo_set_hash_algo(repo, format->hash_algo);
-       repo->objects = odb_new(repo, object_directory,
-                               alternate_object_directories);
        repo_set_compat_hash_algo(repo, format->compat_hash_algo);
        repo_set_ref_storage_format(repo,
                                    format->ref_storage_format,
@@ -1805,6 +1803,9 @@ 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);
+
        free(alternate_object_directories);
        free(object_directory);
        return 0;