git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] ls-tree matching a prefix
@ 2005-05-26  3:47 Jason McMullan
  2005-05-26  4:44 ` Junio C Hamano
  0 siblings, 1 reply; 6+ messages in thread
From: Jason McMullan @ 2005-05-26  3:47 UTC (permalink / raw)
  To: git

In the Porcelain I've been working on, I have found it useful
to retrieve a single file's SHA1 out of a tree when I don't 
want to create an index.

For this purpose, I've enhanced git-ls-tree to allow the
specification of an optional 'match path' that restricts
that output of git-ls-tree to just the path requested.

If the patch has a '/' in it, it implies -r.

ie:

$ git-ls-tree HEAD Makefile
100644  blob    92d0e87535ecaa5e52a6503c43dd30dd546ea6b7        Makefile

$ git-ls-tree HEAD t
040000  tree    33ce2f3201c99d5da785bb777639c1e2374c44d2        t

$ git-ls-tree HEAD t/test-lib.sh 
100755  blob    d3f71d1932310197219155b426687d155bf63c5b	t/test-lib.sh

Signed-Off-By: Jason McMullan <jason.mcmullan@timesys.com>

diff --git a/Documentation/git-ls-tree.txt b/Documentation/git-ls-tree.txt
--- a/Documentation/git-ls-tree.txt
+++ b/Documentation/git-ls-tree.txt
@@ -27,6 +27,10 @@ OPTIONS
 -z::
 	\0 line termination on output
 
+[path]::
+	Only return items that match the specified path, relative to the
+	root of the tree. If a patch has a '/' in it, implies -r
+
 Output Format
 -------------
         <mode>\t	<type>\t	<object>\t	<file>
diff --git a/ls-tree.c b/ls-tree.c
--- a/ls-tree.c
+++ b/ls-tree.c
@@ -26,10 +26,32 @@ static void print_path_prefix(struct pat
 static void list_recursive(void *buffer,
 			   const char *type,
 			   unsigned long size,
-			   struct path_prefix *prefix)
+			   struct path_prefix *prefix,
+			   const char *match_path)
 {
 	struct path_prefix this_prefix;
 	this_prefix.prev = prefix;
+	char mpref[PATH_MAX];
+	size_t mlen = 0;
+	char *cp = NULL;
+	if (match_path != NULL) {
+		if (*match_path == 0)
+			return;
+		cp = strchr(match_path,'/');
+		if (cp == NULL) {
+			strcpy(mpref,match_path);
+			match_path = NULL;
+		} else {
+			recursive = 1;
+			strncpy(mpref,match_path,cp-match_path);
+			mpref[cp-match_path]=0;
+			cp++;
+			match_path = cp;
+			if (*cp == 0)
+				cp = NULL;
+		}
+		mlen = strlen(mpref);
+	}
 
 	if (strcmp(type, "tree"))
 		die("expected a 'tree' node");
@@ -48,27 +70,35 @@ static void list_recursive(void *buffer,
 		buffer = sha1 + 20;
 		size -= namelen + 20;
 
-		printf("%06o\t%s\t%s\t", mode,
-		       S_ISDIR(mode) ? "tree" : "blob",
-		       sha1_to_hex(sha1));
-		print_path_prefix(prefix);
-		fputs(path, stdout);
-		putchar(line_termination);
+		if (mlen && strcmp(mpref, path) != 0)
+			continue;
+
+		if (cp == NULL) {
+			printf("%06o\t%s\t%s\t", mode,
+			       S_ISDIR(mode) ? "tree" : "blob",
+			       sha1_to_hex(sha1));
+			print_path_prefix(prefix);
+			fputs(path, stdout);
+			putchar(line_termination);
+		}
 
 		if (! recursive || ! S_ISDIR(mode))
 			continue;
 
+		if (mlen && cp == NULL)
+			continue;
+
 		if (! (eltbuf = read_sha1_file(sha1, elttype, &eltsize)) ) {
 			error("cannot read %s", sha1_to_hex(sha1));
 			continue;
 		}
 		this_prefix.name = path;
-		list_recursive(eltbuf, elttype, eltsize, &this_prefix);
+		list_recursive(eltbuf, elttype, eltsize, &this_prefix, match_path);
 		free(eltbuf);
 	}
 }
 
-static int list(unsigned char *sha1)
+static int list(unsigned char *sha1, const char *match_path)
 {
 	void *buffer;
 	unsigned long size;
@@ -76,12 +106,12 @@ static int list(unsigned char *sha1)
 	buffer = read_object_with_reference(sha1, "tree", &size, NULL);
 	if (!buffer)
 		die("unable to read sha1 file");
-	list_recursive(buffer, "tree", size, NULL);
+	list_recursive(buffer, "tree", size, NULL, match_path);
 	free(buffer);
 	return 0;
 }
 
-static const char *ls_tree_usage = "git-ls-tree [-r] [-z] <key>";
+static const char *ls_tree_usage = "git-ls-tree [-r] [-z] <key> [path]";
 
 int main(int argc, char **argv)
 {
@@ -101,11 +131,11 @@ int main(int argc, char **argv)
 		argc--; argv++;
 	}
 
-	if (argc != 2)
+	if (argc != 2 && argc != 3)
 		usage(ls_tree_usage);
 	if (get_sha1(argv[1], sha1) < 0)
 		usage(ls_tree_usage);
-	if (list(sha1) < 0)
+	if (list(sha1, argc==3 ? argv[2] : NULL) < 0)
 		die("list failed");
 	return 0;
 }

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] ls-tree matching a prefix
  2005-05-26  3:47 [PATCH] ls-tree matching a prefix Jason McMullan
@ 2005-05-26  4:44 ` Junio C Hamano
  2005-05-26 12:50   ` McMullan, Jason
  0 siblings, 1 reply; 6+ messages in thread
From: Junio C Hamano @ 2005-05-26  4:44 UTC (permalink / raw)
  To: Jason McMullan; +Cc: git

>>>>> "JM" == Jason McMullan <jason.mcmullan@timesys.com> writes:

JM> For this purpose, I've enhanced git-ls-tree to allow the
JM> specification of an optional 'match path' that restricts
JM> that output of git-ls-tree to just the path requested.

JM> If the patch has a '/' in it, it implies -r.

I'd rather see the behaviour match existing commands with path
restriction, like diff-tree, diff-cache, and diff-files.  That
is, to take a list of paths and limit your output to those that
match one of them.  I do not think this enhancement would
negatively affect your stated use of getting one entry with the
exact match.


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] ls-tree matching a prefix
  2005-05-26  4:44 ` Junio C Hamano
