mirror of
https://github.com/git/git.git
synced 2024-11-19 08:14:00 +01:00
url rewriting: take longest and first match
Earlier we had a cop-out in the documentation to make the behaviour "undefined" if configuration had more than one insteadOf that would match the target URL, like this: [url "git://git.or.cz/"] insteadOf = "git.or.cz:" ; (1) insteadOf = "repo.or.cz:" ; (2) [url "/local/mirror/"] insteadOf = "git.or.cz:myrepo" ; (3) insteadOf = "repo.or.cz:" ; (4) It would be most natural to take the longest and first match, i.e. - rewrite "git.or.cz:frotz" to "git://git.or.cz/frotz" by using (1), - rewrite "git.or.cz:myrepo/xyzzy" to "/local/mirror/xyzzy" by favoring (3) over (1), and - rewrite "repo.or.cz:frotz" to "git://git.or.cz/frotz" by favoring (2) over (4). Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
parent
55029ae4da
commit
844112cac0
@ -894,9 +894,8 @@ url.<base>.insteadOf::
|
||||
methods, this feature allows people to specify any of the
|
||||
equivalent URLs and have git automatically rewrite the URL to
|
||||
the best alternative for the particular user, even for a
|
||||
never-before-seen repository on the site. The effect of
|
||||
having multiple `insteadOf` values from different
|
||||
`<base>` match to an URL is undefined.
|
||||
never-before-seen repository on the site. When more than one
|
||||
insteadOf strings match a given URL, the longest match is used.
|
||||
|
||||
user.email::
|
||||
Your email address to be recorded in any newly created commits.
|
||||
|
54
remote.c
54
remote.c
@ -2,9 +2,14 @@
|
||||
#include "remote.h"
|
||||
#include "refs.h"
|
||||
|
||||
struct counted_string {
|
||||
size_t len;
|
||||
const char *s;
|
||||
};
|
||||
struct rewrite {
|
||||
const char *base;
|
||||
const char **instead_of;
|
||||
size_t baselen;
|
||||
struct counted_string *instead_of;
|
||||
int instead_of_nr;
|
||||
int instead_of_alloc;
|
||||
};
|
||||
@ -30,21 +35,32 @@ static char buffer[BUF_SIZE];
|
||||
static const char *alias_url(const char *url)
|
||||
{
|
||||
int i, j;
|
||||
char *ret;
|
||||
struct counted_string *longest;
|
||||
int longest_i;
|
||||
|
||||
longest = NULL;
|
||||
longest_i = -1;
|
||||
for (i = 0; i < rewrite_nr; i++) {
|
||||
if (!rewrite[i])
|
||||
continue;
|
||||
for (j = 0; j < rewrite[i]->instead_of_nr; j++) {
|
||||
if (!prefixcmp(url, rewrite[i]->instead_of[j])) {
|
||||
char *ret = malloc(strlen(rewrite[i]->base) -
|
||||
strlen(rewrite[i]->instead_of[j]) +
|
||||
strlen(url) + 1);
|
||||
strcpy(ret, rewrite[i]->base);
|
||||
strcat(ret, url + strlen(rewrite[i]->instead_of[j]));
|
||||
return ret;
|
||||
if (!prefixcmp(url, rewrite[i]->instead_of[j].s) &&
|
||||
(!longest ||
|
||||
longest->len < rewrite[i]->instead_of[j].len)) {
|
||||
longest = &(rewrite[i]->instead_of[j]);
|
||||
longest_i = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
return url;
|
||||
if (!longest)
|
||||
return url;
|
||||
|
||||
ret = malloc(rewrite[longest_i]->baselen +
|
||||
(strlen(url) - longest->len) + 1);
|
||||
strcpy(ret, rewrite[longest_i]->base);
|
||||
strcpy(ret + rewrite[longest_i]->baselen, url + longest->len);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void add_push_refspec(struct remote *remote, const char *ref)
|
||||
@ -137,27 +153,33 @@ static struct rewrite *make_rewrite(const char *base, int len)
|
||||
int i;
|
||||
|
||||
for (i = 0; i < rewrite_nr; i++) {
|
||||
if (len ? (!strncmp(base, rewrite[i]->base, len) &&
|
||||
!rewrite[i]->base[len]) :
|
||||
!strcmp(base, rewrite[i]->base))
|
||||
if (len
|
||||
? (len == rewrite[i]->baselen &&
|
||||
!strncmp(base, rewrite[i]->base, len))
|
||||
: !strcmp(base, rewrite[i]->base))
|
||||
return rewrite[i];
|
||||
}
|
||||
|
||||
ALLOC_GROW(rewrite, rewrite_nr + 1, rewrite_alloc);
|
||||
ret = xcalloc(1, sizeof(struct rewrite));
|
||||
rewrite[rewrite_nr++] = ret;
|
||||
if (len)
|
||||
if (len) {
|
||||
ret->base = xstrndup(base, len);
|
||||
else
|
||||
ret->baselen = len;
|
||||
}
|
||||
else {
|
||||
ret->base = xstrdup(base);
|
||||
|
||||
ret->baselen = strlen(base);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void add_instead_of(struct rewrite *rewrite, const char *instead_of)
|
||||
{
|
||||
ALLOC_GROW(rewrite->instead_of, rewrite->instead_of_nr + 1, rewrite->instead_of_alloc);
|
||||
rewrite->instead_of[rewrite->instead_of_nr++] = instead_of;
|
||||
rewrite->instead_of[rewrite->instead_of_nr].s = instead_of;
|
||||
rewrite->instead_of[rewrite->instead_of_nr].len = strlen(instead_of);
|
||||
rewrite->instead_of_nr++;
|
||||
}
|
||||
|
||||
static void read_remotes_file(struct remote *remote)
|
||||
|
Loading…
Reference in New Issue
Block a user