refs: pass repo when retrieving submodule ref store

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>
This commit is contained in:
Patrick Steinhardt 2024-05-17 10:18:34 +02:00 committed by Junio C Hamano
parent f1782d185b
commit 965f8991e5
8 changed files with 33 additions and 21 deletions

View 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);

22
refs.c
View file

@ -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:

3
refs.h
View file

@ -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);
/*

View 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: */

View 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);
}

View 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.
*/

View 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);
}

View 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();