@@ -915,6 +915,8 @@ LIB_OBJS += notes-cache.o
LIB_OBJS += notes-merge.o
LIB_OBJS += notes-utils.o
LIB_OBJS += object.o
+LIB_OBJS += odb-helper.o
+LIB_OBJS += remote-odb.o
LIB_OBJS += oidmap.o
LIB_OBJS += oidset.o
LIB_OBJS += packfile.o
new file mode 100644
@@ -0,0 +1,16 @@
+#include "cache.h"
+#include "object.h"
+#include "argv-array.h"
+#include "odb-helper.h"
+#include "run-command.h"
+#include "sha1-lookup.h"
+
+struct odb_helper *odb_helper_new(const char *name, int namelen)
+{
+ struct odb_helper *o;
+
+ o = xcalloc(1, sizeof(*o));
+ o->name = xmemdupz(name, namelen);
+
+ return o;
+}
new file mode 100644
@@ -0,0 +1,19 @@
+#ifndef ODB_HELPER_H
+#define ODB_HELPER_H
+
+/*
+ * An odb helper is a way to access a remote odb.
+ *
+ * Information in its fields comes from the config file [odb "NAME"]
+ * entries.
+ */
+struct odb_helper {
+ const char *name; /* odb.<NAME>.* */
+ const char *remote; /* odb.<NAME>.promisorRemote */
+
+ struct odb_helper *next;
+};
+
+extern struct odb_helper *odb_helper_new(const char *name, int namelen);
+
+#endif /* ODB_HELPER_H */
new file mode 100644
@@ -0,0 +1,91 @@
+#include "cache.h"
+#include "remote-odb.h"
+#include "odb-helper.h"
+#include "config.h"
+
+static struct odb_helper *helpers;
+static struct odb_helper **helpers_tail = &helpers;
+
+static struct odb_helper *find_or_create_helper(const char *name, int len)
+{
+ struct odb_helper *o;
+
+ for (o = helpers; o; o = o->next)
+ if (!strncmp(o->name, name, len) && !o->name[len])
+ return o;
+
+ o = odb_helper_new(name, len);
+ *helpers_tail = o;
+ helpers_tail = &o->next;
+
+ return o;
+}
+
+static struct odb_helper *do_find_odb_helper(const char *remote)
+{
+ struct odb_helper *o;
+
+ for (o = helpers; o; o = o->next)
+ if (o->remote && !strcmp(o->remote, remote))
+ return o;
+
+ return NULL;
+}
+
+static int remote_odb_config(const char *var, const char *value, void *data)
+{
+ struct odb_helper *o;
+ const char *name;
+ int namelen;
+ const char *subkey;
+
+ if (parse_config_key(var, "odb", &name, &namelen, &subkey) < 0)
+ return 0;
+
+ o = find_or_create_helper(name, namelen);
+
+ if (!strcmp(subkey, "promisorremote")) {
+ const char *remote;
+ int res = git_config_string(&remote, var, value);
+
+ if (res)
+ return res;
+
+ if (do_find_odb_helper(remote))
+ return error(_("when parsing config key '%s' "
+ "helper for remote '%s' already exists"),
+ var, remote);
+
+ o->remote = remote;
+
+ return 0;
+ }
+
+ return 0;
+}
+
+static void remote_odb_init(void)
+{
+ static int initialized;
+
+ if (initialized)
+ return;
+ initialized = 1;
+
+ git_config(remote_odb_config, NULL);
+}
+
+struct odb_helper *find_odb_helper(const char *remote)
+{
+ remote_odb_init();
+
+ if (!remote)
+ return helpers;
+
+ return do_find_odb_helper(remote);
+}
+
+int has_remote_odb(void)
+{
+ return !!find_odb_helper(NULL);
+}
new file mode 100644
@@ -0,0 +1,7 @@
+#ifndef REMOTE_ODB_H
+#define REMOTE_ODB_H
+
+extern struct odb_helper *find_odb_helper(const char *remote);
+extern int has_remote_odb(void);
+
+#endif /* REMOTE_ODB_H */