]> git.ipfire.org Git - thirdparty/git.git/commitdiff
refs: pass repo when retrieving submodule ref store
authorPatrick Steinhardt <ps@pks.im>
Fri, 17 May 2024 08:18:34 +0000 (10:18 +0200)
committerJunio C Hamano <gitster@pobox.com>
Fri, 17 May 2024 17:33:37 +0000 (10:33 -0700)
Looking up submodule ref stores has two deficiencies:

  - The initialized subrepo will be attributed to `the_repository`.

  - The submodule ref store will be tracked in a global map.

This makes it impossible to have submodule ref stores for a repository
other than `the_repository`.

Modify the function to accept the parent repository as parameter and
move the global map into `struct repository`. Like this it becomes
possible to look up submodule ref stores for arbitrary repositories.

Note that this also adds a new reference to `the_repository` in
`resolve_gitlink_ref()`, which is part of the refs interfaces. This will
get adjusted in the next patch.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
builtin/submodule--helper.c
refs.c
refs.h
refs/refs-internal.h
repository.c
repository.h
submodule.c
t/helper/test-ref-store.c

index e604cb5ddb578b4dde4df6c564a0a17d7aa248cc..5076a3350001a7025a6698acf8ba5347a7d204d5 100644 (file)
@@ -679,7 +679,8 @@ static void status_submodule(const char *path, const struct object_id *ce_oid,
                             displaypath);
        } else if (!(flags & OPT_CACHED)) {
                struct object_id oid;
-               struct ref_store *refs = get_submodule_ref_store(path);
+               struct ref_store *refs = repo_get_submodule_ref_store(the_repository,
+                                                                     path);
 
                if (!refs) {
                        print_status(flags, '-', path, ce_oid, displaypath);
@@ -903,7 +904,8 @@ static void generate_submodule_summary(struct summary_cb *info,
 
        if (!info->cached && oideq(&p->oid_dst, null_oid())) {
                if (S_ISGITLINK(p->mod_dst)) {
-                       struct ref_store *refs = get_submodule_ref_store(p->sm_path);
+                       struct ref_store *refs = repo_get_submodule_ref_store(the_repository,
+                                                                             p->sm_path);
 
                        if (refs)
                                refs_head_ref(refs, handle_submodule_head_ref, &p->oid_dst);
diff --git a/refs.c b/refs.c
index 01e8453930c643c1119c9305e06fd24076bb7876..1d660d5ace480cee9dddc0d0751e10aafe4fa8fe 100644 (file)
--- a/refs.c
+++ b/refs.c
@@ -1949,8 +1949,7 @@ int resolve_gitlink_ref(const char *submodule, const char *refname,
        struct ref_store *refs;
        int flags;
 
-       refs = get_submodule_ref_store(submodule);
-
+       refs = repo_get_submodule_ref_store(the_repository, submodule);
        if (!refs)
                return -1;
 
@@ -1960,9 +1959,6 @@ int resolve_gitlink_ref(const char *submodule, const char *refname,
        return 0;
 }
 
-/* A strmap of ref_stores, stored by submodule name: */
-static struct strmap submodule_ref_stores;
-
 /* A strmap of ref_stores, stored by worktree id: */
 static struct strmap worktree_ref_stores;
 
@@ -2036,7 +2032,8 @@ static void register_ref_store_map(struct strmap *map,
                BUG("%s ref_store '%s' initialized twice", type, name);
 }
 
-struct ref_store *get_submodule_ref_store(const char *submodule)
+struct ref_store *repo_get_submodule_ref_store(struct repository *repo,
+                                              const char *submodule)
 {
        struct strbuf submodule_sb = STRBUF_INIT;
        struct ref_store *refs;
@@ -2057,7 +2054,7 @@ struct ref_store *get_submodule_ref_store(const char *submodule)
                /* We need to strip off one or more trailing slashes */
                submodule = to_free = xmemdupz(submodule, len);
 
-       refs = lookup_ref_store_map(&submodule_ref_stores, submodule);
+       refs = lookup_ref_store_map(&repo->submodule_ref_stores, submodule);
        if (refs)
                goto done;
 
@@ -2069,20 +2066,15 @@ struct ref_store *get_submodule_ref_store(const char *submodule)
                goto done;
 
        subrepo = xmalloc(sizeof(*subrepo));
-       /*
-        * NEEDSWORK: Make get_submodule_ref_store() work with arbitrary
-        * superprojects other than the_repository. This probably should be
-        * done by making it take a struct repository * parameter instead of a
-        * submodule path.
-        */
-       if (repo_submodule_init(subrepo, the_repository, submodule,
+
+       if (repo_submodule_init(subrepo, repo, submodule,
                                null_oid())) {
                free(subrepo);
                goto done;
        }
        refs = ref_store_init(subrepo, submodule_sb.buf,
                              REF_STORE_READ | REF_STORE_ODB);
-       register_ref_store_map(&submodule_ref_stores, "submodule",
+       register_ref_store_map(&repo->submodule_ref_stores, "submodule",
                               refs, submodule);
 
 done:
diff --git a/refs.h b/refs.h
index b11c250e8a45c239237395d9f7d0cd19a5774fc2..346a81e9e3b41f3143a8f126f93befccab97666b 100644 (file)
--- a/refs.h
+++ b/refs.h
@@ -954,7 +954,8 @@ struct ref_store *get_main_ref_store(struct repository *r);
  * For backwards compatibility, submodule=="" is treated the same as
  * submodule==NULL.
  */
-struct ref_store *get_submodule_ref_store(const char *submodule);
+struct ref_store *repo_get_submodule_ref_store(struct repository *repo,
+                                              const char *submodule);
 struct ref_store *get_worktree_ref_store(const struct worktree *wt);
 
 /*
index 8624477e19cfb981128b60b400b232f6fd31ee8f..178a355eb0a9e6bd6a75087cd2f992245cabf937 100644 (file)
@@ -705,7 +705,7 @@ extern struct ref_storage_be refs_be_packed;
 /*
  * A representation of the reference store for the main repository or
  * a submodule. The ref_store instances for submodules are kept in a
- * hash map; see get_submodule_ref_store() for more info.
+ * hash map; see repo_get_submodule_ref_store() for more info.
  */
 struct ref_store {
        /* The backend describing this ref_store's storage scheme: */
index c50849fd8333900432d0bb6449a6410ea5915bb9..bb9b9e2b528d59654e497dbdc9608cf2fb1d3128 100644 (file)
@@ -14,6 +14,7 @@
 #include "sparse-index.h"
 #include "trace2.h"
 #include "promisor-remote.h"
+#include "refs.h"
 
 /* The main repository */
 static struct repository the_repo;
@@ -289,6 +290,9 @@ static void repo_clear_path_cache(struct repo_path_cache *cache)
 
 void repo_clear(struct repository *repo)
 {
+       struct hashmap_iter iter;
+       struct strmap_entry *e;
+
        FREE_AND_NULL(repo->gitdir);
        FREE_AND_NULL(repo->commondir);
        FREE_AND_NULL(repo->graft_file);
@@ -329,6 +333,10 @@ void repo_clear(struct repository *repo)
                FREE_AND_NULL(repo->remote_state);
        }
 
+       strmap_for_each_entry(&repo->submodule_ref_stores, &iter, e)
+               ref_store_release(e->value);
+       strmap_clear(&repo->submodule_ref_stores, 1);
+
        repo_clear_path_cache(&repo->cached_paths);
 }
 
index 41ed22543a815feb80d31e45e0a1295d6dc8d981..0389df0461d3a363fc106f7beb4dc0295bd12574 100644 (file)
@@ -1,6 +1,8 @@
 #ifndef REPOSITORY_H
 #define REPOSITORY_H
 
+#include "strmap.h"
+
 struct config_set;
 struct fsmonitor_settings;
 struct git_hash_algo;
@@ -108,6 +110,12 @@ struct repository {
         */
        struct ref_store *refs_private;
 
+       /*
+        * A strmap of ref_stores, stored by submodule name, accessible via
+        * `repo_get_submodule_ref_store()`.
+        */
+       struct strmap submodule_ref_stores;
+
        /*
         * Contains path to often used file names.
         */
index f6313cd99fbc4dc8a559c2aeeb0e5da8e3d7fec0..759cf1e1cda9b0ad10a756523b7d5896bfb3a853 100644 (file)
@@ -99,7 +99,8 @@ int is_staging_gitmodules_ok(struct index_state *istate)
 static int for_each_remote_ref_submodule(const char *submodule,
                                         each_ref_fn fn, void *cb_data)
 {
-       return refs_for_each_remote_ref(get_submodule_ref_store(submodule),
+       return refs_for_each_remote_ref(repo_get_submodule_ref_store(the_repository,
+                                                                    submodule),
                                        fn, cb_data);
 }
 
index 82bbf6e2e68b9b57b8c2d159439631aa36a16d20..a5a760981112238f878f66125eaf9f06679dacd3 100644 (file)
@@ -82,7 +82,7 @@ static const char **get_store(const char **argv, struct ref_store **refs)
                add_to_alternates_memory(sb.buf);
                strbuf_release(&sb);
 
-               *refs = get_submodule_ref_store(gitdir);
+               *refs = repo_get_submodule_ref_store(the_repository, gitdir);
        } else if (skip_prefix(argv[0], "worktree:", &gitdir)) {
                struct worktree **p, **worktrees = get_worktrees();