{"thread":{"id":"20307","subject":"[PATCH 1/3 v3] Add support for external programs for handling native fetches","startedAt":"2009-07-31T05:26:38Z","lastAt":"2009-08-05T20:58:23Z","messageCount":6,"participants":["Daniel Barkalow","Johannes Schindelin","Junio C Hamano"],"isPatch":true,"patchVersion":3,"patchTotal":3},"messages":[{"id":"119211","messageId":"alpine.LNX.2.00.0907310109130.2147@iabervon.org","threadId":"20307","inReplyTo":null,"subject":"[PATCH 1/3 v3] Add support for external programs for handling native fetches","fromName":"Daniel Barkalow","fromEmail":"barkalow@iabervon.org","sentAt":"2009-07-31T05:26:38Z","receivedAt":"2009-07-31T05:26:38Z","isPatch":true,"sender":{"key":"barkalow@iabervon.org","avatar":"https://avatars.githubusercontent.com/u/55364219?v=4"},"body":"transport_get() can call transport_native_helper_init() to have list and\nfetch-ref operations handled by running a separate program as:\n\n git remote-<something> <remote> [<url>]\n\nThis program then accepts, on its stdin, \"list\" and \"fetch <hex>\n<name>\" commands; the former prints out a list of available refs and\neither their hashes or what they are symreefs to, while the latter\nfetches them into the local object database and prints a newline when done.\n\nSigned-off-by: Daniel Barkalow <barkalow@iabervon.org>\n---\ndscho: it turned out that disconnect...() is a method defined to return \nint.\n\n Documentation/git-remote-helpers.txt |   72 +++++++++++++++\n Makefile                             |    1 +\n transport-helper.c                   |  168 ++++++++++++++++++++++++++++++++++\n transport.h                          |    3 +\n 4 files changed, 244 insertions(+), 0 deletions(-)\n create mode 100644 Documentation/git-remote-helpers.txt\n create mode 100644 transport-helper.c\n\ndiff --git a/Documentation/git-remote-helpers.txt b/Documentation/git-remote-helpers.txt\nnew file mode 100644\nindex 0000000..86a9c3f\n--- /dev/null\n+++ b/Documentation/git-remote-helpers.txt\n@@ -0,0 +1,72 @@\n+git-remote-helpers(1)\n+=====================\n+\n+NAME\n+----\n+git-remote-helpers - Helper programs for interoperation with remote git\n+\n+SYNOPSIS\n+--------\n+'git remote-<transport>' <remote>\n+\n+DESCRIPTION\n+-----------\n+\n+These programs are normally not used directly by end users, but are\n+invoked by various git programs that interact with remote repositories\n+when the repository they would operate on will be accessed using\n+transport code not linked into the main git binary. Various particular\n+helper programs will behave as documented here.\n+\n+COMMANDS\n+--------\n+\n+Commands are given by the caller on the helper's standard input, one per line.\n+\n+'capabilities'::\n+\tLists the capabilities of the helper, one per line, ending\n+\twith a blank line.\n+\n+'list'::\n+\tLists the refs, one per line, in the format \"<value> <name>\n+\t[<attr> ...]\". The value may be a hex sha1 hash, \"@<dest>\" for\n+\ta symref, or \"?\" to indicate that the helper could not get the\n+\tvalue of the ref. A space-separated list of attributes follows\n+\tthe name; unrecognized attributes are ignored. After the\n+\tcomplete list, outputs a blank line.\n+\n+'fetch' <sha1> <name>::\n+\tFetches the given object, writing the necessary objects to the\n+\tdatabase. Outputs a blank line when the fetch is\n+\tcomplete. Only objects which were reported in the ref list\n+\twith a sha1 may be fetched this way.\n++\n+Supported if the helper has the \"fetch\" capability.\n+\n+If a fatal error occurs, the program writes the error message to\n+stderr and exits. The caller should expect that a suitable error\n+message has been printed if the child closes the connection without\n+completing a valid response for the current command.\n+\n+Additional commands may be supported, as may be determined from\n+capabilities reported by the helper.\n+\n+CAPABILITIES\n+------------\n+\n+'fetch'::\n+\tThis helper supports the 'fetch' command, with the object\n+\tspecified using a sha1 or ref name as specified.\n+\n+REF LIST ATTRIBUTES\n+-------------------\n+\n+None are defined yet, but the caller must accept any which are supplied.\n+\n+Documentation\n+-------------\n+Documentation by Daniel Barkalow.\n+\n+GIT\n+---\n+Part of the linkgit:git[1] suite\ndiff --git a/Makefile b/Makefile\nindex daf4296..504646a 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -549,6 +549,7 @@ LIB_OBJS += symlinks.o\n LIB_OBJS += tag.o\n LIB_OBJS += trace.o\n LIB_OBJS += transport.o\n+LIB_OBJS += transport-helper.o\n LIB_OBJS += tree-diff.o\n LIB_OBJS += tree.o\n LIB_OBJS += tree-walk.o\ndiff --git a/transport-helper.c b/transport-helper.c\nnew file mode 100644\nindex 0000000..a879bc6\n--- /dev/null\n+++ b/transport-helper.c\n@@ -0,0 +1,168 @@\n+#include \"cache.h\"\n+#include \"transport.h\"\n+\n+#include \"run-command.h\"\n+#include \"commit.h\"\n+#include \"diff.h\"\n+#include \"revision.h\"\n+\n+struct helper_data\n+{\n+\tconst char *name;\n+\tstruct child_process *helper;\n+\tunsigned fetch : 1;\n+};\n+\n+static struct child_process *get_helper(struct transport *transport)\n+{\n+\tstruct helper_data *data = transport->data;\n+\tstruct strbuf buf = STRBUF_INIT;\n+\tstruct child_process *helper;\n+\tFILE *file;\n+\n+\tif (data->helper)\n+\t\treturn data->helper;\n+\n+\thelper = xcalloc(1, sizeof(*helper));\n+\thelper->in = -1;\n+\thelper->out = -1;\n+\thelper->err = 0;\n+\thelper->argv = xcalloc(4, sizeof(*helper->argv));\n+\tstrbuf_addf(&buf, \"remote-%s\", data->name);\n+\thelper->argv[0] = strbuf_detach(&buf, NULL);\n+\thelper->argv[1] = transport->remote->name;\n+\thelper->argv[2] = transport->url;\n+\thelper->git_cmd = 1;\n+\tif (start_command(helper))\n+\t\tdie(\"Unable to run helper: git %s\", helper->argv[0]);\n+\tdata->helper = helper;\n+\n+\twrite_in_full(data->helper->in, \"capabilities\\n\", 13);\n+\tfile = xfdopen(helper->out, \"r\");\n+\twhile (1) {\n+\t\tif (strbuf_getline(&buf, file, '\\n') == EOF)\n+\t\t\texit(128); /* child died, message supplied already */\n+\n+\t\tif (!*buf.buf)\n+\t\t\tbreak;\n+\t\tif (!strcmp(buf.buf, \"fetch\"))\n+\t\t\tdata->fetch = 1;\n+\t}\n+\treturn data->helper;\n+}\n+\n+static int disconnect_helper(struct transport *transport)\n+{\n+\tstruct helper_data *data = transport->data;\n+\tif (data->helper) {\n+\t\twrite_in_full(data->helper->in, \"\\n\", 1);\n+\t\tclose(data->helper->in);\n+\t\tfinish_command(data->helper);\n+\t\tfree((char *)data->helper->argv[0]);\n+\t\tfree(data->helper->argv);\n+\t\tfree(data->helper);\n+\t\tdata->helper = NULL;\n+\t}\n+\treturn 0;\n+}\n+\n+static int fetch(struct transport *transport,\n+\t\t int nr_heads, const struct ref **to_fetch)\n+{\n+\tstruct helper_data *data = transport->data;\n+\tstruct child_process *helper;\n+\tconst struct ref *posn;\n+\tstruct strbuf buf = STRBUF_INIT;\n+\tint i, count;\n+\tFILE *file;\n+\n+\tcount = 0;\n+\tfor (i = 0; i < nr_heads; i++) {\n+\t\tposn = to_fetch[i];\n+\t\tif (posn->status & REF_STATUS_UPTODATE)\n+\t\t\tcontinue;\n+\t\tcount++;\n+\t}\n+\n+\tif (!count)\n+\t\treturn 0;\n+\n+\thelper = get_helper(transport);\n+\n+\tif (!data->fetch)\n+\t\treturn -1;\n+\n+\tfile = xfdopen(helper->out, \"r\");\n+\tfor (i = 0; i < nr_heads; i++) {\n+\t\tposn = to_fetch[i];\n+\t\tif (posn->status & REF_STATUS_UPTODATE)\n+\t\t\tcontinue;\n+\t\twrite_in_full(helper->in, \"fetch \", 6);\n+\t\twrite_in_full(helper->in, sha1_to_hex(posn->old_sha1), 40);\n+\t\twrite_in_full(helper->in, \" \", 1);\n+\t\twrite_in_full(helper->in, posn->name, strlen(posn->name));\n+\t\twrite_in_full(helper->in, \"\\n\", 1);\n+\t\tif (strbuf_getline(&buf, file, '\\n') == EOF)\n+\t\t\texit(128); /* child died, message supplied already */\n+\t}\n+\treturn 0;\n+}\n+\n+static struct ref *get_refs_list(struct transport *transport, int for_push)\n+{\n+\tstruct child_process *helper;\n+\tstruct ref *ret = NULL;\n+\tstruct ref **tail = &ret;\n+\tstruct ref *posn;\n+\tstruct strbuf buf = STRBUF_INIT;\n+\tFILE *file;\n+\n+\thelper = get_helper(transport);\n+\twrite_in_full(helper->in, \"list\\n\", 5);\n+\n+\tfile = xfdopen(helper->out, \"r\");\n+\twhile (1) {\n+\t\tchar *eov, *eon;\n+\t\tif (strbuf_getline(&buf, file, '\\n') == EOF)\n+\t\t\texit(128); /* child died, message supplied already */\n+\n+\t\tif (!*buf.buf)\n+\t\t\tbreak;\n+\n+\t\teov = strchr(buf.buf, ' ');\n+\t\tif (!eov)\n+\t\t\tdie(\"Malformed response in ref list: %s\", buf.buf);\n+                eon = strchr(eov + 1, ' ');\n+\t\t*eov = '\\0';\n+                if (eon)\n+                        *eon = '\\0';\n+\t\t*tail = alloc_ref(eov + 1);\n+\t\tif (buf.buf[0] == '@')\n+\t\t\t(*tail)->symref = xstrdup(buf.buf + 1);\n+\t\telse if (buf.buf[0] != '?')\n+\t\t\tget_sha1_hex(buf.buf, (*tail)->old_sha1);\n+\t\ttail = &((*tail)->next);\n+\t\tstrbuf_reset(&buf);\n+\t}\n+\tstrbuf_release(&buf);\n+\n+\tfor (posn = ret; posn; posn = posn->next)\n+\t\tresolve_remote_symref(posn, ret);\n+\n+\treturn ret;\n+}\n+\n+int transport_native_helper_init(struct transport *transport)\n+{\n+\tstruct helper_data *data = xmalloc(sizeof(*data));\n+\tchar *eom = strchr(transport->url, ':');\n+\tif (!eom)\n+\t\treturn -1;\n+\tdata->helper = NULL;\n+\tdata->name = xstrndup(transport->url, eom - transport->url);\n+\ttransport->data = data;\n+\ttransport->get_refs_list = get_refs_list;\n+\ttransport->fetch = fetch;\n+\ttransport->disconnect = disconnect_helper;\n+\treturn 0;\n+}\ndiff --git a/transport.h b/transport.h\nindex 51b5397..fff9d8c 100644\n--- a/transport.h\n+++ b/transport.h\n@@ -77,4 +77,7 @@ void transport_unlock_pack(struct transport *transport);\n int transport_disconnect(struct transport *transport);\n char *transport_anonymize_url(const char *url);\n \n+/* Transport methods defined outside transport.c */\n+int transport_native_helper_init(struct transport *transport);\n+\n #endif\n-- \n1.6.4.rc3.25.gd5eff.dirty\n"},{"id":"119602","messageId":"alpine.DEB.1.00.0908051143000.8306@pacific.mpi-cbg.de","threadId":"20307","inReplyTo":"alpine.LNX.2.00.0907310109130.2147@iabervon.org","subject":"Re: [PATCH 1/3 v3] Add support for external programs for handling native fetches","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2009-08-05T10:01:05Z","receivedAt":"2009-08-05T10:01:05Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Fri, 31 Jul 2009, Daniel Barkalow wrote:\n\n> dscho: it turned out that disconnect...() is a method defined to return \n> int.\n\nOkay, thanks for the clarification.\n\n> +static int fetch(struct transport *transport,\n> +\t\t int nr_heads, const struct ref **to_fetch)\n> +{\n> +\tstruct helper_data *data = transport->data;\n> +\tstruct child_process *helper;\n> +\tconst struct ref *posn;\n> +\tstruct strbuf buf = STRBUF_INIT;\n> +\tint i, count;\n> +\tFILE *file;\n> +\n> +\tcount = 0;\n> +\tfor (i = 0; i < nr_heads; i++) {\n> +\t\tposn = to_fetch[i];\n> +\t\tif (posn->status & REF_STATUS_UPTODATE)\n> +\t\t\tcontinue;\n> +\t\tcount++;\n> +\t}\n\nI still do not like it, but I guess you refuse to please me here.\n\n> +\n> +\tif (!count)\n> +\t\treturn 0;\n> +\n> +\thelper = get_helper(transport);\n> +\n> +\tif (!data->fetch)\n> +\t\treturn -1;\n> +\n> +\tfile = xfdopen(helper->out, \"r\");\n> +\tfor (i = 0; i < nr_heads; i++) {\n> +\t\tposn = to_fetch[i];\n> +\t\tif (posn->status & REF_STATUS_UPTODATE)\n> +\t\t\tcontinue;\n> +\t\twrite_in_full(helper->in, \"fetch \", 6);\n> +\t\twrite_in_full(helper->in, sha1_to_hex(posn->old_sha1), 40);\n> +\t\twrite_in_full(helper->in, \" \", 1);\n> +\t\twrite_in_full(helper->in, posn->name, strlen(posn->name));\n> +\t\twrite_in_full(helper->in, \"\\n\", 1);\n\nHow about\n\n\t\tstrbuf_addf(&buf, \"fetch %s %s\\n\", \n\t\t\tsha1_to_hex(posn->old_sha1), posn->name);\n\t\twrite_in_full(helper->in, buf.buf, buf.len);\n\ninstead?  It is not only much more readable, but also less error-prone.\n\n> +static struct ref *get_refs_list(struct transport *transport, int for_push)\n> +{\n> +\tstruct child_process *helper;\n> +\tstruct ref *ret = NULL;\n> +\tstruct ref **tail = &ret;\n> +\tstruct ref *posn;\n> +\tstruct strbuf buf = STRBUF_INIT;\n> +\tFILE *file;\n> +\n> +\thelper = get_helper(transport);\n> +\twrite_in_full(helper->in, \"list\\n\", 5);\n\nSpeaking of error-prone: we introduced e.g. prefixcmp() for the sole \npurpose of avoiding errors due to hard-coded constants.  I would strongly \nsuggest to introduce a helper here instead of having all those constants \nthat every reviewer has to check (which is no fun).\n\n> +\t\tif (strbuf_getline(&buf, file, '\\n') == EOF)\n> +\t\t\texit(128); /* child died, message supplied already */\n> +\n> +\t\tif (!*buf.buf)\n> +\t\t\tbreak;\n> +\n> +\t\teov = strchr(buf.buf, ' ');\n> +\t\tif (!eov)\n> +\t\t\tdie(\"Malformed response in ref list: %s\", buf.buf);\n> +                eon = strchr(eov + 1, ' ');\n> +\t\t*eov = '\\0';\n> +                if (eon)\n\nFunny indentation?\n\n> +                        *eon = '\\0';\n\nPlease register a complaint about your naming (\"posn\", \"eov\", \"eon\"), and \nalso please register a complaint about the rather confusing order of \nyour statements.\n\n> +\t\t*tail = alloc_ref(eov + 1);\n> +\t\tif (buf.buf[0] == '@')\n> +\t\t\t(*tail)->symref = xstrdup(buf.buf + 1);\n> +\t\telse if (buf.buf[0] != '?')\n> +\t\t\tget_sha1_hex(buf.buf, (*tail)->old_sha1);\n> +\t\ttail = &((*tail)->next);\n> +\t\tstrbuf_reset(&buf);\n\nFor clarity's sake, this should be done _before_ the strbuf is filled, not \nafter it (because then everybody has to think harder why the code is still \ncorrect, but the performance is _exactly_ the same).\n\n> +\t}\n> +\tstrbuf_release(&buf);\n> +\n> +\tfor (posn = ret; posn; posn = posn->next)\n> +\t\tresolve_remote_symref(posn, ret);\n> +\n> +\treturn ret;\n> +}\n> +\n> +int transport_native_helper_init(struct transport *transport)\n> +{\n> +\tstruct helper_data *data = xmalloc(sizeof(*data));\n> +\tchar *eom = strchr(transport->url, ':');\n\n\"End of message\"?\n\nAll in all, I like this patch much better, thank you!\n\nCiao,\nDscho\n"},{"id":"119624","messageId":"alpine.LNX.2.00.0908051058130.2147@iabervon.org","threadId":"20307","inReplyTo":"alpine.DEB.1.00.0908051143000.8306@pacific.mpi-cbg.de","subject":"Re: [PATCH 1/3 v3] Add support for external programs for handling native fetches","fromName":"Daniel Barkalow","fromEmail":"barkalow@iabervon.org","sentAt":"2009-08-05T15:34:49Z","receivedAt":"2009-08-05T15:34:49Z","isPatch":true,"sender":{"key":"barkalow@iabervon.org","avatar":"https://avatars.githubusercontent.com/u/55364219?v=4"},"body":"On Wed, 5 Aug 2009, Johannes Schindelin wrote:\n\n> Hi,\n> \n> On Fri, 31 Jul 2009, Daniel Barkalow wrote:\n> \n> > dscho: it turned out that disconnect...() is a method defined to return \n> > int.\n> \n> Okay, thanks for the clarification.\n> \n> > +static int fetch(struct transport *transport,\n> > +\t\t int nr_heads, const struct ref **to_fetch)\n> > +{\n> > +\tstruct helper_data *data = transport->data;\n> > +\tstruct child_process *helper;\n> > +\tconst struct ref *posn;\n> > +\tstruct strbuf buf = STRBUF_INIT;\n> > +\tint i, count;\n> > +\tFILE *file;\n> > +\n> > +\tcount = 0;\n> > +\tfor (i = 0; i < nr_heads; i++) {\n> > +\t\tposn = to_fetch[i];\n> > +\t\tif (posn->status & REF_STATUS_UPTODATE)\n> > +\t\t\tcontinue;\n> > +\t\tcount++;\n> > +\t}\n> \n> I still do not like it, but I guess you refuse to please me here.\n\nI actually ended up rewriting it the way you wanted, because I no longer \nneeded the numeric value of count to match the iterations of another loop. \nAnd your verision is the clearer way of determining if there are any \nnot-up-to-date refs.\n\n> > +\n> > +\tif (!count)\n> > +\t\treturn 0;\n> > +\n> > +\thelper = get_helper(transport);\n> > +\n> > +\tif (!data->fetch)\n> > +\t\treturn -1;\n> > +\n> > +\tfile = xfdopen(helper->out, \"r\");\n> > +\tfor (i = 0; i < nr_heads; i++) {\n> > +\t\tposn = to_fetch[i];\n> > +\t\tif (posn->status & REF_STATUS_UPTODATE)\n> > +\t\t\tcontinue;\n> > +\t\twrite_in_full(helper->in, \"fetch \", 6);\n> > +\t\twrite_in_full(helper->in, sha1_to_hex(posn->old_sha1), 40);\n> > +\t\twrite_in_full(helper->in, \" \", 1);\n> > +\t\twrite_in_full(helper->in, posn->name, strlen(posn->name));\n> > +\t\twrite_in_full(helper->in, \"\\n\", 1);\n> \n> How about\n> \n> \t\tstrbuf_addf(&buf, \"fetch %s %s\\n\", \n> \t\t\tsha1_to_hex(posn->old_sha1), posn->name);\n> \t\twrite_in_full(helper->in, buf.buf, buf.len);\n> \n> instead?  It is not only much more readable, but also less error-prone.\n\nGood point. Although I am likely to forget the strbuf_reset(&buf) the \nfirst time.\n\n> > +static struct ref *get_refs_list(struct transport *transport, int for_push)\n> > +{\n> > +\tstruct child_process *helper;\n> > +\tstruct ref *ret = NULL;\n> > +\tstruct ref **tail = &ret;\n> > +\tstruct ref *posn;\n> > +\tstruct strbuf buf = STRBUF_INIT;\n> > +\tFILE *file;\n> > +\n> > +\thelper = get_helper(transport);\n> > +\twrite_in_full(helper->in, \"list\\n\", 5);\n> \n> Speaking of error-prone: we introduced e.g. prefixcmp() for the sole \n> purpose of avoiding errors due to hard-coded constants.  I would strongly \n> suggest to introduce a helper here instead of having all those constants \n> that every reviewer has to check (which is no fun).\n\nI think using strbuf like you suggest above is good for everywhere. Sure, \nit might be overkill for a command with no arguments, but having all of \nthe places that write to the helper look the same is good, and it avoids \nthe constant. Maybe strbuf could get a function to write a strbuf to an fd \nand reset the strbuf. I'll look into that.\n\n> > +\t\tif (strbuf_getline(&buf, file, '\\n') == EOF)\n> > +\t\t\texit(128); /* child died, message supplied already */\n> > +\n> > +\t\tif (!*buf.buf)\n> > +\t\t\tbreak;\n> > +\n> > +\t\teov = strchr(buf.buf, ' ');\n> > +\t\tif (!eov)\n> > +\t\t\tdie(\"Malformed response in ref list: %s\", buf.buf);\n> > +                eon = strchr(eov + 1, ' ');\n> > +\t\t*eov = '\\0';\n> > +                if (eon)\n> \n> Funny indentation?\n\nWow, weird. No idea why that happened, although it's a lot less obvious \nbefore it's got 5 characters in front.\n\n> > +                        *eon = '\\0';\n> \n> Please register a complaint about your naming (\"posn\", \"eov\", \"eon\"), and \n> also please register a complaint about the rather confusing order of \n> your statements.\n\nI think the order of statements is improved in the latest version. Is \nthere a preferred style for things like my \"eov\" and \"eon\"? The \nLinus-original code I'm finding just uses \"p\", which is hardly more \nhelpful, and I think that was just written in a hurry. You'd prefer \"ref\" \ninstead of \"posn\", I assume? I don't think it's meaningfully clearer on \nits own, but I agree that it matches everything better, and that's a \nworthwhile thing.\n\n> > +\t\t*tail = alloc_ref(eov + 1);\n> > +\t\tif (buf.buf[0] == '@')\n> > +\t\t\t(*tail)->symref = xstrdup(buf.buf + 1);\n> > +\t\telse if (buf.buf[0] != '?')\n> > +\t\t\tget_sha1_hex(buf.buf, (*tail)->old_sha1);\n> > +\t\ttail = &((*tail)->next);\n> > +\t\tstrbuf_reset(&buf);\n> \n> For clarity's sake, this should be done _before_ the strbuf is filled, not \n> after it (because then everybody has to think harder why the code is still \n> correct, but the performance is _exactly_ the same).\n\nActually, it is done before the strbuf is filled, because strbuf_getline() \nis clever and does it for me. In the latest version, the strbuf_reset() \nhere is dropped.\n\n> > +\t}\n> > +\tstrbuf_release(&buf);\n> > +\n> > +\tfor (posn = ret; posn; posn = posn->next)\n> > +\t\tresolve_remote_symref(posn, ret);\n> > +\n> > +\treturn ret;\n> > +}\n> > +\n> > +int transport_native_helper_init(struct transport *transport)\n> > +{\n> > +\tstruct helper_data *data = xmalloc(sizeof(*data));\n> > +\tchar *eom = strchr(transport->url, ':');\n> \n> \"End of message\"?\n\n\"End of method\"; that's the \"method\" part of a URL.\n\n> All in all, I like this patch much better, thank you!\n\nGreat; I think the version from last night also fixes some but not all of \nyour current complaints.\n\n\t-Daniel\n*This .sig left intentionally blank*\n"},{"id":"119679","messageId":"alpine.DEB.1.00.0908052231461.8306@pacific.mpi-cbg.de","threadId":"20307","inReplyTo":"alpine.LNX.2.00.0908051058130.2147@iabervon.org","subject":"Re: [PATCH 1/3 v3] Add support for external programs for handling native fetches","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2009-08-05T20:34:26Z","receivedAt":"2009-08-05T20:34:26Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Wed, 5 Aug 2009, Daniel Barkalow wrote:\n\n> On Wed, 5 Aug 2009, Johannes Schindelin wrote:\n> \n> > On Fri, 31 Jul 2009, Daniel Barkalow wrote:\n> > \n> > > +\t}\n> > > +\tstrbuf_release(&buf);\n> > > +\n> > > +\tfor (posn = ret; posn; posn = posn->next)\n> > > +\t\tresolve_remote_symref(posn, ret);\n> > > +\n> > > +\treturn ret;\n> > > +}\n> > > +\n> > > +int transport_native_helper_init(struct transport *transport)\n> > > +{\n> > > +\tstruct helper_data *data = xmalloc(sizeof(*data));\n> > > +\tchar *eom = strchr(transport->url, ':');\n> > \n> > \"End of message\"?\n> \n> \"End of method\"; that's the \"method\" part of a URL.\n\nI'd have called that \"protocol\".  At least that's what java.net.URL \ncalls it, and I just assume that Sun is very much in love with standards, \nso I could imagine they picked that term from the appropriate RFC.\n\nIn any case, I am much less likely to puzzle over \"p\" than \"eom\"...\n\nCiao,\nDscho\n"},{"id":"119682","messageId":"7v4osm0z6x.fsf@alter.siamese.dyndns.org","threadId":"20307","inReplyTo":"alpine.DEB.1.00.0908052231461.8306@pacific.mpi-cbg.de","subject":"Re: [PATCH 1/3 v3] Add support for external programs for handling native fetches","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2009-08-05T20:43:02Z","receivedAt":"2009-08-05T20:43:02Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:\n\n>> > > +int transport_native_helper_init(struct transport *transport)\n>> > > +{\n>> > > +\tstruct helper_data *data = xmalloc(sizeof(*data));\n>> > > +\tchar *eom = strchr(transport->url, ':');\n>> > \n>> > \"End of message\"?\n>> \n>> \"End of method\"; that's the \"method\" part of a URL.\n>\n> I'd have called that \"protocol\".  At least that's what java.net.URL \n> calls it, and I just assume that Sun is very much in love with standards, \n> so I could imagine they picked that term from the appropriate RFC.\n\nIn RFC parlance that's called <scheme>.\n"},{"id":"119690","messageId":"alpine.LNX.2.00.0908051648580.2147@iabervon.org","threadId":"20307","inReplyTo":"alpine.DEB.1.00.0908052231461.8306@pacific.mpi-cbg.de","subject":"Re: [PATCH 1/3 v3] Add support for external programs for handling native fetches","fromName":"Daniel Barkalow","fromEmail":"barkalow@iabervon.org","sentAt":"2009-08-05T20:58:23Z","receivedAt":"2009-08-05T20:58:23Z","isPatch":true,"sender":{"key":"barkalow@iabervon.org","avatar":"https://avatars.githubusercontent.com/u/55364219?v=4"},"body":"On Wed, 5 Aug 2009, Johannes Schindelin wrote:\n\n> Hi,\n> \n> On Wed, 5 Aug 2009, Daniel Barkalow wrote:\n> \n> > On Wed, 5 Aug 2009, Johannes Schindelin wrote:\n> > \n> > > On Fri, 31 Jul 2009, Daniel Barkalow wrote:\n> > > \n> > > > +\t}\n> > > > +\tstrbuf_release(&buf);\n> > > > +\n> > > > +\tfor (posn = ret; posn; posn = posn->next)\n> > > > +\t\tresolve_remote_symref(posn, ret);\n> > > > +\n> > > > +\treturn ret;\n> > > > +}\n> > > > +\n> > > > +int transport_native_helper_init(struct transport *transport)\n> > > > +{\n> > > > +\tstruct helper_data *data = xmalloc(sizeof(*data));\n> > > > +\tchar *eom = strchr(transport->url, ':');\n> > > \n> > > \"End of message\"?\n> > \n> > \"End of method\"; that's the \"method\" part of a URL.\n> \n> I'd have called that \"protocol\".  At least that's what java.net.URL \n> calls it, and I just assume that Sun is very much in love with standards, \n> so I could imagine they picked that term from the appropriate RFC.\n\nActually, it turns out to be officially \"scheme\" (although commonly called \n\"protocol\"). I'll just call the variable \"colon\" and avoid the whole \nissue, since it's not trying to really manage official URLs.\n\n\t-Daniel\n*This .sig left intentionally blank*\n"}]}