refs: retrieve worktree ref stores via associated repository
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>
Patrick Steinhardt committed
May 17, 2024 at 10:18 UTC
dc7fb4f72c2e39ffbb98aee55ad7ea4c3f8e12fc
5 files changed
+28
-13
refs.c
+14
-13
@@ -1960,9 +1960,6 @@ int repo_resolve_gitlink_ref(struct repository *r,
1960
return 0;
1961
}
1962
1963
-/* A strmap of ref_stores, stored by worktree id: */
1964
-static struct strmap worktree_ref_stores;
1965
-
1963
/*
1964
* Look up a ref store by name. If that ref_store hasn't been
1965
* registered yet, return NULL.
@@ -2091,25 +2088,29 @@ struct ref_store *get_worktree_ref_store(const struct worktree *wt)
2088
const char *id;
2089
2090
if (wt->is_current)
2094
- return get_main_ref_store(the_repository);
2091
+ return get_main_ref_store(wt->repo);
2092
2093
id = wt->id ? wt->id : "/";
2097
- refs = lookup_ref_store_map(&worktree_ref_stores, id);
2094
+ refs = lookup_ref_store_map(&wt->repo->worktree_ref_stores, id);
2095
if (refs)
2096
return refs;
2097
2101
- if (wt->id)
2102
- refs = ref_store_init(the_repository,
2103
- git_common_path("worktrees/%s", wt->id),
2098
+ if (wt->id) {
2099
+ struct strbuf common_path = STRBUF_INIT;
2100
+ strbuf_git_common_path(&common_path, wt->repo,
2101
+ "worktrees/%s", wt->id);
2102
+ refs = ref_store_init(wt->repo, common_path.buf,
2103
REF_STORE_ALL_CAPS);
2105
- else
2106
- refs = ref_store_init(the_repository,
2107
- get_git_common_dir(),
2104
+ strbuf_release(&common_path);
2105
+ } else {
2106
+ refs = ref_store_init(wt->repo, wt->repo->commondir,
2107
REF_STORE_ALL_CAPS);
2108
+ }
2109
2110
if (refs)
2111
- register_ref_store_map(&worktree_ref_stores, "worktree",
2112
- refs, id);
2111
+ register_ref_store_map(&wt->repo->worktree_ref_stores,
2112
+ "worktree", refs, id);
2113
+
2114
return refs;
2115
}
2116
repository.c
+4
@@ -337,6 +337,10 @@ void repo_clear(struct repository *repo)
337
ref_store_release(e->value);
338
strmap_clear(&repo->submodule_ref_stores, 1);
339
340
+ strmap_for_each_entry(&repo->worktree_ref_stores, &iter, e)
341
+ ref_store_release(e->value);
342
+ strmap_clear(&repo->worktree_ref_stores, 1);
343
+
344
repo_clear_path_cache(&repo->cached_paths);
345
}
346
repository.h
+6
@@ -116,6 +116,12 @@ struct repository {
116
*/
117
struct strmap submodule_ref_stores;
118
119
+ /*
120
+ * A strmap of ref_stores, stored by worktree id, accessible via
121
+ * `get_worktree_ref_store()`.
122
+ */
123
+ struct strmap worktree_ref_stores;
124
+
125
/*
126
* Contains path to often used file names.
127
*/
worktree.c
+2
@@ -65,6 +65,7 @@ static struct worktree *get_main_worktree(int skip_reading_head)
65
strbuf_strip_suffix(&worktree_path, "/.git");
66
67
CALLOC_ARRAY(worktree, 1);
68
+ worktree->repo = the_repository;
69
worktree->path = strbuf_detach(&worktree_path, NULL);
70
/*
71
* NEEDSWORK: If this function is called from a secondary worktree and
@@ -98,6 +99,7 @@ struct worktree *get_linked_worktree(const char *id,
99
strbuf_strip_suffix(&worktree_path, "/.git");
100
101
CALLOC_ARRAY(worktree, 1);
102
+ worktree->repo = the_repository;
103
worktree->path = strbuf_detach(&worktree_path, NULL);
104
worktree->id = xstrdup(id);
105
if (!skip_reading_head)
worktree.h
+2
@@ -6,6 +6,8 @@
6
struct strbuf;
7
8
struct worktree {
9
+ /* The repository this worktree belongs to. */
10
+ struct repository *repo;
11
char *path;
12
char *id;
13
char *head_ref; /* NULL if HEAD is broken or detached */