diff --git a/ls-refs.c b/ls-refs.c
index 88f6c3f60d8..02fbcfd9bde 100644
--- a/ls-refs.c
+++ b/ls-refs.c
@@ -7,37 +7,26 @@
#include "pkt-line.h"
#include "config.h"
-static int config_read;
-static int advertise_unborn;
-static int allow_unborn;
+/* "unborn" is on by default if there's no lsrefs.unborn config */
+static int advertise_unborn = 1;
+static int allow_unborn = 1;
-static void ensure_config_read(void)
+int ls_refs_startup_config(const char *var, const char *value, void *data)
{
- const char *str = NULL;
-
- if (config_read)
- return;
-
- if (repo_config_get_string_tmp(the_repository, "lsrefs.unborn", &str)) {
- /*
- * If there is no such config, advertise and allow it by
- * default.
- */
- advertise_unborn = 1;
- allow_unborn = 1;
- } else {
- if (!strcmp(str, "advertise")) {
- advertise_unborn = 1;
+ if (!strcmp(var, "lsrefs.unborn")) {
+ if (!strcmp(value, "advertise")) {
+ /* Allowed and advertised by default */
+ } else if (!strcmp(value, "allow")) {
+ advertise_unborn = 0;
allow_unborn = 1;
- } else if (!strcmp(str, "allow")) {
- allow_unborn = 1;
- } else if (!strcmp(str, "ignore")) {
- /* do nothing */
+ } else if (!strcmp(value, "ignore")) {
+ advertise_unborn = 0;
+ allow_unborn = 0;
} else {
- die(_("invalid value '%s' for lsrefs.unborn"), str);
+ die(_("invalid value '%s' for lsrefs.unborn"), value);
}
}
- config_read = 1;
+ return 0;
}
/*@@ -145,8 +134,6 @@ int ls_refs(struct repository *r, struct strvec *keys,
memset(&data, 0, sizeof(data));
strvec_init(&data.prefixes);
-
- ensure_config_read();
git_config(ls_refs_config, NULL);
while (packet_reader_read(request) == PACKET_READ_NORMAL) {@@ -179,7 +166,6 @@ int ls_refs(struct repository *r, struct strvec *keys,
int ls_refs_advertise(struct repository *r, struct strbuf *value)
{
if (value) {
- ensure_config_read();
if (advertise_unborn)
strbuf_addstr(value, "unborn");
}diff --git a/ls-refs.h b/ls-refs.h
index a99e4be0bdd..5fcab0d1dca 100644
--- a/ls-refs.h
+++ b/ls-refs.h
@@ -6,6 +6,7 @@ struct strvec;
struct packet_reader;
int ls_refs(struct repository *r, struct strvec *keys,
struct packet_reader *request);
+int ls_refs_startup_config(const char *var, const char *value, void *data);
int ls_refs_advertise(struct repository *r, struct strbuf *value);
#endif /* LS_REFS_H */
diff --git a/serve.c b/serve.c
index 85cd3eab26e..3c7c9329a14 100644
--- a/serve.c
+++ b/serve.c
@@ -33,6 +33,13 @@ static int object_format_advertise(struct repository *r,
return 1;
}
+static int session_id_startup_config(const char *var, const char *value, void *data)
+{
+ if (!strcmp(var, "transfer.advertisesid"))
+ advertise_sid = git_config_bool(var, value);
+ return 0;
+}
+
static int session_id_advertise(struct repository *r, struct strbuf *value)
{
if (!advertise_sid)@@ -54,6 +61,24 @@ struct protocol_capability {
*/
const char *name;
+ /*
+ * A git_config() callback that'll be called only once for the
+ * lifetime of the process, possibly over many different
+ * requests. Used for reading config that's expected to be
+ * static.
+ *
+ * The "command" or "advertise" callbacks themselves are
+ * expected to read config that needs to be more current than
+ * that, or which is dependent on request data.
+ */
+ int (*startup_config)(const char *var, const char *value, void *data);
+
+ /*
+ * A boolean to check if we've called our "startup_config"
+ * callback.
+ */
+ int have_startup_config;
+
/*
* Function queried to see if a capability should be advertised.
* Optionally a value can be specified by adding it to 'value'.@@ -81,6 +106,7 @@ static struct protocol_capability capabilities[] = {
},
{
.name = "ls-refs",
+ .startup_config = ls_refs_startup_config,
.advertise = ls_refs_advertise,
.command = ls_refs,
},@@ -99,6 +125,7 @@ static struct protocol_capability capabilities[] = {
},
{
.name = "session-id",
+ .startup_config = session_id_startup_config,
.advertise = session_id_advertise,
},
{@@ -108,9 +135,20 @@ static struct protocol_capability capabilities[] = {
},
};
+static void read_startup_config(struct protocol_capability *command)
+{
+ if (!command->startup_config)
+ return;
+ if (command->have_startup_config++)
+ return;
+ git_config(command->startup_config, NULL);
+}
+
static int call_advertise(struct protocol_capability *command,
struct repository *r, struct strbuf *value)
{
+ read_startup_config(command);
+
return command->advertise(r, value);
}
@@ -118,6 +156,9 @@ static int call_command(struct protocol_capability *command,
struct repository *r, struct strvec *keys,
struct packet_reader *request)
{
+
+ read_startup_config(command);
+
return command->command(r, keys, request);
}
@@ -318,8 +359,6 @@ static int process_request(void)
/* Main serve loop for protocol version 2 */
void serve(struct serve_options *options)
{
- git_config_get_bool("transfer.advertisesid", &advertise_sid);
-
if (options->advertise_capabilities || !options->stateless_rpc) {
/* serve by default supports v2 */
packet_write_fmt(1, "version 2\n");--
2.32.0.955.ge7c5360f7e7