diff mbox series

[07/16] refs: retrieve worktree ref stores via associated repository

Message ID 4d55dbbceb2162aab1ee83f5efe752f6a721bc8f.1715836916.git.ps@pks.im (mailing list archive)
State Superseded
Headers show
Series refs: drop all references to `the_repository` | expand

Commit Message

Patrick Steinhardt May 16, 2024, 8:04 a.m. UTC
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>
---
 refs.c       | 27 ++++++++++++++-------------
 repository.c |  4 ++++
 repository.h |  6 ++++++
 worktree.c   |  2 ++
 worktree.h   |  2 ++
 5 files changed, 28 insertions(+), 13 deletions(-)
diff mbox series

Patch

diff --git a/refs.c b/refs.c
index 40e241216e..03bf5d0e69 100644
--- 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;
 }
 
diff --git a/repository.c b/repository.c
index bb9b9e2b52..d29b0304fb 100644
--- a/repository.c
+++ b/repository.c
@@ -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);
 }
 
diff --git a/repository.h b/repository.h
index 0389df0461..4bd8969005 100644
--- a/repository.h
+++ b/repository.h
@@ -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.
 	 */
diff --git a/worktree.c b/worktree.c
index cf5eea8c93..12eadacc61 100644
--- a/worktree.c
+++ b/worktree.c
@@ -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)
diff --git a/worktree.h b/worktree.h
index f14784a2ff..7cc6d90e66 100644
--- a/worktree.h
+++ b/worktree.h
@@ -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 */