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

[PATCH] ls-tree path restriction semantics fixes

From
JMJason McMullan <jason.mcmullan@timesys.com>
Date
May 27, 2005, 12:08 UTC
Message-ID
<20050527120851.GA11823@port.evillabs.net>
This patch fixes the git-ls-tree semantics to be less stupid, namely:
	
	* ls of a 'tree' path should just return the SHA1 of the tree
	* ls of a 'tree' path with a trailing '/' should work properly
	* ls of two identical paths should have the same output as ls of
	  a single path. (I consider ls-tree's output to be a hash dictionary)
Also, I added test cases to verify that these issues are fixed.
Old Results:
	$ git-ls-tree t
	040000 tree 4eeb3990955b8badc4c14712b89d8cd9fff02f15    t
	100644 blob 6882e23be568ccf14f3adb0c766139086f2ee952    t/Makefile
	100644 blob 2a94fdb0b83ab5fcbf1a2c6edaf36c2dbe765ec6    t/README
	100644 blob d920c6b3a3bfbb5994244a78d1ad99ce02748122    t/lib-read-tree-m-3way.sh
	...
	$ git-ls-tree t/
	(no output)
	$ git-ls-tree t t
	040000 tree 4eeb3990955b8badc4c14712b89d8cd9fff02f15    t
New Results:
	$ git-ls-tree f
	040000 tree 4eeb3990955b8badc4c14712b89d8cd9fff02f15    t
	$ git-ls-tree t/
	040000 tree 4eeb3990955b8badc4c14712b89d8cd9fff02f15    t
	$ git-ls-tree t t
	040000 tree 4eeb3990955b8badc4c14712b89d8cd9fff02f15    t
Signed-Off-By: Jason McMullan <jason.mcmullan@timesys.com>
diff --git a/ls-tree.c b/ls-tree.c
--- a/ls-tree.c
+++ b/ls-tree.c
@@ -13,8 +13,6 @@ 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;
@@ -118,6 +116,8 @@ static void list_recursive(void *buffer,
 			mtype = pathcmp(match[mindex],&this_prefix);
 			if (mtype >= 0) {
 				matched = match[mindex];
+				/* Skip over any duplicates */
+				for (; mindex+1 < matches && strcmp(match[mindex+1],matched)==0; mindex++);
 				break;
 			}
 		}
@@ -140,19 +140,22 @@ static void list_recursive(void *buffer,
 		if (matches && ! matched)
 			continue;
 
-		if (! (eltbuf = read_sha1_file(sha1, elttype, &eltsize)) ) {
-			error("cannot read %s", sha1_to_hex(sha1));
-			continue;
-		}
-
 		/* 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
+		 * Otherwise, we're at a path subcomponent, and we need
 		 * to try to match again.
 		 */
 		if (mtype == 0)
 			mindex++;
 
+		if (matched && matches-mindex==0)
+			continue;
+
+		if (! (eltbuf = read_sha1_file(sha1, elttype, &eltsize)) ) {
+			error("cannot read %s", sha1_to_hex(sha1));
+			continue;
+		}
+
 		list_recursive(eltbuf, elttype, eltsize, &this_prefix, &match[mindex], matches-mindex);
 		free(eltbuf);
 	}
@@ -169,9 +172,14 @@ static int list(unsigned char *sha1,char
 	unsigned long size;
 	int npaths;
 
-	for (npaths = 0; path[npaths] != NULL; npaths++)
-		;
+	/* Count the paths, and any trailling '/' */
+	for (npaths = 0; path[npaths] != NULL; npaths++) {
+		char *cp = strrchr(path[npaths],'/');
+		if (cp != NULL && *(cp+1) == 0)
+			*cp=0;
+	}	
 
+	/* Sort the paths */
 	qsort(path,npaths,sizeof(char *),qcmp);
 
 	buffer = read_object_with_reference(sha1, "tree", &size, NULL);
diff --git a/t/t3100-ls-tree-restrict.sh b/t/t3100-ls-tree-restrict.sh
--- a/t/t3100-ls-tree-restrict.sh
+++ b/t/t3100-ls-tree-restrict.sh
@@ -84,10 +84,22 @@ test_expect_success \
     '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/ >current &&
+     cat >expected <<\EOF &&
+040000 tree X	path2
+EOF
+     test_output'
+
+test_expect_success \
+    'ls-tree filtered' \
+    'git-ls-tree $tree path2 path2 >current &&
+     cat >expected <<\EOF &&
+040000 tree X	path2
 EOF
      test_output'
 
@@ -96,7 +108,16 @@ test_expect_success \
     '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_expect_success \
+    'ls-tree filtered' \
+    'git-ls-tree $tree path2 path2/bazbo path2/baz >current &&
+     cat >expected <<\EOF &&
+040000 tree X	path2
+040000 tree X	path2/baz
+120000 blob X	path2/bazbo
 EOF
      test_output'
 
Next: Junio C Hamano
Message 1 of 7 in “ls-tree path restriction semantics fixes”
  1. ls-tree path restriction semantics fixesJason McMullan, May 27, 2005
  2. Junio C HamanoMay 27, 2005
  3. Jason McMullanMay 27, 2005
  4. Junio C HamanoMay 28, 2005
  5. Rewrite ls-tree to behave more like "/bin/ls -a"Junio C Hamano, May 28, 2005
  6. Jason McMullanMay 28, 2005
  7. Junio C HamanoMay 29, 2005

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.