Add initial support for many promisor remotes

The promisor-remote.{c,h} files will contain functions to manage many promisor remotes. We expect that there will not be a lot of promisor remotes, so it is ok to use a simple linked list to manage them. Helped-by: Jeff King <peff@peff.net> Helped-by: SZEDER Gábor <szeder.dev@gmail.com> Signed-off-by: Christian Couder <chriscool@tuxfamily.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Christian Couder committed Jun 25, 2019 at 15:40 UTC 48de315817281e49a5e9000d40550b5257b437c6
3 files changed +109
Makefile
+1
@@ -944,6 +944,7 @@ LIB_OBJS += preload-index.o
944 LIB_OBJS += pretty.o
945 LIB_OBJS += prio-queue.o
946 LIB_OBJS += progress.o
947 +LIB_OBJS += promisor-remote.o
948 LIB_OBJS += prompt.o
949 LIB_OBJS += protocol.o
950 LIB_OBJS += quote.o
promisor-remote.c new
+92
@@ -0,0 +1,92 @@
1 +#include "cache.h"
2 +#include "promisor-remote.h"
3 +#include "config.h"
4 +
5 +static struct promisor_remote *promisors;
6 +static struct promisor_remote **promisors_tail = &promisors;
7 +
8 +static struct promisor_remote *promisor_remote_new(const char *remote_name)
9 +{
10 + struct promisor_remote *r;
11 +
12 + if (*remote_name == '/') {
13 + warning(_("promisor remote name cannot begin with '/': %s"),
14 + remote_name);
15 + return NULL;
16 + }
17 +
18 + FLEX_ALLOC_STR(r, name, remote_name);
19 +
20 + *promisors_tail = r;
21 + promisors_tail = &r->next;
22 +
23 + return r;
24 +}
25 +
26 +static struct promisor_remote *promisor_remote_lookup(const char *remote_name,
27 + struct promisor_remote **previous)
28 +{
29 + struct promisor_remote *r, *p;
30 +
31 + for (p = NULL, r = promisors; r; p = r, r = r->next)
32 + if (!strcmp(r->name, remote_name)) {
33 + if (previous)
34 + *previous = p;
35 + return r;
36 + }
37 +
38 + return NULL;
39 +}
40 +
41 +static int promisor_remote_config(const char *var, const char *value, void *data)
42 +{
43 + const char *name;
44 + int namelen;
45 + const char *subkey;
46 +
47 + if (parse_config_key(var, "remote", &name, &namelen, &subkey) < 0)
48 + return 0;
49 +
50 + if (!strcmp(subkey, "promisor")) {
51 + char *remote_name;
52 +
53 + if (!git_config_bool(var, value))
54 + return 0;
55 +
56 + remote_name = xmemdupz(name, namelen);
57 +
58 + if (!promisor_remote_lookup(remote_name, NULL))
59 + promisor_remote_new(remote_name);
60 +
61 + free(remote_name);
62 + return 0;
63 + }
64 +
65 + return 0;
66 +}
67 +
68 +static void promisor_remote_init(void)
69 +{
70 + static int initialized;
71 +
72 + if (initialized)
73 + return;
74 + initialized = 1;
75 +
76 + git_config(promisor_remote_config, NULL);
77 +}
78 +
79 +struct promisor_remote *promisor_remote_find(const char *remote_name)
80 +{
81 + promisor_remote_init();
82 +
83 + if (!remote_name)
84 + return promisors;
85 +
86 + return promisor_remote_lookup(remote_name, NULL);
87 +}
88 +
89 +int has_promisor_remote(void)
90 +{
91 + return !!promisor_remote_find(NULL);
92 +}
promisor-remote.h new
+16
@@ -0,0 +1,16 @@
1 +#ifndef PROMISOR_REMOTE_H
2 +#define PROMISOR_REMOTE_H
3 +
4 +/*
5 + * Promisor remote linked list
6 + * Its information come from remote.XXX config entries.
7 + */
8 +struct promisor_remote {
9 + struct promisor_remote *next;
10 + const char name[FLEX_ARRAY];
11 +};
12 +
13 +extern struct promisor_remote *promisor_remote_find(const char *remote_name);
14 +extern int has_promisor_remote(void);
15 +
16 +#endif /* PROMISOR_REMOTE_H */