All of lore.kernel.org
 help / color / mirror / Atom feed
From: Junio C Hamano <gitster@pobox.com>
To: Daniel Barkalow <barkalow@iabervon.org>
Cc: "Linus Torvalds" <torvalds@linux-foundation.org>,
	"Jay Soffian" <jaysoffian@gmail.com>,
	"Johannes Schindelin" <Johannes.Schindelin@gmx.de>,
	しらいしななこ <nanako3@bluebottle.com>,
	git@vger.kernel.org
Subject: Re: [PATCH 2/2] Add support for url aliases in config files
Date: Sun, 24 Feb 2008 22:22:36 -0800	[thread overview]
Message-ID: <7vfxvho8r7.fsf@gitster.siamese.dyndns.org> (raw)
In-Reply-To: alpine.LNX.1.00.0802242319200.19024@iabervon.org

Daniel Barkalow <barkalow@iabervon.org> writes:

> Thanks; that's exactly what I would have done (assuming I didn't miss 
> places like last time). Except that it should say that it's still 
> undefined if you use:
>
>         [url "foo"]
>                 insteadOf = "baz"
>         [url "bar"]
>                 insteadOf = "baz/sub"
>
> in that you can't predict whether "baz/sub/a" will be "bar/a" or 
> "foo/sub/a". This is actually what I'm most concerned about, since there 
> is actually a logical expectation (the one that matches more will be used 
> in preference to the less specific one), but that's not implemented. 
> Someday, we'll probably want to implement it, and that'll change the 
> behavior of this particular case.

I'd say that that is a reasonable expectation, and it would be
fair to say that if we have it, the topic will be in 1.5.5 and
otherwise it won't.

This might be a bit over-engineered, but should do the job.

---
 Documentation/config.txt |    5 +--
 remote.c                 |   54 ++++++++++++++++++++++++++++++++-------------
 2 files changed, 40 insertions(+), 19 deletions(-)

diff --git a/Documentation/config.txt b/Documentation/config.txt
index 2981389..57b9b99 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -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.
diff --git a/remote.c b/remote.c
index 0012954..1f83696 100644
--- a/remote.c
+++ b/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)

  reply	other threads:[~2008-02-25  6:23 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-02-20 18:43 [PATCH 2/2] Add support for url aliases in config files Daniel Barkalow
2008-02-20 19:15 ` Junio C Hamano
2008-02-20 19:24   ` Daniel Barkalow
2008-02-20 19:42     ` Junio C Hamano
2008-02-20 19:54       ` Jay Soffian
2008-02-20 20:42       ` Daniel Barkalow
2008-02-20 22:02       ` しらいしななこ
2008-02-20 22:22         ` Johannes Schindelin
2008-02-21  0:47           ` Junio C Hamano
2008-02-21  1:26             ` Jay Soffian
2008-02-21  1:47               ` Linus Torvalds
2008-02-21  2:19                 ` Jay Soffian
2008-02-21  5:04                 ` Daniel Barkalow
2008-02-21  5:34                   ` Junio C Hamano
2008-02-25  4:08                     ` Junio C Hamano
2008-02-25  4:30                       ` Daniel Barkalow
2008-02-25  6:22                         ` Junio C Hamano [this message]
2008-02-25  6:35                           ` Daniel Barkalow
2008-02-21 16:31                 ` Jon Loeliger
2008-02-20 19:49     ` Jay Soffian
2008-02-20 19:58       ` Junio C Hamano
2008-02-20 20:22         ` Jay Soffian

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=7vfxvho8r7.fsf@gitster.siamese.dyndns.org \
    --to=gitster@pobox.com \
    --cc=Johannes.Schindelin@gmx.de \
    --cc=barkalow@iabervon.org \
    --cc=git@vger.kernel.org \
    --cc=jaysoffian@gmail.com \
    --cc=nanako3@bluebottle.com \
    --cc=torvalds@linux-foundation.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.