refs: create a base class "ref_store" for files_ref_store
We want ref_stores to be polymorphic, so invent a base class of which files_ref_store is a derived class. For now there is exactly one ref_store for the main repository and one for any submodules whose references have been accessed. Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
committed by
Junio C Hamano
parent
3dce444f17
commit
00eebe351c
93
refs.c
93
refs.c
@ -1151,8 +1151,12 @@ int head_ref(each_ref_fn fn, void *cb_data)
|
||||
static int do_for_each_ref(const char *submodule, const char *prefix,
|
||||
each_ref_fn fn, int trim, int flags, void *cb_data)
|
||||
{
|
||||
struct ref_store *refs = get_ref_store(submodule);
|
||||
struct ref_iterator *iter;
|
||||
|
||||
if (!refs)
|
||||
return 0;
|
||||
|
||||
iter = files_ref_iterator_begin(submodule, prefix, flags);
|
||||
iter = prefix_ref_iterator_begin(iter, prefix, trim);
|
||||
|
||||
@ -1284,3 +1288,92 @@ const char *resolve_ref_unsafe(const char *refname, int resolve_flags,
|
||||
errno = ELOOP;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* A pointer to the ref_store for the main repository: */
|
||||
static struct ref_store *main_ref_store;
|
||||
|
||||
/* A linked list of ref_stores for submodules: */
|
||||
static struct ref_store *submodule_ref_stores;
|
||||
|
||||
void base_ref_store_init(struct ref_store *refs,
|
||||
const struct ref_storage_be *be,
|
||||
const char *submodule)
|
||||
{
|
||||
refs->be = be;
|
||||
if (!submodule) {
|
||||
if (main_ref_store)
|
||||
die("BUG: main_ref_store initialized twice");
|
||||
|
||||
refs->submodule = "";
|
||||
refs->next = NULL;
|
||||
main_ref_store = refs;
|
||||
} else {
|
||||
if (lookup_ref_store(submodule))
|
||||
die("BUG: ref_store for submodule '%s' initialized twice",
|
||||
submodule);
|
||||
|
||||
refs->submodule = xstrdup(submodule);
|
||||
refs->next = submodule_ref_stores;
|
||||
submodule_ref_stores = refs;
|
||||
}
|
||||
}
|
||||
|
||||
struct ref_store *ref_store_init(const char *submodule)
|
||||
{
|
||||
const char *be_name = "files";
|
||||
struct ref_storage_be *be = find_ref_storage_backend(be_name);
|
||||
|
||||
if (!be)
|
||||
die("BUG: reference backend %s is unknown", be_name);
|
||||
|
||||
if (!submodule || !*submodule)
|
||||
return be->init(NULL);
|
||||
else
|
||||
return be->init(submodule);
|
||||
}
|
||||
|
||||
struct ref_store *lookup_ref_store(const char *submodule)
|
||||
{
|
||||
struct ref_store *refs;
|
||||
|
||||
if (!submodule || !*submodule)
|
||||
return main_ref_store;
|
||||
|
||||
for (refs = submodule_ref_stores; refs; refs = refs->next) {
|
||||
if (!strcmp(submodule, refs->submodule))
|
||||
return refs;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct ref_store *get_ref_store(const char *submodule)
|
||||
{
|
||||
struct ref_store *refs;
|
||||
|
||||
if (!submodule || !*submodule) {
|
||||
refs = lookup_ref_store(NULL);
|
||||
|
||||
if (!refs)
|
||||
refs = ref_store_init(NULL);
|
||||
} else {
|
||||
refs = lookup_ref_store(submodule);
|
||||
|
||||
if (!refs) {
|
||||
struct strbuf submodule_sb = STRBUF_INIT;
|
||||
|
||||
strbuf_addstr(&submodule_sb, submodule);
|
||||
if (is_nonbare_repository_dir(&submodule_sb))
|
||||
refs = ref_store_init(submodule);
|
||||
strbuf_release(&submodule_sb);
|
||||
}
|
||||
}
|
||||
|
||||
return refs;
|
||||
}
|
||||
|
||||
void assert_main_repository(struct ref_store *refs, const char *caller)
|
||||
{
|
||||
if (*refs->submodule)
|
||||
die("BUG: %s called for a submodule", caller);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user