remote: move static variables into per-repository struct
remote.c does not works with non-the_repository because it stores its state as static variables. To support non-the_repository, we can use a per-repository struct for the remotes subsystem. Prepare for this change by defining a struct remote_state that holds the remotes subsystem state and move the static variables of remote.c into the_repository->remote_state. This introduces no behavioral or API changes. Signed-off-by: Glen Choo <chooglen@google.com> Reviewed-by: Jonathan Tan <jonathantanmy@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Glen Choo committed
Nov 17, 2021 at 16:53 UTC
fd3cb0501e175bcac042587cb7bb75e16034a5b7
4 files changed
+170
-67
remote.c
+124
-67
@@ -21,33 +21,6 @@ struct counted_string {
21
size_t len;
22
const char *s;
23
};
24
-struct rewrite {
25
- const char *base;
26
- size_t baselen;
27
- struct counted_string *instead_of;
28
- int instead_of_nr;
29
- int instead_of_alloc;
30
-};
31
-struct rewrites {
32
- struct rewrite **rewrite;
33
- int rewrite_alloc;
34
- int rewrite_nr;
35
-};
36
-
37
-static struct remote **remotes;
38
-static int remotes_alloc;
39
-static int remotes_nr;
40
-static struct hashmap remotes_hash;
41
-
42
-static struct branch **branches;
43
-static int branches_alloc;
44
-static int branches_nr;
45
-
46
-static struct branch *current_branch;
47
-static const char *pushremote_name;
48
-
49
-static struct rewrites rewrites;
50
-static struct rewrites rewrites_push;
24
25
static int valid_remote(const struct remote *remote)
26
{
@@ -94,14 +67,16 @@ static void add_pushurl(struct remote *remote, const char *pushurl)
67
68
static void add_pushurl_alias(struct remote *remote, const char *url)
69
{
97
- const char *pushurl = alias_url(url, &rewrites_push);
70
+ const char *pushurl =
71
+ alias_url(url, &the_repository->remote_state->rewrites_push);
72
if (pushurl != url)
73
add_pushurl(remote, pushurl);
74
}
75
76
static void add_url_alias(struct remote *remote, const char *url)
77
{
104
- add_url(remote, alias_url(url, &rewrites));
78
+ add_url(remote,
79
+ alias_url(url, &the_repository->remote_state->rewrites));
80
add_pushurl_alias(remote, url);
81
}
82
@@ -127,12 +102,6 @@ static int remotes_hash_cmp(const void *unused_cmp_data,
102
return strcmp(a->name, b->name);
103
}
104
130
-static inline void init_remotes_hash(void)
131
-{
132
- if (!remotes_hash.cmpfn)
133
- hashmap_init(&remotes_hash, remotes_hash_cmp, NULL, 0);
134
-}
135
-
105
static struct remote *make_remote(const char *name, int len)
106
{
107
struct remote *ret;
@@ -142,12 +111,12 @@ static struct remote *make_remote(const char *name, int len)
111
if (!len)
112
len = strlen(name);
113
145
- init_remotes_hash();
114
lookup.str = name;
115
lookup.len = len;
116
hashmap_entry_init(&lookup_entry, memhash(name, len));
117
150
- e = hashmap_get(&remotes_hash, &lookup_entry, &lookup);
118
+ e = hashmap_get(&the_repository->remote_state->remotes_hash,
119
+ &lookup_entry, &lookup);
120
if (e)
121
return container_of(e, struct remote, ent);
122
@@ -158,15 +127,41 @@ static struct remote *make_remote(const char *name, int len)
127
refspec_init(&ret->push, REFSPEC_PUSH);
128
refspec_init(&ret->fetch, REFSPEC_FETCH);
129
161
- ALLOC_GROW(remotes, remotes_nr + 1, remotes_alloc);
162
- remotes[remotes_nr++] = ret;
130
+ ALLOC_GROW(the_repository->remote_state->remotes,
131
+ the_repository->remote_state->remotes_nr + 1,
132
+ the_repository->remote_state->remotes_alloc);
133
+ the_repository->remote_state
134
+ ->remotes[the_repository->remote_state->remotes_nr++] = ret;
135
136
hashmap_entry_init(&ret->ent, lookup_entry.hash);
165
- if (hashmap_put_entry(&remotes_hash, ret, ent))
137
+ if (hashmap_put_entry(&the_repository->remote_state->remotes_hash, ret,
138
+ ent))
139
BUG("hashmap_put overwrote entry after hashmap_get returned NULL");
140
return ret;
141
}
142
143
+static void remote_clear(struct remote *remote)
144
+{
145
+ int i;
146
+
147
+ free((char *)remote->name);
148
+ free((char *)remote->foreign_vcs);
149
+
150
+ for (i = 0; i < remote->url_nr; i++) {
151
+ free((char *)remote->url[i]);
152
+ }
153
+ FREE_AND_NULL(remote->pushurl);
154
+
155
+ for (i = 0; i < remote->pushurl_nr; i++) {
156
+ free((char *)remote->pushurl[i]);
157
+ }
158
+ FREE_AND_NULL(remote->pushurl);
159
+ free((char *)remote->receivepack);
160
+ free((char *)remote->uploadpack);
161
+ FREE_AND_NULL(remote->http_proxy);
162
+ FREE_AND_NULL(remote->http_proxy_authmethod);
163
+}
164
+
165
static void add_merge(struct branch *branch, const char *name)
166
{
167
ALLOC_GROW(branch->merge_name, branch->merge_nr + 1,
@@ -179,15 +174,20 @@ static struct branch *make_branch(const char *name, size_t len)
174
struct branch *ret;
175
int i;
176
182
- for (i = 0; i < branches_nr; i++) {
183
- if (!strncmp(name, branches[i]->name, len) &&
184
- !branches[i]->name[len])
185
- return branches[i];
177
+ for (i = 0; i < the_repository->remote_state->branches_nr; i++) {
178
+ if (!strncmp(name,
179
+ the_repository->remote_state->branches[i]->name,
180
+ len) &&
181
+ !the_repository->remote_state->branches[i]->name[len])
182
+ return the_repository->remote_state->branches[i];
183
}
184
188
- ALLOC_GROW(branches, branches_nr + 1, branches_alloc);
185
+ ALLOC_GROW(the_repository->remote_state->branches,
186
+ the_repository->remote_state->branches_nr + 1,
187
+ the_repository->remote_state->branches_alloc);
188
CALLOC_ARRAY(ret, 1);
190
- branches[branches_nr++] = ret;
189
+ the_repository->remote_state
190
+ ->branches[the_repository->remote_state->branches_nr++] = ret;
191
ret->name = xstrndup(name, len);
192
ret->refname = xstrfmt("refs/heads/%s", ret->name);
193
@@ -327,12 +327,16 @@ static int handle_config(const char *key, const char *value, void *cb)
327
if (!strcmp(subkey, "insteadof")) {
328
if (!value)
329
return config_error_nonbool(key);
330
- rewrite = make_rewrite(&rewrites, name, namelen);
330
+ rewrite = make_rewrite(
331
+ &the_repository->remote_state->rewrites, name,
332
+ namelen);
333
add_instead_of(rewrite, xstrdup(value));
334
} else if (!strcmp(subkey, "pushinsteadof")) {
335
if (!value)
336
return config_error_nonbool(key);
335
- rewrite = make_rewrite(&rewrites_push, name, namelen);
337
+ rewrite = make_rewrite(
338
+ &the_repository->remote_state->rewrites_push,
339
+ name, namelen);
340
add_instead_of(rewrite, xstrdup(value));
341
}
342
}
@@ -342,7 +346,9 @@ static int handle_config(const char *key, const char *value, void *cb)
346
347
/* Handle remote.* variables */
348
if (!name && !strcmp(subkey, "pushdefault"))
345
- return git_config_string(&pushremote_name, key, value);
349
+ return git_config_string(
350
+ &the_repository->remote_state->pushremote_name, key,
351
+ value);
352
353
if (!name)
354
return 0;
@@ -425,18 +431,34 @@ static int handle_config(const char *key, const char *value, void *cb)
431
static void alias_all_urls(void)
432
{
433
int i, j;
428
- for (i = 0; i < remotes_nr; i++) {
434
+ for (i = 0; i < the_repository->remote_state->remotes_nr; i++) {
435
int add_pushurl_aliases;
430
- if (!remotes[i])
436
+ if (!the_repository->remote_state->remotes[i])
437
continue;
432
- for (j = 0; j < remotes[i]->pushurl_nr; j++) {
433
- remotes[i]->pushurl[j] = alias_url(remotes[i]->pushurl[j], &rewrites);
438
+ for (j = 0;
439
+ j < the_repository->remote_state->remotes[i]->pushurl_nr;
440
+ j++) {
441
+ the_repository->remote_state->remotes[i]->pushurl[j] =
442
+ alias_url(
443
+ the_repository->remote_state->remotes[i]
444
+ ->pushurl[j],
445
+ &the_repository->remote_state->rewrites);
446
}
435
- add_pushurl_aliases = remotes[i]->pushurl_nr == 0;
436
- for (j = 0; j < remotes[i]->url_nr; j++) {
447
+ add_pushurl_aliases =
448
+ the_repository->remote_state->remotes[i]->pushurl_nr ==
449
+ 0;
450
+ for (j = 0;
451
+ j < the_repository->remote_state->remotes[i]->url_nr;
452
+ j++) {
453
if (add_pushurl_aliases)
438
- add_pushurl_alias(remotes[i], remotes[i]->url[j]);
439
- remotes[i]->url[j] = alias_url(remotes[i]->url[j], &rewrites);
454
+ add_pushurl_alias(
455
+ the_repository->remote_state->remotes[i],
456
+ the_repository->remote_state->remotes[i]
457
+ ->url[j]);
458
+ the_repository->remote_state->remotes[i]
459
+ ->url[j] = alias_url(
460
+ the_repository->remote_state->remotes[i]->url[j],
461
+ &the_repository->remote_state->rewrites);
462
}
463
}
464
}
@@ -450,12 +472,13 @@ static void read_config(void)
472
return;
473
loaded = 1;
474
453
- current_branch = NULL;
475
+ the_repository->remote_state->current_branch = NULL;
476
if (startup_info->have_repository) {
477
const char *head_ref = resolve_ref_unsafe("HEAD", 0, NULL, &flag);
478
if (head_ref && (flag & REF_ISSYMREF) &&
479
skip_prefix(head_ref, "refs/heads/", &head_ref)) {
458
- current_branch = make_branch(head_ref, strlen(head_ref));
480
+ the_repository->remote_state->current_branch =
481
+ make_branch(head_ref, strlen(head_ref));
482
}
483
}
484
git_config(handle_config, NULL);
@@ -493,10 +516,10 @@ const char *pushremote_for_branch(struct branch *branch, int *explicit)
516
*explicit = 1;
517
return branch->pushremote_name;
518
}
496
- if (pushremote_name) {
519
+ if (the_repository->remote_state->pushremote_name) {
520
if (explicit)
521
*explicit = 1;
499
- return pushremote_name;
522
+ return the_repository->remote_state->pushremote_name;
523
}
524
return remote_for_branch(branch, explicit);
525
}
@@ -534,7 +557,8 @@ static struct remote *remote_get_1(const char *name,
557
if (name)
558
name_given = 1;
559
else
537
- name = get_default(current_branch, &name_given);
560
+ name = get_default(the_repository->remote_state->current_branch,
561
+ &name_given);
562
563
ret = make_remote(name, 0);
564
if (valid_remote_nick(name) && have_git_dir()) {
@@ -573,11 +597,13 @@ int for_each_remote(each_remote_fn fn, void *priv)
597
{
598
int i, result = 0;
599
read_config();
576
- for (i = 0; i < remotes_nr && !result; i++) {
577
- struct remote *r = remotes[i];
578
- if (!r)
600
+ for (i = 0; i < the_repository->remote_state->remotes_nr && !result;
601
+ i++) {
602
+ struct remote *remote =
603
+ the_repository->remote_state->remotes[i];
604
+ if (!remote)
605
continue;
580
- result = fn(r, priv);
606
+ result = fn(remote, priv);
607
}
608
return result;
609
}
@@ -1685,7 +1711,7 @@ struct branch *branch_get(const char *name)
1711
1712
read_config();
1713
if (!name || !*name || !strcmp(name, "HEAD"))
1688
- ret = current_branch;
1714
+ ret = the_repository->remote_state->current_branch;
1715
else
1716
ret = make_branch(name, strlen(name));
1717
set_merge(ret);
@@ -2585,3 +2611,34 @@ void apply_push_cas(struct push_cas_option *cas,
2611
check_if_includes_upstream(ref);
2612
}
2613
}
2614
+
2615
+struct remote_state *remote_state_new(void)
2616
+{
2617
+ struct remote_state *r = xmalloc(sizeof(*r));
2618
+
2619
+ memset(r, 0, sizeof(*r));
2620
+
2621
+ hashmap_init(&r->remotes_hash, remotes_hash_cmp, NULL, 0);
2622
+ return r;
2623
+}
2624
+
2625
+void remote_state_clear(struct remote_state *remote_state)
2626
+{
2627
+ int i;
2628
+
2629
+ for (i = 0; i < remote_state->remotes_nr; i++) {
2630
+ remote_clear(remote_state->remotes[i]);
2631
+ }
2632
+ FREE_AND_NULL(remote_state->remotes);
2633
+ remote_state->remotes_alloc = 0;
2634
+ remote_state->remotes_nr = 0;
2635
+
2636
+ hashmap_clear_and_free(&remote_state->remotes_hash, struct remote, ent);
2637
+
2638
+ for (i = 0; i < remote_state->branches_nr; i++) {
2639
+ FREE_AND_NULL(remote_state->branches[i]);
2640
+ }
2641
+ FREE_AND_NULL(remote_state->branches);
2642
+ remote_state->branches_alloc = 0;
2643
+ remote_state->branches_nr = 0;
2644
+}
remote.h
+34
@@ -23,6 +23,40 @@ enum {
23
REMOTE_BRANCHES
24
};
25
26
+struct rewrite {
27
+ const char *base;
28
+ size_t baselen;
29
+ struct counted_string *instead_of;
30
+ int instead_of_nr;
31
+ int instead_of_alloc;
32
+};
33
+
34
+struct rewrites {
35
+ struct rewrite **rewrite;
36
+ int rewrite_alloc;
37
+ int rewrite_nr;
38
+};
39
+
40
+struct remote_state {
41
+ struct remote **remotes;
42
+ int remotes_alloc;
43
+ int remotes_nr;
44
+ struct hashmap remotes_hash;
45
+
46
+ struct branch **branches;
47
+ int branches_alloc;
48
+ int branches_nr;
49
+
50
+ struct branch *current_branch;
51
+ const char *pushremote_name;
52
+
53
+ struct rewrites rewrites;
54
+ struct rewrites rewrites_push;
55
+};
56
+
57
+void remote_state_clear(struct remote_state *remote_state);
58
+struct remote_state *remote_state_new(void);
59
+
60
struct remote {
61
struct hashmap_entry ent;
62
repository.c
+8
@@ -9,6 +9,7 @@
9
#include "config.h"
10
#include "object.h"
11
#include "lockfile.h"
12
+#include "remote.h"
13
#include "submodule-config.h"
14
#include "sparse-index.h"
15
#include "promisor-remote.h"
@@ -24,6 +25,7 @@ void initialize_the_repository(void)
25
26
the_repo.index = &the_index;
27
the_repo.objects = raw_object_store_new();
28
+ the_repo.remote_state = remote_state_new();
29
the_repo.parsed_objects = parsed_object_pool_new();
30
31
repo_set_hash_algo(&the_repo, GIT_HASH_SHA1);
@@ -164,6 +166,7 @@ int repo_init(struct repository *repo,
166
167
repo->objects = raw_object_store_new();
168
repo->parsed_objects = parsed_object_pool_new();
169
+ repo->remote_state = remote_state_new();
170
171
if (repo_init_gitdir(repo, gitdir))
172
goto error;
@@ -270,6 +273,11 @@ void repo_clear(struct repository *repo)
273
promisor_remote_clear(repo->promisor_remote_config);
274
FREE_AND_NULL(repo->promisor_remote_config);
275
}
276
+
277
+ if (repo->remote_state) {
278
+ remote_state_clear(repo->remote_state);
279
+ FREE_AND_NULL(repo->remote_state);
280
+ }
281
}
282
283
int repo_read_index(struct repository *repo)
repository.h
+4
@@ -11,6 +11,7 @@ struct pathspec;
11
struct raw_object_store;
12
struct submodule_cache;
13
struct promisor_remote_config;
14
+struct remote_state;
15
16
enum untracked_cache_setting {
17
UNTRACKED_CACHE_KEEP,
@@ -127,6 +128,9 @@ struct repository {
128
*/
129
struct index_state *index;
130
131
+ /* Repository's remotes and associated structures. */
132
+ struct remote_state *remote_state;
133
+
134
/* Repository's current hash algorithm, as serialized on disk. */
135
const struct git_hash_algo *hash_algo;
136