@ 2005-05-26 12:50   ` McMullan, Jason
  2005-05-26 15:13     ` [PATCH] ls-tree matching multiple paths Jason McMullan
  0 siblings, 1 reply; 6+ messages in thread
From: McMullan, Jason @ 2005-05-26 12:50 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git

[-- Attachment #1: Type: text/plain, Size: 492 bytes --]

On Wed, 2005-05-25 at 21:44 -0700, Junio C Hamano wrote:
> I'd rather see the behaviour match existing commands with path
> restriction, like diff-tree, diff-cache, and diff-files.  That
> is, to take a list of paths and limit your output to those that
> match one of them.  I do not think this enhancement would
> negatively affect your stated use of getting one entry with the
> exact match.

Ok, will do.

-- 
Jason McMullan <jason.mcmullan@timesys.com>
TimeSys Corporation


[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] ls-tree matching multiple paths
  2005-05-26 12:50   ` McMullan, Jason
@ 2005-05-26 15:13     ` Jason McMullan
  2005-05-26 17:52       ` Junio C Hamano
  0 siblings, 1 reply; 6+ messages in thread
From: Jason McMullan @ 2005-05-26 15:13 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano

[-- Attachment #1: Type: text/plain, Size: 5886 bytes --]


Same as before, but can now match multiple paths.

Relies upon the name sorted order of the default git-ls-tree -r 
internals.

Signed-Off-By: Jason McMullan <jason.mcmullan@timesys.com>

diff --git a/Documentation/git-ls-tree.txt
b/Documentation/git-ls-tree.txt
--- a/Documentation/git-ls-tree.txt
+++ b/Documentation/git-ls-tree.txt
@@ -9,7 +9,7 @@ git-ls-tree - Displays a tree object in 
 
 SYNOPSIS
 --------
-'git-ls-tree' [-r] [-z] <tree-ish>
+'git-ls-tree' [-r] [-z] <tree-ish> [paths...]
 
 DESCRIPTION
 -----------
@@ -27,6 +27,11 @@ OPTIONS
 -z::
 	\0 line termination on output
 
+paths::
+	Optionally, restrict the output of git-ls-tree to specific
+	paths. Directories will only list their tree blob ids.
+	Implies -r.
+
 Output Format
 -------------
         <mode>\t	<type>\t	<object>\t	<file>
diff --git a/ls-tree.c b/ls-tree.c
--- a/ls-tree.c
+++ b/ls-tree.c
@@ -13,20 +13,79 @@ struct path_prefix {
 	const char *name;
 };
 
+#define DEBUG(fmt, ...)	
+
+static int string_path_prefix(char *buff, size_t blen, struct
path_prefix *prefix)
+{
+	int len = 0;
+	if (prefix) {
+		if (prefix->prev) {
+			len = string_path_prefix(buff,blen,prefix->prev);
+			buff += len;
+			blen -= len;
+			if (blen > 0) {
+				*buff = '/';
+				len++;
+				buff++;
+				blen--;
+			}
+		}
+		strncpy(buff,prefix->name,blen);
+		return len + strlen(prefix->name);
+	}
+
+	return 0;
+}
+
 static void print_path_prefix(struct path_prefix *prefix)
 {
 	if (prefix) {
-		if (prefix->prev)
+		if (prefix->prev) {
 			print_path_prefix(prefix->prev);
+			putchar('/');
+		}
 		fputs(prefix->name, stdout);
-		putchar('/');
 	}
 }
 
+/*
+ * return:
+ * 	-1 if prefix is *not* a subset of path
+ * 	 0 if prefix == path
+ * 	 1 if prefix is a subset of path
+ */
+static int pathcmp(const char *path, struct path_prefix *prefix)
+{
+	char buff[PATH_MAX];
+	int len,slen;
+
+	if (prefix == NULL)
+		return 1;
+
+	len = string_path_prefix(buff, sizeof buff, prefix);
+	slen = strlen(path);
+
+	if (slen < len)
+		return -1;
+
+	if (strncmp(path,buff,len) == 0) {
+		if (slen == len)
+			return 0;
+		else
+			return 1;
+	}
+
+	return -1;
+}	
+
+/*
+ * match may be NULL, or a *sorted* list of paths
+ */
 static void list_recursive(void *buffer,
 			   const char *type,
 			   unsigned long size,
-			   struct path_prefix *prefix)
+			   struct path_prefix *prefix,
+			   char **match, int matches)
 {
 	struct path_prefix this_prefix;
 	this_prefix.prev = prefix;
@@ -34,54 +93,96 @@ static void list_recursive(void *buffer,
 	if (strcmp(type, "tree"))
 		die("expected a 'tree' node");
 
+	if (matches)
+		recursive = 1;
+
 	while (size) {
 		int namelen = strlen(buffer)+1;
-		void *eltbuf;
+		void *eltbuf = NULL;
 		char elttype[20];
 		unsigned long eltsize;
 		unsigned char *sha1 = buffer + namelen;
 		char *path = strchr(buffer, ' ') + 1;
 		unsigned int mode;
+		const char *matched = NULL;
+		int mtype = -1;
+		int mindex;
 
 		if (size < namelen + 20 || sscanf(buffer, "%o", &mode) != 1)
 			die("corrupt 'tree' file");
 		buffer = sha1 + 20;
 		size -= namelen + 20;
 
-		printf("%06o\t%s\t%s\t", mode,
-		       S_ISDIR(mode) ? "tree" : "blob",
-		       sha1_to_hex(sha1));
-		print_path_prefix(prefix);
-		fputs(path, stdout);
-		putchar(line_termination);
+		this_prefix.name = path;
+		for ( mindex = 0; mindex < matches; mindex++) {
+			mtype = pathcmp(match[mindex],&this_prefix);
+			if (mtype >= 0) {
+				matched = match[mindex];
+				break;
+			}
+		}
+
+		/*
+		 * If we're not matching, or if this is an exact match,
+		 * print out the info
+		 */
+		if (!matches || (matched != NULL && mtype == 0)) {
+			printf("%06o\t%s\t%s\t", mode,
+			       S_ISDIR(mode) ? "tree" : "blob",
+			       sha1_to_hex(sha1));
+			print_path_prefix(&this_prefix);
+			putchar(line_termination);
+		}
 
 		if (! recursive || ! S_ISDIR(mode))
 			continue;
 
+		if (matches && ! matched)
+			continue;
+
 		if (! (eltbuf = read_sha1_file(sha1, elttype, &eltsize)) ) {
 			error("cannot read %s", sha1_to_hex(sha1));
 			continue;
 		}
-		this_prefix.name = path;
-		list_recursive(eltbuf, elttype, eltsize, &this_prefix);
+
+		/* If this is an exact directory match, we may have
+		 * directory files following this path. Match on them.
+		 * Otherwise, we're at a pach subcomponent, and we need
+		 * to try to match again.
+		 */
+		if (mtype == 0)
+			mindex++;
+
+		list_recursive(eltbuf, elttype, eltsize, &this_prefix,
&match[mindex], matches-mindex);
 		free(eltbuf);
 	}
 }
 
-static int list(unsigned char *sha1)
+static int qcmp(const void *a, const void *b)
+{
+	return strcmp(*(char **)a, *(char **)b);
+}
+
+static int list(unsigned char *sha1,char **path)
 {
 	void *buffer;
 	unsigned long size;
+	int npaths;
+
+	for (npaths = 0; path[npaths] != NULL; npaths++)
+		;
+
+	qsort(path,npaths,sizeof(char *),qcmp);
 
 	buffer = read_object_with_reference(sha1, "tree", &size, NULL);
 	if (!buffer)
 		die("unable to read sha1 file");
-	list_recursive(buffer, "tree", size, NULL);
+	list_recursive(buffer, "tree", size, NULL, path, npaths);
 	free(buffer);
 	return 0;
 }
 
-static const char *ls_tree_usage = "git-ls-tree [-r] [-z] <key>";
+static const char *ls_tree_usage = "git-ls-tree [-r] [-z] <key>
[paths...]";
 
 int main(int argc, char **argv)
 {
@@ -101,11 +202,11 @@ int main(int argc, char **argv)
 		argc--; argv++;
 	}
 
-	if (argc != 2)
+	if (argc < 2)
 		usage(ls_tree_usage);
 	if (get_sha1(argv[1], sha1) < 0)
 		usage(ls_tree_usage);
-	if (list(sha1) < 0)
+	if (list(sha1, &argv[2]) < 0)
 		die("list failed");
 	return 0;
 }



-- 
Jason McMullan <jason.mcmullan@timesys.com>
TimeSys Corporation


[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH] ls-tree matching multiple paths
  2005-05-26 15:13     ` [PATCH] ls-tree matching multiple paths Jason McMullan
@ 2005-05-26 17:52       ` Junio C Hamano
  2005-05-26 18:06         ` Junio C Hamano
  0 siblings, 1 reply; 6+ messages in thread
From: Junio C Hamano @ 2005-05-26 17:52 UTC (permalink / raw)
  To: Jason McMullan; +Cc: Linus Torvalds, git

Jason, could you double check your MUA setup?  The copy I got, and
the mailing list archive MARC has, both seems to have got line
wrapped.  Here is the beginning of your message cut & pasted from
http://marc.theaimsgroup.com/?l=git&m=111712054707691&w=2

    ...
    Signed-Off-By: Jason McMullan <jason.mcmullan@timesys.com>

    diff --git a/Documentation/git-ls-tree.txt
    b/Documentation/git-ls-tree.txt
    --- a/Documentation/git-ls-tree.txt
    ...

I fixed it up by hand and added a test case, which your test passes
fine.  Again, thanks for doing this.

------------
From: Jason McMullan <jason.mcmullan@timesys.com>

Enhance git-ls-tree to allow optional 'match paths' that
restricts the output of git-ls-tree.  This is useful to retrieve
a single file's SHA1 out of a tree without creating an index.

[JC: I added the test case]

Signed-off-by: Junio C Hamano <junkio@cox.net>
---

Documentation/git-ls-tree.txt |    7 +-
ls-tree.c                     |  135 ++++++++++++++++++++++++++++++++++++------
t/t3100-ls-tree-restrict.sh   |  103 ++++++++++++++++++++++++++++++++
3 files changed, 227 insertions(+), 18 deletions(-)
new file (100755): t/t3100-ls-tree-restrict.sh

diff --git a/Documentation/git-ls-tree.txt b/Documentation/git-ls-tree.txt
--- a/Documentation/git-ls-tree.txt
+++ b/Documentation/git-ls-tree.txt
@@ -9,7 +9,7 @@ git-ls-tree - Displays a tree object in 
 
 SYNOPSIS
 --------
-'git-ls-tree' [-r] [-z] <tree-ish>
+'git-ls-tree' [-r] [-z] <tree-ish> [paths...]
 
 DESCRIPTION
 -----------
@@ -27,6 +27,11 @@ OPTIONS
 -z::
 	\0 line termination on output
 
+paths::
+	Optionally, restrict the output of git-ls-tree to specific
+	paths. Directories will only list their tree blob ids.
+	Implies -r.
+
 Output Format
 -------------
         <mode>\t	<type>\t	<object>\t	<file>
diff --git a/ls-tree.c b/ls-tree.c
--- a/ls-tree.c
+++ b/ls-tree.c
@@ -13,20 +13,79 @@ struct path_prefix {
 	const char *name;
 };
 
+#define DEBUG(fmt, ...)	
+
+static int string_path_prefix(char *buff, size_t blen, struct path_prefix *prefix)
+{
+	int len = 0;
+	if (prefix) {
+		if (prefix->prev) {
+			len = string_path_prefix(buff,blen,prefix->prev);
+			buff += len;
+			blen -= len;
+			if (blen > 0) {
+				*buff = '/';
+				len++;
+				buff++;
+				blen--;
+			}
+		}
+		strncpy(buff,prefix->name,blen);
+		return len + strlen(prefix->name);
+	}
+
+	return 0;
+}
+
 static void print_path_prefix(struct path_prefix *prefix)
 {
 	if (prefix) {
-		if (prefix->prev)
+		if (prefix->prev) {
 			print_path_prefix(prefix->prev);
+			putchar('/');
+		}
 		fputs(prefix->name, stdout);
-		putchar('/');
 	}
 }
 
+/*
+ * return:
+ * 	-1 if prefix is *not* a subset of path
+ * 	 0 if prefix == path
+ * 	 1 if prefix is a subset of path
+ */
+static int pathcmp(const char *path, struct path_prefix *prefix)
+{
+	char buff[PATH_MAX];
+	int len,slen;
+
+	if (prefix == NULL)
+		return 1;
+
+	len = string_path_prefix(buff, sizeof buff, prefix);
+	slen = strlen(path);
+
+	if (slen < len)
+		return -1;
+
+	if (strncmp(path,buff,len) == 0) {
+		if (slen == len)
+			return 0;
+		else
+			return 1;
+	}
+
+	return -1;
+}	
+
+/*
+ * match may be NULL, or a *sorted* list of paths
+ */
 static void list_recursive(void *buffer,
 			   const char *type,
 			   unsigned long size,
-			   struct path_prefix *prefix)
+			   struct path_prefix *prefix,
+			   char **match, int matches)
 {
 	struct path_prefix this_prefix;
 	this_prefix.prev = prefix;
@@ -34,54 +93,96 @@ static void list_recursive(void *buffer,
 	if (strcmp(type, "tree"))
 		die("expected a 'tree' node");
 
+	if (matches)
+		recursive = 1;
+
 	while (size) {
 		int namelen = strlen(buffer)+1;
-		void *eltbuf;
+		void *eltbuf = NULL;
 		char elttype[20];
 		unsigned long eltsize;
 		unsigned char *sha1 = buffer + namelen;
 		char *path = strchr(buffer, ' ') + 1;
 		unsigned int mode;
+		const char *matched = NULL;
+		int mtype = -1;
+		int mindex;
 
 		if (size < namelen + 20 || sscanf(buffer, "%o", &mode) != 1)
 			die("corrupt 'tree' file");
 		buffer = sha1 + 20;
 		size -= namelen + 20;
 
-		printf("%06o\t%s\t%s\t", mode,
-		       S_ISDIR(mode) ? "tree" : "blob",
-		       sha1_to_hex(sha1));
-		print_path_prefix(prefix);
-		fputs(path, stdout);
-		putchar(line_termination);
+		this_prefix.name = path;
+		for ( mindex = 0; mindex < matches; mindex++) {
+			mtype = pathcmp(match[mindex],&this_prefix);
+			if (mtype >= 0) {
+				matched = match[mindex];
+				break;
+			}
+		}
+
+		/*
+		 * If we're not matching, or if this is an exact match,
+		 * print out the info
+		 */
+		if (!matches || (matched != NULL && mtype == 0)) {
+			printf("%06o\t%s\t%s\t", mode,
+			       S_ISDIR(mode) ? "tree" : "blob",
+			       sha1_to_hex(sha1));
+			print_path_prefix(&this_prefix);
+			putchar(line_termination);
+		}
 
 		if (! recursive || ! S_ISDIR(mode))
 			continue;
 
+		if (matches && ! matched)
+			continue;
+
 		if (! (eltbuf = read_sha1_file(sha1, elttype, &eltsize)) ) {
 			error("cannot read %s", sha1_to_hex(sha1));
 			continue;
 		}
-		this_prefix.name = path;
-		list_recursive(eltbuf, elttype, eltsize, &this_prefix);
+
+		/* If this is an exact directory match, we may have
+		 * directory files following this path. Match on them.
+		 * Otherwise, we're at a pach subcomponent, and we need
+		 * to try to match again.
+		 */
+		if (mtype == 0)
+			mindex++;
+
+		list_recursive(eltbuf, elttype, eltsize, &this_prefix, &match[mindex], matches-mindex);
 		free(eltbuf);
 	}
 }
 
-static int list(unsigned char *sha1)
+static int qcmp(const void *a, const void *b)
+{
+	return strcmp(*(char **)a, *(char **)b);
+}
+
+static int list(unsigned char *sha1,char **path)
 {
 	void *buffer;
 	unsigned long size;
+	int npaths;
+
+	for (npaths = 0; path[npaths] != NULL; npaths++)
+		;
+
+	qsort(path,npaths,sizeof(char *),qcmp);
 
 	buffer = read_object_with_reference(sha1, "tree", &size, NULL);
 	if (!buffer)
 		die("unable to read sha1 file");
-	list_recursive(buffer, "tree", size, NULL);
+	list_recursive(buffer, "tree", size, NULL, path, npaths);
 	free(buffer);
 	return 0;
 }
 
-static const char *ls_tree_usage = "git-ls-tree [-r] [-z] <key>";
+static const char *ls_tree_usage = "git-ls-tree [-r] [-z] <key> [paths...]";
 
 int main(int argc, char **argv)
 {
@@ -101,11 +202,11 @@ int main(int argc, char **argv)
 		argc--; argv++;
 	}
 
-	if (argc != 2)
+	if (argc < 2)
 		usage(ls_tree_usage);
 	if (get_sha1(argv[1], sha1) < 0)
 		usage(ls_tree_usage);
-	if (list(sha1) < 0)
+	if (list(sha1, &argv[2]) < 0)
 		die("list failed");
 	return 0;
 }
