Message ID | c462927ff222501ade111003d9e063bf06d3a0b0.1623111879.git.jonathantanmy@google.com (mailing list archive) |
---|---|
State | Superseded |
Headers | show |
Series | First steps towards partial clone submodules | expand |
Jonathan Tan <jonathantanmy@google.com> writes: > 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. This does make sense. In general, repository extensions are per repository, so anything read from "extensions.*" should be stored per in-core repository structure. But doesn't that mean the thing that should be fixed is on the setup.c side, where not just extensions.partialClone but other data is read into "struct repository_format *format"? Shouldn't we have a pointer to that struct in the in-core repository object? Special casing the "partialClone" field alone feels somewhat strange to me. Thanks. > 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> > --- > promisor-remote.c | 103 ++++++++++++++++++++++++++-------------------- > promisor-remote.h | 22 ++++++++-- > repository.c | 6 +++ > repository.h | 4 ++ > 4 files changed, 87 insertions(+), 48 deletions(-) > > diff --git a/promisor-remote.c b/promisor-remote.c > index c0e5061dfe..e1e1f7e93a 100644 > --- a/promisor-remote.c > +++ b/promisor-remote.c > @@ -5,7 +5,11 @@ > #include "transport.h" > #include "strvec.h" > > -static char *repository_format_partial_clone; > +struct promisor_remote_config { > + char *repository_format_partial_clone; > + struct promisor_remote *promisors; > + struct promisor_remote **promisors_tail; > +}; > > static int fetch_objects(const char *remote_name, > const struct object_id *oids, > @@ -37,10 +41,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; > > @@ -52,18 +54,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; > @@ -73,7 +76,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) > @@ -82,14 +86,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; > @@ -99,7 +104,7 @@ static int promisor_remote_config(const char *var, const char *value, void *data > * NULL value is handled in handle_extension_v0 in setup.c. > */ > if (value) > - repository_format_partial_clone = xstrdup(value); > + config->repository_format_partial_clone = xstrdup(value); > return 0; > } > > @@ -114,8 +119,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; > @@ -124,9 +129,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); > > @@ -139,59 +144,65 @@ 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); > + git_config(promisor_remote_config, config); > > - if (repository_format_partial_clone) { > + if (config->repository_format_partial_clone) { > struct promisor_remote *o, *previous; > > - o = promisor_remote_lookup(repository_format_partial_clone, > + o = promisor_remote_lookup(config, > + config->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(repository_format_partial_clone); > + promisor_remote_new(config, config->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; > + FREE_AND_NULL(config->repository_format_partial_clone); > + > + 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, > @@ -239,9 +250,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; > diff --git a/promisor-remote.h b/promisor-remote.h > index 687210ab87..edc45ab0f5 100644 > --- a/promisor-remote.h > +++ b/promisor-remote.h > @@ -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 > diff --git a/repository.c b/repository.c > index 448cd557d4..dca0a11ab6 100644 > --- a/repository.c > +++ b/repository.c > @@ -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; > @@ -258,6 +259,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) > diff --git a/repository.h b/repository.h > index a45f7520fd..fc06c154e2 100644 > --- a/repository.h > +++ b/repository.h > @@ -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, > @@ -139,6 +140,9 @@ struct repository { > /* True if commit-graph has been disabled within this process. */ > int commit_graph_disabled; > > + /* Configurations related to promisor remotes. */ > + struct promisor_remote_config *promisor_remote_config; > + > /* Configurations */ > > /* Indicate if a repository has a different 'commondir' from 'gitdir' */
> Jonathan Tan <jonathantanmy@google.com> writes: > > > 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. > > This does make sense. In general, repository extensions are per > repository, so anything read from "extensions.*" should be stored > per in-core repository structure. > > But doesn't that mean the thing that should be fixed is on the > setup.c side, where not just extensions.partialClone but other data > is read into "struct repository_format *format"? Shouldn't we have > a pointer to that struct in the in-core repository object? > > Special casing the "partialClone" field alone feels somewhat strange > to me. > > Thanks. My reply is the same as what I replied to the query in patch 1 [1]. [1] https://lore.kernel.org/git/20210609042649.2322758-1-jonathantanmy@google.com/
diff --git a/promisor-remote.c b/promisor-remote.c index c0e5061dfe..e1e1f7e93a 100644 --- a/promisor-remote.c +++ b/promisor-remote.c @@ -5,7 +5,11 @@ #include "transport.h" #include "strvec.h" -static char *repository_format_partial_clone; +struct promisor_remote_config { + char *repository_format_partial_clone; + struct promisor_remote *promisors; + struct promisor_remote **promisors_tail; +}; static int fetch_objects(const char *remote_name, const struct object_id *oids, @@ -37,10 +41,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; @@ -52,18 +54,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; @@ -73,7 +76,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) @@ -82,14 +86,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; @@ -99,7 +104,7 @@ static int promisor_remote_config(const char *var, const char *value, void *data * NULL value is handled in handle_extension_v0 in setup.c. */ if (value) - repository_format_partial_clone = xstrdup(value); + config->repository_format_partial_clone = xstrdup(value); return 0; } @@ -114,8 +119,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; @@ -124,9 +129,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); @@ -139,59 +144,65 @@ 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); + git_config(promisor_remote_config, config); - if (repository_format_partial_clone) { + if (config->repository_format_partial_clone) { struct promisor_remote *o, *previous; - o = promisor_remote_lookup(repository_format_partial_clone, + o = promisor_remote_lookup(config, + config->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(repository_format_partial_clone); + promisor_remote_new(config, config->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; + FREE_AND_NULL(config->repository_format_partial_clone); + + 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, @@ -239,9 +250,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; diff --git a/promisor-remote.h b/promisor-remote.h index 687210ab87..edc45ab0f5 100644 --- a/promisor-remote.h +++ b/promisor-remote.h @@ -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 diff --git a/repository.c b/repository.c index 448cd557d4..dca0a11ab6 100644 --- a/repository.c +++ b/repository.c @@ -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; @@ -258,6 +259,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) diff --git a/repository.h b/repository.h index a45f7520fd..fc06c154e2 100644 --- a/repository.h +++ b/repository.h @@ -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, @@ -139,6 +140,9 @@ struct repository { /* True if commit-graph has been disabled within this process. */ int commit_graph_disabled; + /* Configurations related to promisor remotes. */ + struct promisor_remote_config *promisor_remote_config; + /* Configurations */ /* Indicate if a repository has a different 'commondir' from 'gitdir' */
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> --- promisor-remote.c | 103 ++++++++++++++++++++++++++-------------------- promisor-remote.h | 22 ++++++++-- repository.c | 6 +++ repository.h | 4 ++ 4 files changed, 87 insertions(+), 48 deletions(-)