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>
Jonathan Tan committed
Jun 17, 2021 at 10:13 UTC
ef7dc2e9ccb832c1dc29d5102c09f6c4a51d4dca
4 files changed
+82
-46
promisor-remote.c
+55
-43
@@ -5,6 +5,11 @@
5
#include "transport.h"
6
#include "strvec.h"
7
8
+struct promisor_remote_config {
9
+ struct promisor_remote *promisors;
10
+ struct promisor_remote **promisors_tail;
11
+};
12
+
13
static int fetch_objects(const char *remote_name,
14
const struct object_id *oids,
15
int oid_nr)
@@ -35,10 +40,8 @@ static int fetch_objects(const char *remote_name,
40
return finish_command(&child) ? -1 : 0;
41
}
42
38
-static struct promisor_remote *promisors;
39
-static struct promisor_remote **promisors_tail = &promisors;
40
-
41
-static struct promisor_remote *promisor_remote_new(const char *remote_name)
43
+static struct promisor_remote *promisor_remote_new(struct promisor_remote_config *config,
44
+ const char *remote_name)
45
{
46
struct promisor_remote *r;
47
@@ -50,18 +53,19 @@ static struct promisor_remote *promisor_remote_new(const char *remote_name)
53
54
FLEX_ALLOC_STR(r, name, remote_name);
55
53
- *promisors_tail = r;
54
- promisors_tail = &r->next;
56
+ *config->promisors_tail = r;
57
+ config->promisors_tail = &r->next;
58
59
return r;
60
}
61
59
-static struct promisor_remote *promisor_remote_lookup(const char *remote_name,
62
+static struct promisor_remote *promisor_remote_lookup(struct promisor_remote_config *config,
63
+ const char *remote_name,
64
struct promisor_remote **previous)
65
{
66
struct promisor_remote *r, *p;
67
64
- for (p = NULL, r = promisors; r; p = r, r = r->next)
68
+ for (p = NULL, r = config->promisors; r; p = r, r = r->next)
69
if (!strcmp(r->name, remote_name)) {
70
if (previous)
71
*previous = p;
@@ -71,7 +75,8 @@ static struct promisor_remote *promisor_remote_lookup(const char *remote_name,
75
return NULL;
76
}
77
74
-static void promisor_remote_move_to_tail(struct promisor_remote *r,
78
+static void promisor_remote_move_to_tail(struct promisor_remote_config *config,
79
+ struct promisor_remote *r,
80
struct promisor_remote *previous)
81
{
82
if (r->next == NULL)
@@ -80,14 +85,15 @@ static void promisor_remote_move_to_tail(struct promisor_remote *r,
85
if (previous)
86
previous->next = r->next;
87
else
83
- promisors = r->next ? r->next : r;
88
+ config->promisors = r->next ? r->next : r;
89
r->next = NULL;
85
- *promisors_tail = r;
86
- promisors_tail = &r->next;
90
+ *config->promisors_tail = r;
91
+ config->promisors_tail = &r->next;
92
}
93
94
static int promisor_remote_config(const char *var, const char *value, void *data)
95
{
96
+ struct promisor_remote_config *config = data;
97
const char *name;
98
size_t namelen;
99
const char *subkey;
@@ -103,8 +109,8 @@ static int promisor_remote_config(const char *var, const char *value, void *data
109
110
remote_name = xmemdupz(name, namelen);
111
106
- if (!promisor_remote_lookup(remote_name, NULL))
107
- promisor_remote_new(remote_name);
112
+ if (!promisor_remote_lookup(config, remote_name, NULL))
113
+ promisor_remote_new(config, remote_name);
114
115
free(remote_name);
116
return 0;
@@ -113,9 +119,9 @@ static int promisor_remote_config(const char *var, const char *value, void *data
119
struct promisor_remote *r;
120
char *remote_name = xmemdupz(name, namelen);
121
116
- r = promisor_remote_lookup(remote_name, NULL);
122
+ r = promisor_remote_lookup(config, remote_name, NULL);
123
if (!r)
118
- r = promisor_remote_new(remote_name);
124
+ r = promisor_remote_new(config, remote_name);
125
126
free(remote_name);
127
@@ -128,59 +134,63 @@ static int promisor_remote_config(const char *var, const char *value, void *data
134
return 0;
135
}
136
131
-static int initialized;
132
-
133
-static void promisor_remote_init(void)
137
+static void promisor_remote_init(struct repository *r)
138
{
135
- if (initialized)
139
+ struct promisor_remote_config *config;
140
+
141
+ if (r->promisor_remote_config)
142
return;
137
- initialized = 1;
143
+ config = r->promisor_remote_config =
144
+ xcalloc(sizeof(*r->promisor_remote_config), 1);
145
+ config->promisors_tail = &config->promisors;
146
139
- git_config(promisor_remote_config, NULL);
147
+ repo_config(r, promisor_remote_config, config);
148
141
- if (the_repository->repository_format_partial_clone) {
149
+ if (r->repository_format_partial_clone) {
150
struct promisor_remote *o, *previous;
151
144
- o = promisor_remote_lookup(the_repository->repository_format_partial_clone,
152
+ o = promisor_remote_lookup(config,
153
+ r->repository_format_partial_clone,
154
&previous);
155
if (o)
147
- promisor_remote_move_to_tail(o, previous);
156
+ promisor_remote_move_to_tail(config, o, previous);
157
else
149
- promisor_remote_new(the_repository->repository_format_partial_clone);
158
+ promisor_remote_new(config, r->repository_format_partial_clone);
159
}
160
}
161
153
-static void promisor_remote_clear(void)
162
+void promisor_remote_clear(struct promisor_remote_config *config)
163
{
155
- while (promisors) {
156
- struct promisor_remote *r = promisors;
157
- promisors = promisors->next;
164
+ while (config->promisors) {
165
+ struct promisor_remote *r = config->promisors;
166
+ config->promisors = config->promisors->next;
167
free(r);
168
}
169
161
- promisors_tail = &promisors;
170
+ config->promisors_tail = &config->promisors;
171
}
172
164
-void promisor_remote_reinit(void)
173
+void repo_promisor_remote_reinit(struct repository *r)
174
{
166
- initialized = 0;
167
- promisor_remote_clear();
168
- promisor_remote_init();
175
+ promisor_remote_clear(r->promisor_remote_config);
176
+ FREE_AND_NULL(r->promisor_remote_config);
177
+ promisor_remote_init(r);
178
}
179
171
-struct promisor_remote *promisor_remote_find(const char *remote_name)
180
+struct promisor_remote *repo_promisor_remote_find(struct repository *r,
181
+ const char *remote_name)
182
{
173
- promisor_remote_init();
183
+ promisor_remote_init(r);
184
185
if (!remote_name)
176
- return promisors;
186
+ return r->promisor_remote_config->promisors;
187
178
- return promisor_remote_lookup(remote_name, NULL);
188
+ return promisor_remote_lookup(r->promisor_remote_config, remote_name, NULL);
189
}
190
181
-int has_promisor_remote(void)
191
+int repo_has_promisor_remote(struct repository *r)
192
{
183
- return !!promisor_remote_find(NULL);
193
+ return !!repo_promisor_remote_find(r, NULL);
194
}
195
196
static int remove_fetched_oids(struct repository *repo,
@@ -228,9 +238,11 @@ int promisor_remote_get_direct(struct repository *repo,
238
if (oid_nr == 0)
239
return 0;
240
231
- promisor_remote_init();
241
+ promisor_remote_init(repo);
242
233
- for (r = promisors; r; r = r->next) {
243
+ if (repo != the_repository)
244
+ BUG("only the_repository is supported for now");
245
+ for (r = repo->promisor_remote_config->promisors; r; r = r->next) {
246
if (fetch_objects(r->name, remaining_oids, remaining_nr) < 0) {
247
if (remaining_nr == 1)
248
continue;
promisor-remote.h
+19
-3
@@ -17,9 +17,25 @@ struct promisor_remote {
17
const char name[FLEX_ARRAY];
18
};
19
20
-void promisor_remote_reinit(void);
21
-struct promisor_remote *promisor_remote_find(const char *remote_name);
22
-int has_promisor_remote(void);
20
+void repo_promisor_remote_reinit(struct repository *r);
21
+static inline void promisor_remote_reinit(void)
22
+{
23
+ repo_promisor_remote_reinit(the_repository);
24
+}
25
+
26
+void promisor_remote_clear(struct promisor_remote_config *config);
27
+
28
+struct promisor_remote *repo_promisor_remote_find(struct repository *r, const char *remote_name);
29
+static inline struct promisor_remote *promisor_remote_find(const char *remote_name)
30
+{
31
+ return repo_promisor_remote_find(the_repository, remote_name);
32
+}
33
+
34
+int repo_has_promisor_remote(struct repository *r);
35
+static inline int has_promisor_remote(void)
36
+{
37
+ return repo_has_promisor_remote(the_repository);
38
+}
39
40
/*
41
* Fetches all requested objects from all promisor remotes, trying them one at
repository.c
+6
@@ -11,6 +11,7 @@
11
#include "lockfile.h"
12
#include "submodule-config.h"
13
#include "sparse-index.h"
14
+#include "promisor-remote.h"
15
16
/* The main repository */
17
static struct repository the_repo;
@@ -262,6 +263,11 @@ void repo_clear(struct repository *repo)
263
if (repo->index != &the_index)
264
FREE_AND_NULL(repo->index);
265
}
266
+
267
+ if (repo->promisor_remote_config) {
268
+ promisor_remote_clear(repo->promisor_remote_config);
269
+ FREE_AND_NULL(repo->promisor_remote_config);
270
+ }
271
}
272
273
int repo_read_index(struct repository *repo)
repository.h
+2
@@ -10,6 +10,7 @@ struct lock_file;
10
struct pathspec;
11
struct raw_object_store;
12
struct submodule_cache;
13
+struct promisor_remote_config;
14
15
enum untracked_cache_setting {
16
UNTRACKED_CACHE_UNSET = -1,
@@ -141,6 +142,7 @@ struct repository {
142
143
/* Configurations related to promisor remotes. */
144
char *repository_format_partial_clone;
145
+ struct promisor_remote_config *promisor_remote_config;
146
147
/* Configurations */
148