diff --git a/t/t3100-ls-tree-restrict.sh b/t/t3100-ls-tree-restrict.sh
new file mode 100755
--- /dev/null
+++ b/t/t3100-ls-tree-restrict.sh
@@ -0,0 +1,103 @@
+#!/bin/sh
+#
+# Copyright (c) 2005 Junio C Hamano
+#
+
+test_description='git-ls-tree test.
+
+This test runs git-ls-tree with the following in a tree.
+
+    path0       - a file
+    path1	- a symlink
+    path2/foo   - a file in a directory
+    path2/bazbo - a symlink in a directory
+    path2/baz/b - a file in a directory in a directory
+
+The new path restriction code should do the right thing for path2 and
+path2/baz
+'
+. ./test-lib.sh
+
+test_expect_success \
+    'setup' \
+    'mkdir path2 path2/baz &&
+     echo Hi >path0 &&
+     ln -s path0 path1 &&
+     echo Lo >path2/foo &&
+     ln -s ../path1 path2/bazbo &&
+     echo Mi >path2/baz/b &&
+     find path? \( -type f -o -type l \) -print |
+     xargs git-update-cache --add &&
+     tree=`git-write-tree` &&
+     echo $tree'
+
+_x40='[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]'
+_x40="$_x40$_x40$_x40$_x40$_x40$_x40$_x40$_x40"
+test_output () {
+    sed -e "s/	$_x40	/	X	/" <current >check
+    diff -u expected check
+}
+
+test_expect_success \
+    'ls-tree plain' \
+    'git-ls-tree $tree >current &&
+     cat >expected <<\EOF &&
+100644	blob	X	path0
+120000	blob	X	path1
+040000	tree	X	path2
+EOF
+     test_output'
+
+test_expect_success \
+    'ls-tree recursive' \
+    'git-ls-tree -r $tree >current &&
+     cat >expected <<\EOF &&
+100644	blob	X	path0
+120000	blob	X	path1
+040000	tree	X	path2
+040000	tree	X	path2/baz
+100644	blob	X	path2/baz/b
+120000	blob	X	path2/bazbo
+100644	blob	X	path2/foo
+EOF
+     test_output'
+
+test_expect_success \
+    'ls-tree filtered' \
+    'git-ls-tree $tree path >current &&
+     cat >expected <<\EOF &&
+EOF
+     test_output'
+
+
+test_expect_success \
+    'ls-tree filtered' \
+    'git-ls-tree $tree path1 path0 >current &&
+     cat >expected <<\EOF &&
+100644	blob	X	path0
+120000	blob	X	path1
+EOF
+     test_output'
+
+test_expect_success \
+    'ls-tree filtered' \
+    'git-ls-tree $tree path2 >current &&
+     cat >expected <<\EOF &&
+040000	tree	X	path2
+040000	tree	X	path2/baz
+100644	blob	X	path2/baz/b
+120000	blob	X	path2/bazbo
+100644	blob	X	path2/foo
+EOF
+     test_output'
+
+test_expect_success \
+    'ls-tree filtered' \
+    'git-ls-tree $tree path2/baz >current &&
+     cat >expected <<\EOF &&
+040000	tree	X	path2/baz
+100644	blob	X	path2/baz/b
+EOF
+     test_output'
+
+test_done


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] ls-tree matching multiple paths
  2005-05-26 17:52       ` Junio C Hamano
@ 2005-05-26 18:06         ` Junio C Hamano
  0 siblings, 0 replies; 6+ messages in thread
From: Junio C Hamano @ 2005-05-26 18:06 UTC (permalink / raw)
  To: Jason McMullan; +Cc: Linus Torvalds, git

>>>>> "JCH" == Junio C Hamano <junkio@cox.net> writes:

JCH> +040000	tree	X	path2/baz
JCH> +100644	blob	X	path2/baz/b

Side note.  Linus, don't you think it would make more sense to
change the column separator befor type and SHA1 from TAB to SP?
We should keep the one before the path to TAB for easier
splitting with cut (which defaults to a TAB).  This comes from
the same reasoning as the latest diff-raw format design we did.

While we are at it, we may want to do the same to ls-files,
which does not use TAB for inter_name_termination (it uses SP
for everything).


^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2005-05-26 18:05 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-05-26  3:47 [PATCH] ls-tree matching a prefix Jason McMullan
2005-05-26  4:44 ` Junio C Hamano
2005-05-26 12:50   ` McMullan, Jason
2005-05-26 15:13     ` [PATCH] ls-tree matching multiple paths Jason McMullan
2005-05-26 17:52       ` Junio C Hamano
2005-05-26 18:06         ` Junio C Hamano

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).