{"thread":{"id":"17095","subject":"[RFC PATCH 3/3] Support fetching from foreign VCSes","startedAt":"2009-01-11T20:12:10Z","lastAt":"2009-02-01T02:35:42Z","messageCount":9,"participants":["Daniel Barkalow","Junio C Hamano","Shawn O. Pearce","Johannes Schindelin","Johan Herland"],"isPatch":true,"patchVersion":1,"patchTotal":3},"messages":[{"id":"99993","messageId":"alpine.LNX.1.00.0901110335520.19665@iabervon.org","threadId":"17095","inReplyTo":null,"subject":"[RFC PATCH 3/3] Support fetching from foreign VCSes","fromName":"Daniel Barkalow","fromEmail":"barkalow@iabervon.org","sentAt":"2009-01-11T20:12:10Z","receivedAt":"2009-01-11T20:12:10Z","isPatch":true,"sender":{"key":"barkalow@iabervon.org","avatar":"https://avatars.githubusercontent.com/u/55364219?v=4"},"body":"This supports a useful subset of the usual fetch logic, mostly in the\nconfig file.\n\nSigned-off-by: Daniel Barkalow <barkalow@iabervon.org>\n---\n builtin-fetch.c |  135 +++++++++++++++++++++++++++++++++++++++++++++++++++++-\n 1 files changed, 132 insertions(+), 3 deletions(-)\n\ndiff --git a/builtin-fetch.c b/builtin-fetch.c\nindex 7b46f8f..14e037e 100644\n--- a/builtin-fetch.c\n+++ b/builtin-fetch.c\n@@ -614,6 +614,136 @@ static void set_option(const char *name, const char *value)\n \t\t\tname, transport->url);\n }\n \n+static struct ref *list_foreign(struct remote *remote)\n+{\n+\tstruct child_process importer;\n+\tstruct ref *ret = NULL;\n+\tstruct ref **end = &ret;\n+\tstruct strbuf buf;\n+\tmemset(&importer, 0, sizeof(importer));\n+\timporter.in = 0;\n+\timporter.no_stdin = 1;\n+\timporter.out = -1;\n+\timporter.err = 0;\n+\timporter.argv = xcalloc(5, sizeof(*importer.argv));\n+\tstrbuf_init(&buf, 80);\n+\tstrbuf_addf(&buf, \"vcs-%s\", remote->foreign_vcs);\n+\timporter.argv[0] = buf.buf;\n+\timporter.argv[1] = \"list\";\n+\timporter.argv[2] = remote->name;\n+\timporter.git_cmd = 1;\n+\tstart_command(&importer);\n+\n+\tstrbuf_reset(&buf);\n+\twhile (1) {\n+\t\tchar *eol, *eon;\n+\t\tif (strbuf_read(&buf, importer.out, 80) <= 0)\n+\t\t\tbreak;\n+\t\twhile (1) {\n+\t\t\teol = strchr(buf.buf, '\\n');\n+\t\t\tif (!eol)\n+\t\t\t\tbreak;\n+\t\t\t*eol = '\\0';\n+\t\t\teon = strchr(buf.buf, ' ');\n+\t\t\tif (eon)\n+\t\t\t\t*eon = '\\0';\n+\t\t\t*end = alloc_ref(buf.buf);\n+\t\t\tend = &((*end)->next);\n+\t\t\tstrbuf_remove(&buf, 0, eol - buf.buf + 1);\n+\t\t}\n+\t}\n+\n+\tfinish_command(&importer);\n+\tstrbuf_release(&buf);\n+\treturn ret;\n+}\n+\n+static int import_foreign(struct remote *remote, struct ref *refs)\n+{\n+\tstruct child_process importer;\n+\tstruct child_process fastimport;\n+\tstruct ref *posn;\n+\tint count = 0;\n+\tstruct strbuf buf;\n+\n+\tfor (posn = refs; posn; posn = posn->next)\n+\t\tcount++;\n+\n+\tmemset(&importer, 0, sizeof(importer));\n+\timporter.in = 0;\n+\timporter.no_stdin = 1;\n+\timporter.out = -1;\n+\timporter.err = 0;\n+\timporter.argv = xcalloc(5 + count, sizeof(*importer.argv));\n+\tstrbuf_init(&buf, 80);\n+\tstrbuf_addf(&buf, \"vcs-%s\", remote->foreign_vcs);\n+\timporter.argv[0] = buf.buf;\n+\timporter.argv[1] = \"import\";\n+\timporter.argv[2] = remote->name;\n+\tcount = 0;\n+\tfor (posn = refs; posn; posn = posn->next) {\n+\t\timporter.argv[3 + count] = posn->name;\n+\t\tcount++;\n+\t}\n+\timporter.git_cmd = 1;\n+\tstart_command(&importer);\n+\n+\tmemset(&fastimport, 0, sizeof(fastimport));\n+\tfastimport.in = importer.out;\n+\tfastimport.argv = xcalloc(2, sizeof(*fastimport.argv));\n+\tfastimport.argv[0] = \"fast-import\";\n+\tfastimport.argv[1] = \"--quiet\";\n+\tfastimport.git_cmd = 1;\n+\tstart_command(&fastimport);\n+\n+\tfinish_command(&importer);\n+\tfinish_command(&fastimport);\n+\tstrbuf_release(&buf);\n+\treturn 0;\n+}\n+\n+static int fetch_foreign(struct remote *remote)\n+{\n+\tstruct ref *remote_refs = list_foreign(remote);\n+\tstruct ref *ref_map = NULL;\n+\tstruct ref *rm;\n+\tstruct ref **tail = &ref_map;\n+\tstruct branch *branch;\n+\tint i;\n+\n+\tint exit_code = import_foreign(remote, remote_refs);\n+\tif (exit_code)\n+\t\treturn exit_code;\n+\n+\t/* if not appending, truncate FETCH_HEAD */\n+\tif (!append) {\n+\t\tchar *filename = git_path(\"FETCH_HEAD\");\n+\t\tFILE *fp = fopen(filename, \"w\");\n+\t\tif (!fp)\n+\t\t\treturn error(\"cannot open %s: %s\\n\", filename, strerror(errno));\n+\t\tfclose(fp);\n+\t}\n+\n+\tfor (rm = remote_refs; rm; rm = rm->next)\n+\t\tread_ref(rm->name, rm->old_sha1);\n+\n+\tbranch = branch_get(NULL);\n+\n+\tfor (i = 0; i < remote->fetch_refspec_nr; i++) {\n+\t\tget_fetch_map(remote_refs, &remote->fetch[i], &tail, 0);\n+\t\tif (!strcmp(branch->remote_name, remote->name))\n+\t\t\tadd_merge_config(&ref_map, remote_refs, branch, &tail);\n+\t}\n+\n+\tfor (rm = ref_map; rm; rm = rm->next)\n+\t\tif (rm->peer_ref)\n+\t\t\tread_ref(rm->peer_ref->name, rm->peer_ref->old_sha1);\n+\n+\tstore_updated_refs(\"foreign\", remote->name, ref_map);\n+\n+\treturn exit_code;\n+}\n+\n int cmd_fetch(int argc, const char **argv, const char *prefix)\n {\n \tstruct remote *remote;\n@@ -635,9 +765,8 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)\n \telse\n \t\tremote = remote_get(argv[0]);\n \n-\tif (remote->foreign_vcs) {\n-\t\tdie(\"Using foreign VCSes for fetch is not yet supported.\");\n-\t}\n+\tif (remote->foreign_vcs)\n+\t\treturn fetch_foreign(remote);\n \n \ttransport = transport_get(remote, remote->url[0]);\n \tif (verbosity >= 2)\n-- \n1.6.0.6\n"},{"id":"100050","messageId":"7vfxjpmhow.fsf@gitster.siamese.dyndns.org","threadId":"17095","inReplyTo":"alpine.LNX.1.00.0901110335520.19665@iabervon.org","subject":"Re: [RFC PATCH 3/3] Support fetching from foreign VCSes","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2009-01-12T01:33:35Z","receivedAt":"2009-01-12T01:33:35Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Daniel Barkalow <barkalow@iabervon.org> writes:\n\n> This supports a useful subset of the usual fetch logic, mostly in the\n> config file.\n>\n> Signed-off-by: Daniel Barkalow <barkalow@iabervon.org>\n\nI like the direction this series is going.  In the longer term, it would\nbe nice if we can have git-svn and git-cvsimport replaced with something\nlike this.\n\nIs the current foreign vcs interface sufficiently rich to support git as a\nforeign scm by using fast-import and fast-export?\n\nThanks.\n"},{"id":"100074","messageId":"alpine.LNX.1.00.0901120041260.19665@iabervon.org","threadId":"17095","inReplyTo":"7vfxjpmhow.fsf@gitster.siamese.dyndns.org","subject":"Re: [RFC PATCH 3/3] Support fetching from foreign VCSes","fromName":"Daniel Barkalow","fromEmail":"barkalow@iabervon.org","sentAt":"2009-01-12T05:48:28Z","receivedAt":"2009-01-12T05:48:28Z","isPatch":true,"sender":{"key":"barkalow@iabervon.org","avatar":"https://avatars.githubusercontent.com/u/55364219?v=4"},"body":"On Sun, 11 Jan 2009, Junio C Hamano wrote:\n\n> Daniel Barkalow <barkalow@iabervon.org> writes:\n> \n> > This supports a useful subset of the usual fetch logic, mostly in the\n> > config file.\n> >\n> > Signed-off-by: Daniel Barkalow <barkalow@iabervon.org>\n> \n> I like the direction this series is going.  In the longer term, it would\n> be nice if we can have git-svn and git-cvsimport replaced with something\n> like this.\n\nThat was my goal, although the only foreign system I currently use is \nPerforce.\n\n> Is the current foreign vcs interface sufficiently rich to support git as a\n> foreign scm by using fast-import and fast-export?\n\nI think so, although it would be pretty strange, since it would generally \nhave a whole lot of local data (a complete clone of any remote \nrepository).\n\n\t-Daniel\n*This .sig left intentionally blank*\n"},{"id":"100132","messageId":"20090112154224.GD10179@spearce.org","threadId":"17095","inReplyTo":"alpine.LNX.1.00.0901120041260.19665@iabervon.org","subject":"Re: [RFC PATCH 3/3] Support fetching from foreign VCSes","fromName":"Shawn O. Pearce","fromEmail":"spearce@spearce.org","sentAt":"2009-01-12T15:42:24Z","receivedAt":"2009-01-12T15:42:24Z","isPatch":true,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"Daniel Barkalow <barkalow@iabervon.org> wrote:\n> On Sun, 11 Jan 2009, Junio C Hamano wrote:\n> > Daniel Barkalow <barkalow@iabervon.org> writes:\n> > > This supports a useful subset of the usual fetch logic, mostly in the\n> > > config file.\n> > \n> > I like the direction this series is going.  In the longer term, it would\n> > be nice if we can have git-svn and git-cvsimport replaced with something\n> > like this.\n\nThe series seems to require that the foreign tool speak fast-import.  I've\ntried to get git-svn to use it, but its currently not possible because the\ngit-svn process needs to be able to read objects it has written during this\nsession.  Those objects are stored in the output pack, where only the active\nfast-import process can get to them.  Thus git-svn can't use fast-import.\n\nAs import as the git-p4 stuff is, git-svn is our \"killer feature\" when it\ncomes to foreign system integration.  I think we need to make SVN work for\nthis foreign vcs thing to work.\n \n> > Is the current foreign vcs interface sufficiently rich to support git as a\n> > foreign scm by using fast-import and fast-export?\n> \n> I think so, although it would be pretty strange, since it would generally \n> have a whole lot of local data (a complete clone of any remote \n> repository).\n\nIt might not be that bad.  If the foreign system is git and the\nlocal system is git, we should have a massive amount of object reuse.\nAt least all of the blobs from the foreign system should be reused\nby the local system, and that's like 80-90% of most project's\nobject state.\n\nIf the import is flawless (no mangling of commit messages or history)\nthen you should get 100% object reuse and the git-git import would\ngive you the same SHA-1, but just slower than going over git://.\n\nIts strange only because it would be sucking more CPU time on the\nclient than is necessary to do the fetch.  But if something like\na filter-branch tool existed to massage a fast-import stream, it\nmight be useful to fetch someone else's tree, massage it a bit,\nand then import it with a subtree merge.  :-)\n\n-- \nShawn.\n"},{"id":"100150","messageId":"alpine.LNX.1.00.0901121246320.19665@iabervon.org","threadId":"17095","inReplyTo":"20090112154224.GD10179@spearce.org","subject":"Re: [RFC PATCH 3/3] Support fetching from foreign VCSes","fromName":"Daniel Barkalow","fromEmail":"barkalow@iabervon.org","sentAt":"2009-01-12T18:19:37Z","receivedAt":"2009-01-12T18:19:37Z","isPatch":true,"sender":{"key":"barkalow@iabervon.org","avatar":"https://avatars.githubusercontent.com/u/55364219?v=4"},"body":"On Mon, 12 Jan 2009, Shawn O. Pearce wrote:\n\n> Daniel Barkalow <barkalow@iabervon.org> wrote:\n> > On Sun, 11 Jan 2009, Junio C Hamano wrote:\n> > > Daniel Barkalow <barkalow@iabervon.org> writes:\n> > > > This supports a useful subset of the usual fetch logic, mostly in the\n> > > > config file.\n> > > \n> > > I like the direction this series is going.  In the longer term, it would\n> > > be nice if we can have git-svn and git-cvsimport replaced with something\n> > > like this.\n> \n> The series seems to require that the foreign tool speak fast-import.  I've\n> tried to get git-svn to use it, but its currently not possible because the\n> git-svn process needs to be able to read objects it has written during this\n> session.  Those objects are stored in the output pack, where only the active\n> fast-import process can get to them.  Thus git-svn can't use fast-import.\n>\n> As import as the git-p4 stuff is, git-svn is our \"killer feature\" when it\n> comes to foreign system integration.  I think we need to make SVN work for\n> this foreign vcs thing to work.\n\nI think fast-import should be made sufficient for git-svn, rather than \nhaving the integration about to speak other things. As you say, git-svn is \nthe killer feature, and I'd like to have it using (and therefore \ncontributing to the testing of) all of the applicable tools.\n\nMaybe fast-import should be able to run with a bi-directional connection \nto its input, so it can acknowledge checkpoints? When the pipeline is set \nup in the main git code, it should be easy enough to do this sort of \ncomplicated stuff.\n\n> > > Is the current foreign vcs interface sufficiently rich to support git as a\n> > > foreign scm by using fast-import and fast-export?\n> > \n> > I think so, although it would be pretty strange, since it would generally \n> > have a whole lot of local data (a complete clone of any remote \n> > repository).\n> \n> It might not be that bad.  If the foreign system is git and the\n> local system is git, we should have a massive amount of object reuse.\n> At least all of the blobs from the foreign system should be reused\n> by the local system, and that's like 80-90% of most project's\n> object state.\n\nThe part I think is weird is that the helper would be first going to the \nnetwork to get all of the data, and then extracting the history from it \nlocally in a separate process (that is, passing data to it only through \nthe filesystem). Other systems generally get the data on demand, which \nsort of makes more sense for the case where you will then run exactly one \ncommand (fast-export) to it. I suppose sticking the data into the \ndestination object store would make this not so strange.\n\n> If the import is flawless (no mangling of commit messages or history)\n> then you should get 100% object reuse and the git-git import would\n> give you the same SHA-1, but just slower than going over git://.\n> \n> Its strange only because it would be sucking more CPU time on the\n> client than is necessary to do the fetch.  But if something like\n> a filter-branch tool existed to massage a fast-import stream, it\n> might be useful to fetch someone else's tree, massage it a bit,\n> and then import it with a subtree merge.  :-)\n\nThat is true, and would be a good actual use for this. It would make it \npossible for Wine to have a remote for the upstream Kconfig repository \n(that being a filtering of the linux-2.6 repository).\n\nThat is, a git repository can be \"foreign\" in that it disagrees with you \nover the project layout or contents.\n\n\t-Daniel\n*This .sig left intentionally blank*\n"},{"id":"100152","messageId":"alpine.DEB.1.00.0901122007070.3586@pacific.mpi-cbg.de","threadId":"17095","inReplyTo":"alpine.LNX.1.00.0901121246320.19665@iabervon.org","subject":"Re: [RFC PATCH 3/3] Support fetching from foreign VCSes","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2009-01-12T19:09:01Z","receivedAt":"2009-01-12T19:09:01Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Mon, 12 Jan 2009, Daniel Barkalow wrote:\n\n> Maybe fast-import should be able to run with a bi-directional connection \n> to its input, so it can acknowledge checkpoints?\n\nWhoa.\n\nfast-import was first and foremost a very simple way to get stuff done.  \nIs it absolutely necessary to complicate that?\n\nI mean, I don't know about git-svn, but shouldn't it be \nrelatively easy to use fast-import to import from Subversion once the \ninformation is extracted from Subversion?\n\nCiao,\nDscho\n"},{"id":"100154","messageId":"alpine.LNX.1.00.0901121413040.19665@iabervon.org","threadId":"17095","inReplyTo":"alpine.DEB.1.00.0901122007070.3586@pacific.mpi-cbg.de","subject":"Re: [RFC PATCH 3/3] Support fetching from foreign VCSes","fromName":"Daniel Barkalow","fromEmail":"barkalow@iabervon.org","sentAt":"2009-01-12T19:38:09Z","receivedAt":"2009-01-12T19:38:09Z","isPatch":true,"sender":{"key":"barkalow@iabervon.org","avatar":"https://avatars.githubusercontent.com/u/55364219?v=4"},"body":"On Mon, 12 Jan 2009, Johannes Schindelin wrote:\n\n> Hi,\n> \n> On Mon, 12 Jan 2009, Daniel Barkalow wrote:\n> \n> > Maybe fast-import should be able to run with a bi-directional connection \n> > to its input, so it can acknowledge checkpoints?\n> \n> Whoa.\n> \n> fast-import was first and foremost a very simple way to get stuff done.  \n> Is it absolutely necessary to complicate that?\n> \n> I mean, I don't know about git-svn, but shouldn't it be \n> relatively easy to use fast-import to import from Subversion once the \n> information is extracted from Subversion?\n\nI assume that git-svn's problem is that it would need to store too much of \nthe information (rather than being able to discard it) if it couldn't get \nthe information back from the git object database.\n\nActually, I think it might be actually simplify programs using fast-import \nif they could ask it for data from before, and I think that would have to \nbe necessary in order to have a reasonable non-git-specific incremental \nimporter without duplicating the storage of a lot of information that \npreviously went into fast-import.\n\nI know I found it helpful in my p4 one to be able to pick up the \nincremental state by looking at what refs exist and the information in \ncommits they point to, rather than trying to get the information from the \nperforce client state or custom storage.\n\n\t-Daniel\n*This .sig left intentionally blank*\n"},{"id":"102749","messageId":"200902010320.28128.johan@herland.net","threadId":"17095","inReplyTo":"alpine.LNX.1.00.0901110335520.19665@iabervon.org","subject":"Re: [RFC PATCH 3/3] Support fetching from foreign VCSes","fromName":"Johan Herland","fromEmail":"johan@herland.net","sentAt":"2009-02-01T02:20:28Z","receivedAt":"2009-02-01T02:20:28Z","isPatch":true,"sender":{"key":"johan@herland.net","avatar":"https://avatars.githubusercontent.com/u/547031?v=4"},"body":"On Sunday 11 January 2009, Daniel Barkalow wrote:\n> This supports a useful subset of the usual fetch logic, mostly in the\n> config file.\n\nHi,\n\nI love the idea of this patch series, and have started working on a CVS \nbackend for this. I have a question though...\n\n> Signed-off-by: Daniel Barkalow <barkalow@iabervon.org>\n> ---\n>  builtin-fetch.c |  135\n> +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 files changed,\n> 132 insertions(+), 3 deletions(-)\n>\n> diff --git a/builtin-fetch.c b/builtin-fetch.c\n> index 7b46f8f..14e037e 100644\n> --- a/builtin-fetch.c\n> +++ b/builtin-fetch.c\n> @@ -614,6 +614,136 @@ static void set_option(const char *name, const char\n> *value) name, transport->url);\n>  }\n>\n> +static struct ref *list_foreign(struct remote *remote)\n> +{\n\n[...]\n\n> +}\n> +\n> +static int import_foreign(struct remote *remote, struct ref *refs)\n> +{\n\n[...]\n\n> +}\n> +\n> +static int fetch_foreign(struct remote *remote)\n> +{\n> +\tstruct ref *remote_refs = list_foreign(remote);\n\nWe retrieve a list of all refs available at the given remote...\n\n> +\tstruct ref *ref_map = NULL;\n> +\tstruct ref *rm;\n> +\tstruct ref **tail = &ref_map;\n> +\tstruct branch *branch;\n> +\tint i;\n> +\n> +\tint exit_code = import_foreign(remote, remote_refs);\n\n...and then we start fetching _all_ the refs returned by list_foreign().\n\nWhen I call \"git fetch <vcs-remote> <ref>\", I expect _only_ <ref> to be \nfetched from the remote, but it seems the above code doesn't even concern \nitself with the ref(s) specified on the \"git fetch\" command-line\n\nI'm not even sure why list_foreign() should be called in this case (except, \nmaybe, to verify the existence of <ref> before attempting to fetch it).\n\nAFAICS list_foreign() is only needed by \"git fetch\" if <ref> contains a \nwildcard (like the default refspec: +refs/heads/*:refs/remotes/<remote>/*).\n\n...or have I misunderstood something fundamental about how this is going to \nwork?\n\n\nHave fun! :)\n\n...Johan\n\n-- \nJohan Herland, <johan@herland.net>\nwww.herland.net\n"},{"id":"102745","messageId":"alpine.LNX.1.00.0901312122340.19665@iabervon.org","threadId":"17095","inReplyTo":"200902010320.28128.johan@herland.net","subject":"Re: [RFC PATCH 3/3] Support fetching from foreign VCSes","fromName":"Daniel Barkalow","fromEmail":"barkalow@iabervon.org","sentAt":"2009-02-01T02:35:42Z","receivedAt":"2009-02-01T02:35:42Z","isPatch":true,"sender":{"key":"barkalow@iabervon.org","avatar":"https://avatars.githubusercontent.com/u/55364219?v=4"},"body":"On Sun, 1 Feb 2009, Johan Herland wrote:\n\n> On Sunday 11 January 2009, Daniel Barkalow wrote:\n> > This supports a useful subset of the usual fetch logic, mostly in the\n> > config file.\n> \n> Hi,\n> \n> I love the idea of this patch series, and have started working on a CVS \n> backend for this. I have a question though...\n> \n> > Signed-off-by: Daniel Barkalow <barkalow@iabervon.org>\n> > ---\n> >  builtin-fetch.c |  135\n> > +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 files changed,\n> > 132 insertions(+), 3 deletions(-)\n> >\n> > diff --git a/builtin-fetch.c b/builtin-fetch.c\n> > index 7b46f8f..14e037e 100644\n> > --- a/builtin-fetch.c\n> > +++ b/builtin-fetch.c\n> > @@ -614,6 +614,136 @@ static void set_option(const char *name, const char\n> > *value) name, transport->url);\n> >  }\n> >\n> > +static struct ref *list_foreign(struct remote *remote)\n> > +{\n> \n> [...]\n> \n> > +}\n> > +\n> > +static int import_foreign(struct remote *remote, struct ref *refs)\n> > +{\n> \n> [...]\n> \n> > +}\n> > +\n> > +static int fetch_foreign(struct remote *remote)\n> > +{\n> > +\tstruct ref *remote_refs = list_foreign(remote);\n> \n> We retrieve a list of all refs available at the given remote...\n> \n> > +\tstruct ref *ref_map = NULL;\n> > +\tstruct ref *rm;\n> > +\tstruct ref **tail = &ref_map;\n> > +\tstruct branch *branch;\n> > +\tint i;\n> > +\n> > +\tint exit_code = import_foreign(remote, remote_refs);\n> \n> ...and then we start fetching _all_ the refs returned by list_foreign().\n> \n> When I call \"git fetch <vcs-remote> <ref>\", I expect _only_ <ref> to be \n> fetched from the remote, but it seems the above code doesn't even concern \n> itself with the ref(s) specified on the \"git fetch\" command-line\n> \n> I'm not even sure why list_foreign() should be called in this case (except, \n> maybe, to verify the existence of <ref> before attempting to fetch it).\n> \n> AFAICS list_foreign() is only needed by \"git fetch\" if <ref> contains a \n> wildcard (like the default refspec: +refs/heads/*:refs/remotes/<remote>/*).\n> \n> ...or have I misunderstood something fundamental about how this is going to \n> work?\n\nNope, I was just a bit lazy; I just didn't implement looking at the \ncommand line (I just use \"git fetch\" when I'm using this), and my goal is \nto use wildcards (although I haven't gotten wildcards implemented that can \nmatch the branch names than come naturally out of the particular foreign \nsystem I'm using).\n\nI was also staying as close as possible to the git design, where it always \nfetches the complete list and then looks at what matches. It would \nprobably be a good optimization to only ask for the complete list if it's \nneeded to determine what specific refs to ask for.\n\nIncidently, you probably want this patch so it doesn't crash if you don't \nhave a merge config:\n\ncommit 71266fe87dae351c0f77b0ecf8802dab2909db05\nAuthor: Daniel Barkalow <barkalow@iabervon.org>\nDate:   Fri Jan 30 20:30:10 2009 -0500\n\n    Fix bug with not having merge config\n    \n    Signed-off-by: Daniel Barkalow <barkalow@iabervon.org>\n\ndiff --git a/builtin-fetch.c b/builtin-fetch.c\nindex 14e037e..63e0637 100644\n--- a/builtin-fetch.c\n+++ b/builtin-fetch.c\n@@ -710,6 +710,7 @@ static int fetch_foreign(struct remote *remote)\n \tstruct ref **tail = &ref_map;\n \tstruct branch *branch;\n \tint i;\n+\tint has_merge;\n \n \tint exit_code = import_foreign(remote, remote_refs);\n \tif (exit_code)\n@@ -729,9 +730,11 @@ static int fetch_foreign(struct remote *remote)\n \n \tbranch = branch_get(NULL);\n \n+\thas_merge = branch_has_merge_config(branch);\n+\n \tfor (i = 0; i < remote->fetch_refspec_nr; i++) {\n \t\tget_fetch_map(remote_refs, &remote->fetch[i], &tail, 0);\n-\t\tif (!strcmp(branch->remote_name, remote->name))\n+\t\tif (has_merge && !strcmp(branch->remote_name, remote->name))\n \t\t\tadd_merge_config(&ref_map, remote_refs, branch, &tail);\n \t}\n \n\n\t-Daniel\n*This .sig left intentionally blank*\n"}]}