From ebaf3bcf1aecdc31062ede80fca3a7c98202d8bb Mon Sep 17 00:00:00 2001 From: Jonathan Tan Date: Thu, 17 Jun 2021 10:13:22 -0700 Subject: repository: move global r_f_p_c to repo struct Move repository_format_partial_clone, which is currently a global variable, into struct repository. (Full support for per-repository partial clone config will be done in a subsequent commit - this is split into its own commit because of the extent of the changes needed.) The new repo-specific variable cannot be set in check_repository_format_gently() (as is currently), because that function does not know which repo it is operating on (or even whether the value is important); therefore this responsibility is delegated to the outermost caller that knows. Of all the outermost callers that know (found by looking at all functions that call clear_repository_format()), I looked at those that either read from the main Git directory or write into a struct repository. These callers have been modified accordingly (write to the_repository in the former case and write to the given struct repository in the latter case). Signed-off-by: Jonathan Tan Signed-off-by: Junio C Hamano Reviewed-by: Elijah Newren Signed-off-by: Junio C Hamano --- promisor-remote.c | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) (limited to 'promisor-remote.c') diff --git a/promisor-remote.c b/promisor-remote.c index da3f2ca261..d24081dc21 100644 --- a/promisor-remote.c +++ b/promisor-remote.c @@ -5,13 +5,6 @@ #include "transport.h" #include "strvec.h" -static char *repository_format_partial_clone; - -void set_repository_format_partial_clone(char *partial_clone) -{ - repository_format_partial_clone = xstrdup_or_null(partial_clone); -} - static int fetch_objects(const char *remote_name, const struct object_id *oids, int oid_nr) @@ -145,15 +138,15 @@ static void promisor_remote_init(void) git_config(promisor_remote_config, NULL); - if (repository_format_partial_clone) { + if (the_repository->repository_format_partial_clone) { struct promisor_remote *o, *previous; - o = promisor_remote_lookup(repository_format_partial_clone, + o = promisor_remote_lookup(the_repository->repository_format_partial_clone, &previous); if (o) promisor_remote_move_to_tail(o, previous); else - promisor_remote_new(repository_format_partial_clone); + promisor_remote_new(the_repository->repository_format_partial_clone); } } -- cgit v1.2.3 From ef7dc2e9ccb832c1dc29d5102c09f6c4a51d4dca Mon Sep 17 00:00:00 2001 From: Jonathan Tan Date: Thu, 17 Jun 2021 10:13:23 -0700 Subject: 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 Signed-off-by: Junio C Hamano Reviewed-by: Elijah Newren Signed-off-by: Junio C Hamano --- promisor-remote.c | 98 +++++++++++++++++++++++++++++++------------------------ 1 file changed, 55 insertions(+), 43 deletions(-) (limited to 'promisor-remote.c') diff --git a/promisor-remote.c b/promisor-remote.c index d24081dc21..1e00e16b0f 100644 --- a/promisor-remote.c +++ b/promisor-remote.c @@ -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; -- cgit v1.2.3 From ef830cc4341260ef45ffe6c7164e23505d45a5a2 Mon Sep 17 00:00:00 2001 From: Jonathan Tan Date: Thu, 17 Jun 2021 10:13:26 -0700 Subject: promisor-remote: teach lazy-fetch in any repo This is one step towards supporting partial clone submodules. Even after this patch, we will still lack partial clone submodules support, primarily because a lot of Git code that accesses submodule objects does so by adding their object stores as alternates, meaning that any lazy fetches that would occur in the submodule would be done based on the config of the superproject, not of the submodule. This also prevents testing of the functionality in this patch by user-facing commands. So for now, test this mechanism using a test helper. Besides that, there is some code that uses the wrapper functions like has_promisor_remote(). Those will need to be checked to see if they could support the non-wrapper functions instead (and thus support any repository, not just the_repository). Signed-off-by: Jonathan Tan Signed-off-by: Junio C Hamano Reviewed-by: Elijah Newren Signed-off-by: Junio C Hamano --- promisor-remote.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'promisor-remote.c') diff --git a/promisor-remote.c b/promisor-remote.c index 1e00e16b0f..c088dcbff3 100644 --- a/promisor-remote.c +++ b/promisor-remote.c @@ -10,7 +10,8 @@ struct promisor_remote_config { struct promisor_remote **promisors_tail; }; -static int fetch_objects(const char *remote_name, +static int fetch_objects(struct repository *repo, + const char *remote_name, const struct object_id *oids, int oid_nr) { @@ -20,6 +21,8 @@ static int fetch_objects(const char *remote_name, child.git_cmd = 1; child.in = -1; + if (repo != the_repository) + prepare_other_repo_env(&child.env_array, repo->gitdir); strvec_pushl(&child.args, "-c", "fetch.negotiationAlgorithm=noop", "fetch", remote_name, "--no-tags", "--no-write-fetch-head", "--recurse-submodules=no", @@ -240,10 +243,8 @@ int promisor_remote_get_direct(struct repository *repo, promisor_remote_init(repo); - 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(repo, r->name, remaining_oids, remaining_nr) < 0) { if (remaining_nr == 1) continue; remaining_nr = remove_fetched_oids(repo, &remaining_oids, -- cgit v1.2.3