]> git.ipfire.org Git - thirdparty/git.git/commitdiff
refs: retrieve worktree ref stores via associated repository
authorPatrick Steinhardt <ps@pks.im>
Fri, 17 May 2024 08:18:44 +0000 (10:18 +0200)
committerJunio C Hamano <gitster@pobox.com>
Fri, 17 May 2024 17:33:38 +0000 (10:33 -0700)
Similar as with the preceding commit, the worktree ref stores are always
looked up via `the_repository`. Also, again, those ref stores are stored
in a global map.

Refactor the code so that worktrees have a pointer to their repository.
Like this, we can move the global map into `struct repository` and stop
using `the_repository`. With this change, we can now in theory look up
worktree ref stores for repositories other than `the_repository`. In
practice, the worktree code will need further changes to look up
arbitrary worktrees.

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

diff --git a/refs.c b/refs.c
index 7703b7781c553894d2e196f352798b9d934100e5..70e712fcef7ea57a498bbea4add5b1944f14b439 100644 (file)
--- a/refs.c
+++ b/refs.c
@@ -1960,9 +1960,6 @@ int repo_resolve_gitlink_ref(struct repository *r,
        return 0;
 }
 
-/* A strmap of ref_stores, stored by worktree id: */
-static struct strmap worktree_ref_stores;
-
 /*
  * Look up a ref store by name. If that ref_store hasn't been
  * registered yet, return NULL.
@@ -2091,25 +2088,29 @@ struct ref_store *get_worktree_ref_store(const struct worktree *wt)
        const char *id;
 
        if (wt->is_current)
-               return get_main_ref_store(the_repository);
+               return get_main_ref_store(wt->repo);
 
        id = wt->id ? wt->id : "/";
-       refs = lookup_ref_store_map(&worktree_ref_stores, id);
+       refs = lookup_ref_store_map(&wt->repo->worktree_ref_stores, id);
        if (refs)
                return refs;
 
-       if (wt->id)
-               refs = ref_store_init(the_repository,
-                                     git_common_path("worktrees/%s", wt->id),
+       if (wt->id) {
+               struct strbuf common_path = STRBUF_INIT;
+               strbuf_git_common_path(&common_path, wt->repo,
+                                     "worktrees/%s", wt->id);
+               refs = ref_store_init(wt->repo, common_path.buf,
                                      REF_STORE_ALL_CAPS);
-       else
-               refs = ref_store_init(the_repository,
-                                     get_git_common_dir(),
+               strbuf_release(&common_path);
+       } else {
+               refs = ref_store_init(wt->repo, wt->repo->commondir,
                                      REF_STORE_ALL_CAPS);
+       }
 
        if (refs)
-               register_ref_store_map(&worktree_ref_stores, "worktree",
-                                      refs, id);
+               register_ref_store_map(&wt->repo->worktree_ref_stores,
+                                      "worktree", refs, id);
+
        return refs;
 }
 
index bb9b9e2b528d59654e497dbdc9608cf2fb1d3128..d29b0304fbd32ecfb6d8f63060cc5e1577f3db0d 100644 (file)
@@ -337,6 +337,10 @@ void repo_clear(struct repository *repo)
                ref_store_release(e->value);
        strmap_clear(&repo->submodule_ref_stores, 1);
 
+       strmap_for_each_entry(&repo->worktree_ref_stores, &iter, e)
+               ref_store_release(e->value);
+       strmap_clear(&repo->worktree_ref_stores, 1);
+
        repo_clear_path_cache(&repo->cached_paths);
 }
 
index 0389df0461d3a363fc106f7beb4dc0295bd12574..4bd896900554bb589c6ebf08534653ca18894329 100644 (file)
@@ -116,6 +116,12 @@ struct repository {
         */
        struct strmap submodule_ref_stores;
 
+       /*
+        * A strmap of ref_stores, stored by worktree id, accessible via
+        * `get_worktree_ref_store()`.
+        */
+       struct strmap worktree_ref_stores;
+
        /*
         * Contains path to often used file names.
         */
index cf5eea8c931a0cea85499aab6d24e5cbd392d839..12eadacc618a1db5e734bea16a5fb7ae15085131 100644 (file)
@@ -65,6 +65,7 @@ static struct worktree *get_main_worktree(int skip_reading_head)
        strbuf_strip_suffix(&worktree_path, "/.git");
 
        CALLOC_ARRAY(worktree, 1);
+       worktree->repo = the_repository;
        worktree->path = strbuf_detach(&worktree_path, NULL);
        /*
         * NEEDSWORK: If this function is called from a secondary worktree and
@@ -98,6 +99,7 @@ struct worktree *get_linked_worktree(const char *id,
        strbuf_strip_suffix(&worktree_path, "/.git");
 
        CALLOC_ARRAY(worktree, 1);
+       worktree->repo = the_repository;
        worktree->path = strbuf_detach(&worktree_path, NULL);
        worktree->id = xstrdup(id);
        if (!skip_reading_head)
index f14784a2ff871c69e5b5e28466439201721407b2..7cc6d90e66047115a725fa35e2b1a75b058eda15 100644 (file)
@@ -6,6 +6,8 @@
 struct strbuf;
 
 struct worktree {
+       /* The repository this worktree belongs to. */
+       struct repository *repo;
        char *path;
        char *id;
        char *head_ref;         /* NULL if HEAD is broken or detached */