{"thread":{"id":"12154","subject":"[PATCH] Add support for host aliases in config files","startedAt":"2008-02-17T18:38:51Z","lastAt":"2008-02-18T19:29:38Z","messageCount":6,"participants":["Daniel Barkalow","Jakub Narebski","Johannes Schindelin","Junio C Hamano"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"69018","messageId":"alpine.LNX.1.00.0802171337000.5816@iabervon.org","threadId":"12154","inReplyTo":null,"subject":"[PATCH] Add support for host aliases in config files","fromName":"Daniel Barkalow","fromEmail":"barkalow@iabervon.org","sentAt":"2008-02-17T18:38:51Z","receivedAt":"2008-02-17T18:38:51Z","isPatch":true,"sender":{"key":"barkalow@iabervon.org","avatar":"https://avatars.githubusercontent.com/u/55364219?v=4"},"body":"This allows users with different preferences for access methods to the\nsame remote repositories to rewrite each other's URLs by pattern\nmatching across a large set of similiarly set up repositories to each\nget the desired access.\n\nSigned-off-by: Daniel Barkalow <barkalow@iabervon.org>\n---\nI still need to work more on the documentation (and I think I'd failed to \ncome up with an organization for it that I liked), but I'd like to get the \ncode portion out there are reviewed, at least, since I think last time, \nthe patch only got as far as a discussion of how I should explain what it \ndoes.\n\n Documentation/config.txt |   22 +++++++++\n Documentation/urls.txt   |   25 ++++++++++\n remote.c                 |  112 ++++++++++++++++++++++++++++++++++++++++++++-\n 3 files changed, 156 insertions(+), 3 deletions(-)\n\ndiff --git a/Documentation/config.txt b/Documentation/config.txt\nindex f2f6a77..6ccd59f 100644\n--- a/Documentation/config.txt\n+++ b/Documentation/config.txt\n@@ -646,6 +646,28 @@ help.format::\n \tValues 'man', 'info', 'web' and 'html' are supported. 'man' is\n \tthe default. 'web' and 'html' are the same.\n \n+host.<name>.*::\n+\tThese options provide a way to rewrite URLs when there is a\n+\tpattern of URLs with a common prefix which should be replaced\n+\twith a different prefix. For every 'alias' prefix given, any\n+\tURL git receives that starts with that prefix will be\n+\trewritten to have the 'base' prefix instead. In cases where\n+\tsome site serves a large number of repositories, and serves\n+\tthem with multiple access methods, and some users need to use\n+\tdifferent access methods, this feature allows people to\n+\tspecify any of the equivalent URLs and have git automatically\n+\trewrite the URL to the best alternative for the particular\n+\tuser, even for a never-before-seen repository on the site.\n+\n+host.<name>.base::\n+\tThe base URL which should be used for this particular\n+\thost.\n+\n+host.<name>.rewritebase::\n+\tAdditional base URLs which refer to this host. If a URL\n+\tmatches this, any access to it will use the URL formed with\n+\tthe corresponding base URL instead of the given URL.\n+\n http.proxy::\n \tOverride the HTTP proxy, normally configured using the 'http_proxy'\n \tenvironment variable (see linkgit:curl[1]).  This can be overridden\ndiff --git a/Documentation/urls.txt b/Documentation/urls.txt\nindex 81ac17f..11c05db 100644\n--- a/Documentation/urls.txt\n+++ b/Documentation/urls.txt\n@@ -44,3 +44,28 @@ endif::git-clone[]\n ifdef::git-clone[]\n They are equivalent, except the former implies --local option.\n endif::git-clone[]\n+\n+\n+If there are a large number of similarly-named remote repositories and\n+you want to use a different format for them (such that the URLs you\n+use will be rewritten into URLs that work), you can create a\n+configuration section of the form:\n+\n+------------\n+\t[host \"<host>\"]\n+\t\tbase = <actual url base>\n+\t\trewritebase = <other url base>\n+------------\n+\n+If you have a section:\n+\n+------------\n+\t[host \"xz\"]\n+\t\tbase = git://git.host.xz/\n+\t\trewritebase = host.xz:/path/to/\n+\t\trewritebase = work:\n+------------\n+\n+a URL like \"work:repo.git\" or like \"host.xz:/path/to/repo.git\" will be\n+rewritten in any context that takes a URL to be\n+\"git://git.host.xz/repo.git\".\ndiff --git a/remote.c b/remote.c\nindex 6b56473..59338a3 100644\n--- a/remote.c\n+++ b/remote.c\n@@ -2,6 +2,15 @@\n #include \"remote.h\"\n #include \"refs.h\"\n \n+struct host {\n+\tconst char *name;\n+\n+\tconst char *base;\n+\n+\tconst char **alias;\n+\tint alias_nr;\n+};\n+\n static struct remote **remotes;\n static int allocated_remotes;\n \n@@ -11,9 +20,32 @@ static int allocated_branches;\n static struct branch *current_branch;\n static const char *default_remote_name;\n \n+static struct host **hosts;\n+static int allocated_hosts;\n+\n #define BUF_SIZE (2048)\n static char buffer[BUF_SIZE];\n \n+static const char *alias_url(const char *url)\n+{\n+\tint i, j;\n+\tfor (i = 0; i < allocated_hosts; i++) {\n+\t\tif (!hosts[i])\n+\t\t\tcontinue;\n+\t\tfor (j = 0; j < hosts[i]->alias_nr; j++) {\n+\t\t\tif (!prefixcmp(url, hosts[i]->alias[j])) {\n+\t\t\t\tchar *ret = malloc(strlen(hosts[i]->base) -\n+\t\t\t\t\t\t   strlen(hosts[i]->alias[j]) +\n+\t\t\t\t\t\t   strlen(url) + 1);\n+\t\t\t\tstrcpy(ret, hosts[i]->base);\n+\t\t\t\tstrcat(ret, url + strlen(hosts[i]->alias[j]));\n+\t\t\t\treturn ret;\n+\t\t\t}\n+\t\t}\n+\t}\n+\treturn url;\n+}\n+\n static void add_push_refspec(struct remote *remote, const char *ref)\n {\n \tint nr = remote->push_refspec_nr + 1;\n@@ -41,6 +73,11 @@ static void add_url(struct remote *remote, const char *url)\n \tremote->url_nr = nr;\n }\n \n+static void add_url_alias(struct remote *remote, const char *url)\n+{\n+\tadd_url(remote, alias_url(url));\n+}\n+\n static struct remote *make_remote(const char *name, int len)\n {\n \tint i, empty = -1;\n@@ -121,6 +158,48 @@ static struct branch *make_branch(const char *name, int len)\n \treturn branches[empty];\n }\n \n+static struct host *make_host(const char *name, int len)\n+{\n+\tint i, empty = -1;\n+\n+\tfor (i = 0; i < allocated_hosts; i++) {\n+\t\tif (!hosts[i]) {\n+\t\t\tif (empty < 0)\n+\t\t\t\tempty = i;\n+\t\t} else {\n+\t\t\tif (len ? (!strncmp(name, hosts[i]->name, len) &&\n+\t\t\t\t   !hosts[i]->name[len]) :\n+\t\t\t    !strcmp(name, hosts[i]->name))\n+\t\t\t\treturn hosts[i];\n+\t\t}\n+\t}\n+\n+\tif (empty < 0) {\n+\t\tempty = allocated_hosts;\n+\t\tallocated_hosts += allocated_hosts ? allocated_hosts : 1;\n+\t\thosts = xrealloc(hosts,\n+\t\t\t\t sizeof(*hosts) * allocated_hosts);\n+\t\tmemset(hosts + empty, 0,\n+\t\t       (allocated_hosts - empty) * sizeof(*hosts));\n+\t}\n+\thosts[empty] = xcalloc(1, sizeof(struct host));\n+\tif (len)\n+\t\thosts[empty]->name = xstrndup(name, len);\n+\telse\n+\t\thosts[empty]->name = xstrdup(name);\n+\n+\treturn hosts[empty];\n+}\n+\n+static void add_alias(struct host *host, const char *name)\n+{\n+\tint nr = host->alias_nr + 1;\n+\thost->alias =\n+\t\txrealloc(host->alias, nr * sizeof(char *));\n+\thost->alias[nr-1] = name;\n+\thost->alias_nr = nr;\n+}\n+\n static void read_remotes_file(struct remote *remote)\n {\n \tFILE *f = fopen(git_path(\"remotes/%s\", remote->name), \"r\");\n@@ -154,7 +233,7 @@ static void read_remotes_file(struct remote *remote)\n \n \t\tswitch (value_list) {\n \t\tcase 0:\n-\t\t\tadd_url(remote, xstrdup(s));\n+\t\t\tadd_url_alias(remote, xstrdup(s));\n \t\t\tbreak;\n \t\tcase 1:\n \t\t\tadd_push_refspec(remote, xstrdup(s));\n@@ -206,7 +285,7 @@ static void read_branches_file(struct remote *remote)\n \t} else {\n \t\tbranch = \"refs/heads/master\";\n \t}\n-\tadd_url(remote, p);\n+\tadd_url_alias(remote, p);\n \tadd_fetch_refspec(remote, branch);\n \tremote->fetch_tags = 1; /* always auto-follow */\n }\n@@ -236,6 +315,20 @@ static int handle_config(const char *key, const char *value)\n \t\t}\n \t\treturn 0;\n \t}\n+\tif (!prefixcmp(key, \"host.\")) {\n+\t\tstruct host *host;\n+\t\tname = key + 5;\n+\t\tsubkey = strrchr(name, '.');\n+\t\tif (!subkey)\n+\t\t\treturn 0;\n+\t\thost = make_host(name, subkey - name);\n+\t\tif (!value)\n+\t\t\treturn 0;\n+\t\tif (!strcmp(subkey, \".base\"))\n+\t\t\thost->base = xstrdup(value);\n+\t\telse if (!strcmp(subkey, \".rewritebase\"))\n+\t\t\tadd_alias(host, xstrdup(value));\n+\t}\n \tif (prefixcmp(key,  \"remote.\"))\n \t\treturn 0;\n \tname = key + 7;\n@@ -287,6 +380,18 @@ static int handle_config(const char *key, const char *value)\n \treturn 0;\n }\n \n+static void alias_all_urls(void)\n+{\n+\tint i, j;\n+\tfor (i = 0; i < allocated_remotes; i++) {\n+\t\tif (!remotes[i])\n+\t\t\tcontinue;\n+\t\tfor (j = 0; j < remotes[i]->url_nr; j++) {\n+\t\t\tremotes[i]->url[j] = alias_url(remotes[i]->url[j]);\n+\t\t}\n+\t}\n+}\n+\n static void read_config(void)\n {\n \tunsigned char sha1[20];\n@@ -303,6 +408,7 @@ static void read_config(void)\n \t\t\tmake_branch(head_ref + strlen(\"refs/heads/\"), 0);\n \t}\n \tgit_config(handle_config);\n+\talias_all_urls();\n }\n \n struct refspec *parse_ref_spec(int nr_refspec, const char **refspec)\n@@ -368,7 +474,7 @@ struct remote *remote_get(const char *name)\n \t\t\tread_branches_file(ret);\n \t}\n \tif (!ret->url)\n-\t\tadd_url(ret, name);\n+\t\tadd_url_alias(ret, name);\n \tif (!ret->url)\n \t\treturn NULL;\n \tret->fetch = parse_ref_spec(ret->fetch_refspec_nr, ret->fetch_refspec);\n-- \n1.5.4.1.1350.g2b9ee\n"},{"id":"69020","messageId":"m3zltza06r.fsf@localhost.localdomain","threadId":"12154","inReplyTo":"alpine.LNX.1.00.0802171337000.5816@iabervon.org","subject":"Re: [PATCH] Add support for host aliases in config files","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2008-02-17T18:48:51Z","receivedAt":"2008-02-17T18:48:51Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Daniel Barkalow <barkalow@iabervon.org> writes:\n\n> +host.<name>.*::\n> +\tThese options provide a way to rewrite URLs when there is a\n> +\tpattern of URLs with a common prefix which should be replaced\n> +\twith a different prefix. For every 'alias' prefix given, any\n\nYou menat 'rewritebase' prefix here, isn't it?\n\n> +------------\n> +\t[host \"<host>\"]\n> +\t\tbase = <actual url base>\n> +\t\trewritebase = <other url base>\n> +------------\n[...]\n> +\t\telse if (!strcmp(subkey, \".rewritebase\"))\n> +\t\t\tadd_alias(host, xstrdup(value));\n> +\t}\n\n-- \nJakub Narebski\nPoland\nShadeHawk on #git\n"},{"id":"69021","messageId":"alpine.LNX.1.00.0802171357510.5816@iabervon.org","threadId":"12154","inReplyTo":"m3zltza06r.fsf@localhost.localdomain","subject":"Re: [PATCH] Add support for host aliases in config files","fromName":"Daniel Barkalow","fromEmail":"barkalow@iabervon.org","sentAt":"2008-02-17T18:58:43Z","receivedAt":"2008-02-17T18:58:43Z","isPatch":true,"sender":{"key":"barkalow@iabervon.org","avatar":"https://avatars.githubusercontent.com/u/55364219?v=4"},"body":"On Sun, 17 Feb 2008, Jakub Narebski wrote:\n\n> Daniel Barkalow <barkalow@iabervon.org> writes:\n> \n> > +host.<name>.*::\n> > +\tThese options provide a way to rewrite URLs when there is a\n> > +\tpattern of URLs with a common prefix which should be replaced\n> > +\twith a different prefix. For every 'alias' prefix given, any\n> \n> You menat 'rewritebase' prefix here, isn't it?\n\nYes.\n\n\t-Daniel\n*This .sig left intentionally blank*\n"},{"id":"69029","messageId":"alpine.LSU.1.00.0802171935200.30505@racer.site","threadId":"12154","inReplyTo":"alpine.LNX.1.00.0802171337000.5816@iabervon.org","subject":"Re: [PATCH] Add support for host aliases in config files","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2008-02-17T19:36:20Z","receivedAt":"2008-02-17T19:36:20Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Sun, 17 Feb 2008, Daniel Barkalow wrote:\n\n> This allows users with different preferences for access methods to the \n> same remote repositories to rewrite each other's URLs by pattern \n> matching across a large set of similiarly set up repositories to each \n> get the desired access.\n> \n> Signed-off-by: Daniel Barkalow <barkalow@iabervon.org>\n\nHow about adding your example with master.kernel.org?  That should make it \neasier to understand for people like me, who was puzzled after reading \nthis commit message the first time.\n\nCiao,\nDscho\n"},{"id":"69085","messageId":"7vskzquarz.fsf@gitster.siamese.dyndns.org","threadId":"12154","inReplyTo":"alpine.LNX.1.00.0802171337000.5816@iabervon.org","subject":"Re: [PATCH] Add support for host aliases in config files","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2008-02-18T04:52:00Z","receivedAt":"2008-02-18T04:52:00Z","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> ..., but I'd like to get the \n> code portion out there are reviewed, at least, since I think last time, \n> the patch only got as far as a discussion of how I should explain what it \n> does.\n\nI actually think that is the most important part to get it right\nfirst.  I usually do not have to read the patch text to reject\nan ill-conceived idea if the description is unclear and/or\nunconvincing.\n\nI think the documentation (I removed from the quote) shows the\nfeature is unambiguously good.\n\n> diff --git a/remote.c b/remote.c\n> index 6b56473..59338a3 100644\n> --- a/remote.c\n> +++ b/remote.c\n> @@ -2,6 +2,15 @@\n>  #include \"remote.h\"\n>  #include \"refs.h\"\n>  \n> +struct host {\n> +\tconst char *name;\n> +\n> +\tconst char *base;\n> +\n> +\tconst char **alias;\n> +\tint alias_nr;\n> +};\n\nExtra blank lines?\n\n> @@ -11,9 +20,32 @@ static int allocated_branches;\n>  static struct branch *current_branch;\n>  static const char *default_remote_name;\n>  \n> +static struct host **hosts;\n> +static int allocated_hosts;\n\nThe allocation in remote.c file is unusual from the rest of git\nthat usually follow the technical/api-allocation-growing\nconvention (the comment unfortunately applies to the code we\nalready have there).\n\n> +static const char *alias_url(const char *url)\n> +{\n> +\tint i, j;\n> +\tfor (i = 0; i < allocated_hosts; i++) {\n> +\t\tif (!hosts[i])\n> +\t\t\tcontinue;\n> +\t\tfor (j = 0; j < hosts[i]->alias_nr; j++) {\n> +\t\t\tif (!prefixcmp(url, hosts[i]->alias[j])) {\n> +\t\t\t\tchar *ret = malloc(strlen(hosts[i]->base) -\n> +\t\t\t\t\t\t   strlen(hosts[i]->alias[j]) +\n> +\t\t\t\t\t\t   strlen(url) + 1);\n> +\t\t\t\tstrcpy(ret, hosts[i]->base);\n> +\t\t\t\tstrcat(ret, url + strlen(hosts[i]->alias[j]));\n> +\t\t\t\treturn ret;\n> +\t\t\t}\n\nFirst match semantics is fine during runtime but at some point\nwe would want a \"config file lint\" that points out ambiguous\naliases perhaps?\n\n> +static struct host *make_host(const char *name, int len)\n> +{\n> ...\n> +\tif (empty < 0) {\n> +\t\tempty = allocated_hosts;\n> +\t\tallocated_hosts += allocated_hosts ? allocated_hosts : 1;\n> +\t\thosts = xrealloc(hosts,\n> +\t\t\t\t sizeof(*hosts) * allocated_hosts);\n\nThis hand-rolled allocation growing is quite different from the\nrest of our codebase.\n\n> +static void add_alias(struct host *host, const char *name)\n> +{\n> +\tint nr = host->alias_nr + 1;\n> +\thost->alias =\n> +\t\txrealloc(host->alias, nr * sizeof(char *));\n> +\thost->alias[nr-1] = name;\n> +\thost->alias_nr = nr;\n> +}\n\nAnd this \"add one-by-one\" allocation, too.\n\n> @@ -154,7 +233,7 @@ static void read_remotes_file(struct remote *remote)\n>  \n>  \t\tswitch (value_list) {\n>  \t\tcase 0:\n> -\t\t\tadd_url(remote, xstrdup(s));\n> +\t\t\tadd_url_alias(remote, xstrdup(s));\n>  \t\t\tbreak;\n>  \t\tcase 1:\n>  \t\t\tadd_push_refspec(remote, xstrdup(s));\n> @@ -206,7 +285,7 @@ static void read_branches_file(struct remote *remote)\n>  \t} else {\n>  \t\tbranch = \"refs/heads/master\";\n>  \t}\n> -\tadd_url(remote, p);\n> +\tadd_url_alias(remote, p);\n>  \tadd_fetch_refspec(remote, branch);\n>  \tremote->fetch_tags = 1; /* always auto-follow */\n>  }\n\nThese two are logical and clean updates.\n\n> @@ -236,6 +315,20 @@ static int handle_config(const char *key, const char *value)\n>  \t\t}\n>  \t\treturn 0;\n>  \t}\n> +\tif (!prefixcmp(key, \"host.\")) {\n> +\t\tstruct host *host;\n> +\t\tname = key + 5;\n> +\t\tsubkey = strrchr(name, '.');\n> +\t\tif (!subkey)\n> +\t\t\treturn 0;\n\nThis \"ignore this entry\" is good.  We might later want to add\nhost.<var> that is not about a specific host, and we would want\nto be able to read a configuration that is written for such a\nfuture version of git.\n\n> +\t\thost = make_host(name, subkey - name);\n> +\t\tif (!value)\n> +\t\t\treturn 0;\n\nThis is not.\n\n (1) We should barf saying \"host.<this-host>.<var> configuration\n     should be a string\", for base and rewritebase, instead of\n     silently ignoring such a misconfiguration;\n\n (2) We should _not_ do such barfing for future variables that\n     are not base nor rewritebase, so this \"return\" is at a\n     wrong place.\n\nSo the code should do this part (perhaps with git_config_string())\nfirst,...\n\n> +\t\tif (!strcmp(subkey, \".base\"))\n> +\t\t\thost->base = xstrdup(value);\n> +\t\telse if (!strcmp(subkey, \".rewritebase\"))\n> +\t\t\tadd_alias(host, xstrdup(value));\n\n... and then ignore anything other than host.<this-host>.{base,rewritebase}\nthat may mean something in future versions of git.\n"},{"id":"69192","messageId":"alpine.LNX.1.00.0802181410120.5816@iabervon.org","threadId":"12154","inReplyTo":"7vskzquarz.fsf@gitster.siamese.dyndns.org","subject":"Re: [PATCH] Add support for host aliases in config files","fromName":"Daniel Barkalow","fromEmail":"barkalow@iabervon.org","sentAt":"2008-02-18T19:29:38Z","receivedAt":"2008-02-18T19:29:38Z","isPatch":true,"sender":{"key":"barkalow@iabervon.org","avatar":"https://avatars.githubusercontent.com/u/55364219?v=4"},"body":"On Sun, 17 Feb 2008, Junio C Hamano wrote:\n\n> Daniel Barkalow <barkalow@iabervon.org> writes:\n> \n> > ..., but I'd like to get the \n> > code portion out there are reviewed, at least, since I think last time, \n> > the patch only got as far as a discussion of how I should explain what it \n> > does.\n> \n> I actually think that is the most important part to get it right\n> first.  I usually do not have to read the patch text to reject\n> an ill-conceived idea if the description is unclear and/or\n> unconvincing.\n> \n> I think the documentation (I removed from the quote) shows the\n> feature is unambiguously good.\n\nWhat I meant by that was that you'd asked for some change in how this \nfeature would get mentioned to people reading man pages on git commands \nthat can use it.\n\n> > diff --git a/remote.c b/remote.c\n> > index 6b56473..59338a3 100644\n> > --- a/remote.c\n> > +++ b/remote.c\n> > @@ -2,6 +2,15 @@\n> >  #include \"remote.h\"\n> >  #include \"refs.h\"\n> >  \n> > +struct host {\n> > +\tconst char *name;\n> > +\n> > +\tconst char *base;\n> > +\n> > +\tconst char **alias;\n> > +\tint alias_nr;\n> > +};\n> \n> Extra blank lines?\n\nI tend to like grouping related fields by having blank lines between \nunrelated ones, but it's not needed here.\n\n> > @@ -11,9 +20,32 @@ static int allocated_branches;\n> >  static struct branch *current_branch;\n> >  static const char *default_remote_name;\n> >  \n> > +static struct host **hosts;\n> > +static int allocated_hosts;\n> \n> The allocation in remote.c file is unusual from the rest of git\n> that usually follow the technical/api-allocation-growing\n> convention (the comment unfortunately applies to the code we\n> already have there).\n\nI think I originally used an older style that never got converted, and \nthis time matched the style of the rest of the file. I'll add an initial \npatch to convert the rest of the file to the standard thing, and use that \nstyle for this patch as well.\n\n> > +static const char *alias_url(const char *url)\n> > +{\n> > +\tint i, j;\n> > +\tfor (i = 0; i < allocated_hosts; i++) {\n> > +\t\tif (!hosts[i])\n> > +\t\t\tcontinue;\n> > +\t\tfor (j = 0; j < hosts[i]->alias_nr; j++) {\n> > +\t\t\tif (!prefixcmp(url, hosts[i]->alias[j])) {\n> > +\t\t\t\tchar *ret = malloc(strlen(hosts[i]->base) -\n> > +\t\t\t\t\t\t   strlen(hosts[i]->alias[j]) +\n> > +\t\t\t\t\t\t   strlen(url) + 1);\n> > +\t\t\t\tstrcpy(ret, hosts[i]->base);\n> > +\t\t\t\tstrcat(ret, url + strlen(hosts[i]->alias[j]));\n> > +\t\t\t\treturn ret;\n> > +\t\t\t}\n> \n> First match semantics is fine during runtime but at some point\n> we would want a \"config file lint\" that points out ambiguous\n> aliases perhaps?\n\nI think first match may actually be useful in dealing with sites where a \nsubset of the web-served space is git-served or something. But I'm really \nnot sure; maybe we want \"longest base\" or something.\n\n> > @@ -154,7 +233,7 @@ static void read_remotes_file(struct remote *remote)\n> >  \n> >  \t\tswitch (value_list) {\n> >  \t\tcase 0:\n> > -\t\t\tadd_url(remote, xstrdup(s));\n> > +\t\t\tadd_url_alias(remote, xstrdup(s));\n> >  \t\t\tbreak;\n> >  \t\tcase 1:\n> >  \t\t\tadd_push_refspec(remote, xstrdup(s));\n> > @@ -206,7 +285,7 @@ static void read_branches_file(struct remote *remote)\n> >  \t} else {\n> >  \t\tbranch = \"refs/heads/master\";\n> >  \t}\n> > -\tadd_url(remote, p);\n> > +\tadd_url_alias(remote, p);\n> >  \tadd_fetch_refspec(remote, branch);\n> >  \tremote->fetch_tags = 1; /* always auto-follow */\n> >  }\n> \n> These two are logical and clean updates.\n> \n> > @@ -236,6 +315,20 @@ static int handle_config(const char *key, const char *value)\n> >  \t\t}\n> >  \t\treturn 0;\n> >  \t}\n> > +\tif (!prefixcmp(key, \"host.\")) {\n> > +\t\tstruct host *host;\n> > +\t\tname = key + 5;\n> > +\t\tsubkey = strrchr(name, '.');\n> > +\t\tif (!subkey)\n> > +\t\t\treturn 0;\n> \n> This \"ignore this entry\" is good.  We might later want to add\n> host.<var> that is not about a specific host, and we would want\n> to be able to read a configuration that is written for such a\n> future version of git.\n> \n> > +\t\thost = make_host(name, subkey - name);\n> > +\t\tif (!value)\n> > +\t\t\treturn 0;\n> \n> This is not.\n> \n>  (1) We should barf saying \"host.<this-host>.<var> configuration\n>      should be a string\", for base and rewritebase, instead of\n>      silently ignoring such a misconfiguration;\n\nTrue. I'll look up the present best practices for config stuff.\n\n>  (2) We should _not_ do such barfing for future variables that\n>      are not base nor rewritebase, so this \"return\" is at a\n>      wrong place.\n\nI was intentionally careful to ignore unknown options.\n\n\t-Daniel\n*This .sig left intentionally blank*\n"}]}