git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [PATCH] Restore ls-remote reference pattern matching

From
Junio C Hamano <gitster@pobox.com>
Date
Dec 9, 2007, 06:51 UTC
Message-ID
<7v8x44tl7q.fsf@gitster.siamese.dyndns.org>
In-Reply-To
<Pine.LNX.4.64.0712082346310.5349@iabervon.org>
Daniel Barkalow <barkalow@iabervon.org> writes:
> I'd found the same code ("git log -p -- git-ls-remote.sh" also reveals it, 
> and I couldn't remember it's contrib/examples that things end up in), but 
> I don't really follow that shell syntax.
Sorry, I should have been more explicit.
At this point in the scripted version:
	for pat
	do
		case "/$path" in
		*/$pat )
			match=yes
			break ;;
		esac
	done
 - $path is what we read from peek-remote (or the equivalent from curl
   for http), e.g. "refs/heads/master", or "HEAD".
 - we iterate over remainder of arguments to the script, assigning each
   to $pat;
 - we check if the pattern "*/$pat" matches "/$path".  "case" matching
   rule is an entire string match with globbing, so it is asking if
   /$path ends with /$pat.  IOW, $pat="master" matches:
	$path=refs/heads/master
        $path=refs/remotes/origin/master
   but it does not match $path="refs/heads/omaster".
---
 builtin-ls-remote.c |   44 ++++++++++++++++++++++++++++++++++++++------
 1 files changed, 38 insertions(+), 6 deletions(-)
diff --git a/builtin-ls-remote.c b/builtin-ls-remote.c
index 56f3f88..bae7c48 100644
--- a/builtin-ls-remote.c
+++ b/builtin-ls-remote.c
@@ -6,6 +6,35 @@
 static const char ls_remote_usage[] =
 "git-ls-remote [--upload-pack=<git-upload-pack>] [<host>:]<directory>";
 
+/*
+ * pattern is a list of tail-part of accepted refnames.  Is there one
+ * among then that is a suffix of the path?  Directory boundary must
+ * be honored when doing this match.  IOW, patterns "master" and
+ * "sa/master" both match path "refs/hold/sa/master".  On the other
+ * hand, path "refs/hold/foosa/master" is matched by "master" but not
+ * by "sa/master".
+ */
+
+static int tail_match(const char **pattern, const char *path)
+{
+	int pathlen;
+	const char *p;
+
+	if (!*pattern)
+		return 1; /* no restriction */
+
+	for (pathlen = strlen(path); (p = *pattern); pattern++) {
+		int pfxlen = pathlen - strlen(p);
+		if (pfxlen < 0)
+			continue; /* pattern is longer, will never match */
+		if (strcmp(path + pfxlen, p))
+			continue; /* no tail match */
+		if (!pfxlen || path[pfxlen - 1] == '/')
+			return 1; /* fully match at directory boundary */
+	}
+	return 0;
+}
+
 int cmd_ls_remote(int argc, const char **argv, const char *prefix)
 {
 	int i;
@@ -13,6 +42,7 @@ int cmd_ls_remote(int argc, const char **argv, const char *prefix)
 	int nongit = 0;
 	unsigned flags = 0;
 	const char *uploadpack = NULL;
+	const char **pattern = NULL;
 
 	struct remote *remote;
 	struct transport *transport;
@@ -50,9 +80,9 @@ int cmd_ls_remote(int argc, const char **argv, const char *prefix)
 		break;
 	}
 
-	if (!dest || i != argc - 1)
+	if (!dest)
 		usage(ls_remote_usage);
-
+	pattern = argv + i + 1;
 	remote = nongit ? NULL : remote_get(dest);
 	if (remote && !remote->url_nr)
 		die("remote %s has no configured URL", dest);
@@ -65,10 +95,12 @@ int cmd_ls_remote(int argc, const char **argv, const char *prefix)
 	if (!ref)
 		return 1;
 
-	while (ref) {
-		if (check_ref_type(ref, flags))
-			printf("%s	%s\n", sha1_to_hex(ref->old_sha1), ref->name);
-		ref = ref->next;
+	for ( ; ref; ref = ref->next) {
+		if (!check_ref_type(ref, flags))
+			continue;
+		if (!tail_match(pattern, ref->name))
+			continue;
+		printf("%s	%s\n", sha1_to_hex(ref->old_sha1), ref->name);
 	}
 	return 0;
 }
Previous: Daniel BarkalowNext: Sergey Vlasov
Message 4 of 10 in “Restore ls-remote reference pattern matching”
  1. Restore ls-remote reference pattern matchingDaniel Barkalow, Dec 9, 2007
  2. Junio C HamanoDec 9, 2007
  3. Daniel BarkalowDec 9, 2007
  4. Junio C HamanoDec 9, 2007
  5. Sergey VlasovDec 9, 2007
  6. Eyvind BernhardsenDec 9, 2007
  7. Junio C HamanoDec 9, 2007
  8. Junio C HamanoDec 9, 2007
  9. Eyvind BernhardsenDec 10, 2007
  10. Junio C HamanoDec 10, 2007

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.