{"thread":{"id":"6709","subject":"[PATCH] Add utility functions for enumerating remotes.","startedAt":"2007-02-06T07:25:14Z","lastAt":"2007-02-06T07:25:14Z","messageCount":1,"participants":["Jeff King"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"33695","messageId":"20070206072513.GA29895@coredump.intra.peff.net","threadId":"6709","inReplyTo":null,"subject":"[PATCH] Add utility functions for enumerating remotes.","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2007-02-06T07:25:14Z","receivedAt":"2007-02-06T07:25:14Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"This creates remotes.[ch], which implement for_each_remote, a function\nfor enumerating all remotes.\n\nSigned-off-by: Jeff King <peff@peff.net>\n---\nI wrote this to play with Carl's \"look for branches under refs/remotes/\"\nidea. Since these functions have no users, I don't know if it's worth\napplying this patch. However, I thought I would publish it, at least,\nsince it may eventually become useful.\n\n Makefile  |    3 +-\n remotes.c |   71 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n remotes.h |    6 +++++\n 3 files changed, 79 insertions(+), 1 deletions(-)\n create mode 100644 remotes.c\n create mode 100644 remotes.h\n\ndiff --git a/Makefile b/Makefile\nindex de89d8a..aca96c8 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -261,7 +261,8 @@ LIB_OBJS = \\\n \trevision.o pager.o tree-walk.o xdiff-interface.o \\\n \twrite_or_die.o trace.o list-objects.o grep.o \\\n \talloc.o merge-file.o path-list.o help.o unpack-trees.o $(DIFF_OBJS) \\\n-\tcolor.o wt-status.o archive-zip.o archive-tar.o shallow.o utf8.o\n+\tcolor.o wt-status.o archive-zip.o archive-tar.o shallow.o utf8.o \\\n+\tremotes.o\n \n BUILTIN_OBJS = \\\n \tbuiltin-add.o \\\ndiff --git a/remotes.c b/remotes.c\nnew file mode 100644\nindex 0000000..1963753\n--- /dev/null\n+++ b/remotes.c\n@@ -0,0 +1,71 @@\n+#include \"remotes.h\"\n+#include \"cache.h\"\n+\n+/* We can't be reentrant here, because git_config doesn't allow\n+ * passing callback data. */\n+static each_remote_fn *config_fn;\n+static void *config_cb_data;\n+static int config_ret;\n+static int find_remote_in_config(const char *k, const char *v)\n+{\n+\tconst char *dot;\n+\tchar remote[1024];\n+\n+\tif (config_ret < 0)\n+\t\treturn 0;\n+\n+\tif (strncmp(k, \"remote.\", 7))\n+\t\treturn 0;\n+\tk += 7;\n+\tdot = strchr(k, '.');\n+\tif (!dot)\n+\t\treturn 0;\n+\tif (strcmp(dot + 1, \"url\"))\n+\t\treturn 0;\n+\n+\tmemcpy(remote, k, dot - k);\n+\tremote[dot - k] = '\\0';\n+\n+\tconfig_ret = config_fn(remote, config_cb_data);\n+\treturn 0;\n+}\n+\n+static int do_for_each_remotes(each_remote_fn fn, void *cb_data)\n+{\n+\tconst char *remotes;\n+        DIR *dir;\n+\tstruct dirent *de;\n+\tint ret;\n+\n+\tremotes = git_path(\"remotes\");\n+\tdir = opendir(remotes);\n+\tif (!dir) {\n+\t\tif (errno == ENOENT)\n+\t\t\treturn 0;\n+\t\tdie(\"unable to open %s: %s\", remotes, strerror(errno));\n+\t}\n+\n+\tret = 0;\n+\twhile ((de = readdir(dir)) != NULL) {\n+\t\tif (de->d_name[0] == '.')\n+\t\t\tcontinue;\n+\t\tret = fn(de->d_name, cb_data);\n+\t\tif (ret < 0)\n+\t\t\tbreak;\n+\t}\n+\n+\tclosedir(dir);\n+\treturn ret;\n+}\n+\n+int for_each_remote(each_remote_fn fn, void *cb_data)\n+{\n+\tconfig_fn = fn;\n+\tconfig_cb_data = cb_data;\n+\tconfig_ret = 0;\n+\tgit_config(find_remote_in_config);\n+\tif (config_ret < 0)\n+\t\treturn config_ret;\n+\n+\treturn do_for_each_remotes(fn, cb_data);\n+}\ndiff --git a/remotes.h b/remotes.h\nnew file mode 100644\nindex 0000000..632a449\n--- /dev/null\n+++ b/remotes.h\n@@ -0,0 +1,6 @@\n+#ifndef REMOTES_H\n+\n+typedef int each_remote_fn(const char *remote, void *cb_data);\n+int for_each_remote(each_remote_fn fn, void *cb_data);\n+\n+#endif /* REMOTES_H */\n-- \n1.5.0.rc3.554.ga40e-dirty\n"}]}