promisor-remote: support per-repository config

Instead of using global variables to store promisor remote information,
store this config in struct repository instead, and add
repository-agnostic non-static functions corresponding to the existing
non-static functions that only work on the_repository.

The actual lazy-fetching of missing objects currently does not work on
repositories other than the_repository, and will still not work after
this commit, so add a BUG message explaining this. A subsequent commit
will remove this limitation.

Signed-off-by: Jonathan Tan <jonathantanmy@google.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Reviewed-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Jonathan Tan
2021-06-17 10:13:23 -07:00
committed by Junio C Hamano
parent ebaf3bcf1a
commit ef7dc2e9cc
4 changed files with 82 additions and 46 deletions

View File

@ -5,6 +5,11 @@
#include "transport.h" #include "transport.h"
#include "strvec.h" #include "strvec.h"
struct promisor_remote_config {
struct promisor_remote *promisors;
struct promisor_remote **promisors_tail;
};
static int fetch_objects(const char *remote_name, static int fetch_objects(const char *remote_name,
const struct object_id *oids, const struct object_id *oids,
int oid_nr) int oid_nr)
@ -35,10 +40,8 @@ static int fetch_objects(const char *remote_name,
return finish_command(&child) ? -1 : 0; return finish_command(&child) ? -1 : 0;
} }
static struct promisor_remote *promisors; static struct promisor_remote *promisor_remote_new(struct promisor_remote_config *config,
static struct promisor_remote **promisors_tail = &promisors; const char *remote_name)
static struct promisor_remote *promisor_remote_new(const char *remote_name)
{ {
struct promisor_remote *r; struct promisor_remote *r;
@ -50,18 +53,19 @@ static struct promisor_remote *promisor_remote_new(const char *remote_name)
FLEX_ALLOC_STR(r, name, remote_name); FLEX_ALLOC_STR(r, name, remote_name);
*promisors_tail = r; *config->promisors_tail = r;
promisors_tail = &r->next; config->promisors_tail = &r->next;
return r; return r;
} }
static struct promisor_remote *promisor_remote_lookup(const char *remote_name, static struct promisor_remote *promisor_remote_lookup(struct promisor_remote_config *config,
const char *remote_name,
struct promisor_remote **previous) struct promisor_remote **previous)
{ {
struct promisor_remote *r, *p; struct promisor_remote *r, *p;
for (p = NULL, r = promisors; r; p = r, r = r->next) for (p = NULL, r = config->promisors; r; p = r, r = r->next)
if (!strcmp(r->name, remote_name)) { if (!strcmp(r->name, remote_name)) {
if (previous) if (previous)
*previous = p; *previous = p;
@ -71,7 +75,8 @@ static struct promisor_remote *promisor_remote_lookup(const char *remote_name,
return NULL; return NULL;
} }
static void promisor_remote_move_to_tail(struct promisor_remote *r, static void promisor_remote_move_to_tail(struct promisor_remote_config *config,
struct promisor_remote *r,
struct promisor_remote *previous) struct promisor_remote *previous)
{ {
if (r->next == NULL) if (r->next == NULL)
@ -80,14 +85,15 @@ static void promisor_remote_move_to_tail(struct promisor_remote *r,
if (previous) if (previous)
previous->next = r->next; previous->next = r->next;
else else
promisors = r->next ? r->next : r; config->promisors = r->next ? r->next : r;
r->next = NULL; r->next = NULL;
*promisors_tail = r; *config->promisors_tail = r;
promisors_tail = &r->next; config->promisors_tail = &r->next;
} }
static int promisor_remote_config(const char *var, const char *value, void *data) static int promisor_remote_config(const char *var, const char *value, void *data)
{ {
struct promisor_remote_config *config = data;
const char *name; const char *name;
size_t namelen; size_t namelen;
const char *subkey; const char *subkey;
@ -103,8 +109,8 @@ static int promisor_remote_config(const char *var, const char *value, void *data
remote_name = xmemdupz(name, namelen); remote_name = xmemdupz(name, namelen);
if (!promisor_remote_lookup(remote_name, NULL)) if (!promisor_remote_lookup(config, remote_name, NULL))
promisor_remote_new(remote_name); promisor_remote_new(config, remote_name);
free(remote_name); free(remote_name);
return 0; return 0;
@ -113,9 +119,9 @@ static int promisor_remote_config(const char *var, const char *value, void *data
struct promisor_remote *r; struct promisor_remote *r;
char *remote_name = xmemdupz(name, namelen); char *remote_name = xmemdupz(name, namelen);
r = promisor_remote_lookup(remote_name, NULL); r = promisor_remote_lookup(config, remote_name, NULL);
if (!r) if (!r)
r = promisor_remote_new(remote_name); r = promisor_remote_new(config, remote_name);
free(remote_name); free(remote_name);
@ -128,59 +134,63 @@ static int promisor_remote_config(const char *var, const char *value, void *data
return 0; return 0;
} }
static int initialized; static void promisor_remote_init(struct repository *r)
static void promisor_remote_init(void)
{ {
if (initialized) struct promisor_remote_config *config;
if (r->promisor_remote_config)
return; return;
initialized = 1; config = r->promisor_remote_config =
xcalloc(sizeof(*r->promisor_remote_config), 1);
config->promisors_tail = &config->promisors;
git_config(promisor_remote_config, NULL); repo_config(r, promisor_remote_config, config);
if (the_repository->repository_format_partial_clone) { if (r->repository_format_partial_clone) {
struct promisor_remote *o, *previous; struct promisor_remote *o, *previous;
o = promisor_remote_lookup(the_repository->repository_format_partial_clone, o = promisor_remote_lookup(config,
r->repository_format_partial_clone,
&previous); &previous);
if (o) if (o)
promisor_remote_move_to_tail(o, previous); promisor_remote_move_to_tail(config, o, previous);
else else
promisor_remote_new(the_repository->repository_format_partial_clone); promisor_remote_new(config, r->repository_format_partial_clone);
} }
} }
static void promisor_remote_clear(void) void promisor_remote_clear(struct promisor_remote_config *config)
{ {
while (promisors) { while (config->promisors) {
struct promisor_remote *r = promisors; struct promisor_remote *r = config->promisors;
promisors = promisors->next; config->promisors = config->promisors->next;
free(r); free(r);
} }
promisors_tail = &promisors; config->promisors_tail = &config->promisors;
} }
void promisor_remote_reinit(void) void repo_promisor_remote_reinit(struct repository *r)
{ {
initialized = 0; promisor_remote_clear(r->promisor_remote_config);
promisor_remote_clear(); FREE_AND_NULL(r->promisor_remote_config);
promisor_remote_init(); promisor_remote_init(r);
} }
struct promisor_remote *promisor_remote_find(const char *remote_name) struct promisor_remote *repo_promisor_remote_find(struct repository *r,
const char *remote_name)
{ {
promisor_remote_init(); promisor_remote_init(r);
if (!remote_name) if (!remote_name)
return promisors; return r->promisor_remote_config->promisors;
return promisor_remote_lookup(remote_name, NULL); return promisor_remote_lookup(r->promisor_remote_config, remote_name, NULL);
} }
int has_promisor_remote(void) int repo_has_promisor_remote(struct repository *r)
{ {
return !!promisor_remote_find(NULL); return !!repo_promisor_remote_find(r, NULL);
} }
static int remove_fetched_oids(struct repository *repo, static int remove_fetched_oids(struct repository *repo,
@ -228,9 +238,11 @@ int promisor_remote_get_direct(struct repository *repo,
if (oid_nr == 0) if (oid_nr == 0)
return 0; return 0;
promisor_remote_init(); promisor_remote_init(repo);
for (r = promisors; r; r = r->next) { if (repo != the_repository)
BUG("only the_repository is supported for now");
for (r = repo->promisor_remote_config->promisors; r; r = r->next) {
if (fetch_objects(r->name, remaining_oids, remaining_nr) < 0) { if (fetch_objects(r->name, remaining_oids, remaining_nr) < 0) {
if (remaining_nr == 1) if (remaining_nr == 1)
continue; continue;

View File

@ -17,9 +17,25 @@ struct promisor_remote {
const char name[FLEX_ARRAY]; const char name[FLEX_ARRAY];
}; };
void promisor_remote_reinit(void); void repo_promisor_remote_reinit(struct repository *r);
struct promisor_remote *promisor_remote_find(const char *remote_name); static inline void promisor_remote_reinit(void)
int has_promisor_remote(void); {
repo_promisor_remote_reinit(the_repository);
}
void promisor_remote_clear(struct promisor_remote_config *config);
struct promisor_remote *repo_promisor_remote_find(struct repository *r, const char *remote_name);
static inline struct promisor_remote *promisor_remote_find(const char *remote_name)
{
return repo_promisor_remote_find(the_repository, remote_name);
}
int repo_has_promisor_remote(struct repository *r);
static inline int has_promisor_remote(void)
{
return repo_has_promisor_remote(the_repository);
}
/* /*
* Fetches all requested objects from all promisor remotes, trying them one at * Fetches all requested objects from all promisor remotes, trying them one at

View File

@ -11,6 +11,7 @@
#include "lockfile.h" #include "lockfile.h"
#include "submodule-config.h" #include "submodule-config.h"
#include "sparse-index.h" #include "sparse-index.h"
#include "promisor-remote.h"
/* The main repository */ /* The main repository */
static struct repository the_repo; static struct repository the_repo;
@ -262,6 +263,11 @@ void repo_clear(struct repository *repo)
if (repo->index != &the_index) if (repo->index != &the_index)
FREE_AND_NULL(repo->index); FREE_AND_NULL(repo->index);
} }
if (repo->promisor_remote_config) {
promisor_remote_clear(repo->promisor_remote_config);
FREE_AND_NULL(repo->promisor_remote_config);
}
} }
int repo_read_index(struct repository *repo) int repo_read_index(struct repository *repo)

View File

@ -10,6 +10,7 @@ struct lock_file;
struct pathspec; struct pathspec;
struct raw_object_store; struct raw_object_store;
struct submodule_cache; struct submodule_cache;
struct promisor_remote_config;
enum untracked_cache_setting { enum untracked_cache_setting {
UNTRACKED_CACHE_UNSET = -1, UNTRACKED_CACHE_UNSET = -1,
@ -141,6 +142,7 @@ struct repository {
/* Configurations related to promisor remotes. */ /* Configurations related to promisor remotes. */
char *repository_format_partial_clone; char *repository_format_partial_clone;
struct promisor_remote_config *promisor_remote_config;
/* Configurations */ /* Configurations */