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@xxxxxx> --- refs.c | 27 ++++++++++++++------------- repository.c | 4 ++++ repository.h | 6 ++++++ worktree.c | 2 ++ worktree.h | 2 ++ 5 files changed, 28 insertions(+), 13 deletions(-) diff --git a/refs.c b/refs.c index 7703b7781c..70e712fcef 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 */ -- 2.45.1.190.g19fe900cfc.dirty
Attachment:
signature.asc
Description: PGP signature