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:
parent
ebaf3bcf1a
commit
ef7dc2e9cc
@ -5,6 +5,11 @@
|
||||
#include "transport.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,
|
||||
const struct object_id *oids,
|
||||
int oid_nr)
|
||||
@ -35,10 +40,8 @@ static int fetch_objects(const char *remote_name,
|
||||
return finish_command(&child) ? -1 : 0;
|
||||
}
|
||||
|
||||
static struct promisor_remote *promisors;
|
||||
static struct promisor_remote **promisors_tail = &promisors;
|
||||
|
||||
static struct promisor_remote *promisor_remote_new(const char *remote_name)
|
||||
static struct promisor_remote *promisor_remote_new(struct promisor_remote_config *config,
|
||||
const char *remote_name)
|
||||
{
|
||||
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);
|
||||
|
||||
*promisors_tail = r;
|
||||
promisors_tail = &r->next;
|
||||
*config->promisors_tail = r;
|
||||
config->promisors_tail = &r->next;
|
||||
|
||||
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 *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 (previous)
|
||||
*previous = p;
|
||||
@ -71,7 +75,8 @@ static struct promisor_remote *promisor_remote_lookup(const char *remote_name,
|
||||
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)
|
||||
{
|
||||
if (r->next == NULL)
|
||||
@ -80,14 +85,15 @@ static void promisor_remote_move_to_tail(struct promisor_remote *r,
|
||||
if (previous)
|
||||
previous->next = r->next;
|
||||
else
|
||||
promisors = r->next ? r->next : r;
|
||||
config->promisors = r->next ? r->next : r;
|
||||
r->next = NULL;
|
||||
*promisors_tail = r;
|
||||
promisors_tail = &r->next;
|
||||
*config->promisors_tail = r;
|
||||
config->promisors_tail = &r->next;
|
||||
}
|
||||
|
||||
static int promisor_remote_config(const char *var, const char *value, void *data)
|
||||
{
|
||||
struct promisor_remote_config *config = data;
|
||||
const char *name;
|
||||
size_t namelen;
|
||||
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);
|
||||
|
||||
if (!promisor_remote_lookup(remote_name, NULL))
|
||||
promisor_remote_new(remote_name);
|
||||
if (!promisor_remote_lookup(config, remote_name, NULL))
|
||||
promisor_remote_new(config, remote_name);
|
||||
|
||||
free(remote_name);
|
||||
return 0;
|
||||
@ -113,9 +119,9 @@ static int promisor_remote_config(const char *var, const char *value, void *data
|
||||
struct promisor_remote *r;
|
||||
char *remote_name = xmemdupz(name, namelen);
|
||||
|
||||
r = promisor_remote_lookup(remote_name, NULL);
|
||||
r = promisor_remote_lookup(config, remote_name, NULL);
|
||||
if (!r)
|
||||
r = promisor_remote_new(remote_name);
|
||||
r = promisor_remote_new(config, remote_name);
|
||||
|
||||
free(remote_name);
|
||||
|
||||
@ -128,59 +134,63 @@ static int promisor_remote_config(const char *var, const char *value, void *data
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int initialized;
|
||||
|
||||
static void promisor_remote_init(void)
|
||||
static void promisor_remote_init(struct repository *r)
|
||||
{
|
||||
if (initialized)
|
||||
struct promisor_remote_config *config;
|
||||
|
||||
if (r->promisor_remote_config)
|
||||
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;
|
||||
|
||||
o = promisor_remote_lookup(the_repository->repository_format_partial_clone,
|
||||
o = promisor_remote_lookup(config,
|
||||
r->repository_format_partial_clone,
|
||||
&previous);
|
||||
if (o)
|
||||
promisor_remote_move_to_tail(o, previous);
|
||||
promisor_remote_move_to_tail(config, o, previous);
|
||||
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) {
|
||||
struct promisor_remote *r = promisors;
|
||||
promisors = promisors->next;
|
||||
while (config->promisors) {
|
||||
struct promisor_remote *r = config->promisors;
|
||||
config->promisors = config->promisors->next;
|
||||
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();
|
||||
promisor_remote_init();
|
||||
promisor_remote_clear(r->promisor_remote_config);
|
||||
FREE_AND_NULL(r->promisor_remote_config);
|
||||
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)
|
||||
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,
|
||||
@ -228,9 +238,11 @@ int promisor_remote_get_direct(struct repository *repo,
|
||||
if (oid_nr == 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 (remaining_nr == 1)
|
||||
continue;
|
||||
|
@ -17,9 +17,25 @@ struct promisor_remote {
|
||||
const char name[FLEX_ARRAY];
|
||||
};
|
||||
|
||||
void promisor_remote_reinit(void);
|
||||
struct promisor_remote *promisor_remote_find(const char *remote_name);
|
||||
int has_promisor_remote(void);
|
||||
void repo_promisor_remote_reinit(struct repository *r);
|
||||
static inline void promisor_remote_reinit(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
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "lockfile.h"
|
||||
#include "submodule-config.h"
|
||||
#include "sparse-index.h"
|
||||
#include "promisor-remote.h"
|
||||
|
||||
/* The main repository */
|
||||
static struct repository the_repo;
|
||||
@ -262,6 +263,11 @@ void repo_clear(struct repository *repo)
|
||||
if (repo->index != &the_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)
|
||||
|
@ -10,6 +10,7 @@ struct lock_file;
|
||||
struct pathspec;
|
||||
struct raw_object_store;
|
||||
struct submodule_cache;
|
||||
struct promisor_remote_config;
|
||||
|
||||
enum untracked_cache_setting {
|
||||
UNTRACKED_CACHE_UNSET = -1,
|
||||
@ -141,6 +142,7 @@ struct repository {
|
||||
|
||||
/* Configurations related to promisor remotes. */
|
||||
char *repository_format_partial_clone;
|
||||
struct promisor_remote_config *promisor_remote_config;
|
||||
|
||||
/* Configurations */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user