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

Re: [PATCH 6/8] ls-tree: work from subdirectory.

From
Linus Torvalds <torvalds@osdl.org>
Date
Nov 28, 2005, 06:48 UTC
Message-ID
<Pine.LNX.4.64.0511272219420.13959@g5.osdl.org>
In-Reply-To
<7vpsol1ett.fsf@assigned-by-dhcp.cox.net>
On Sun, 27 Nov 2005, Junio C Hamano wrote:
> 
> So it probably is safer to default ls_options to LS_RECURSIVE,
> and use "-d" to restrict it not to recurse.
I have a patch that solves all the problems, I think.

It modifies the selection a bit, so that a pathspec that is a superset of a particular tree path will always cause it to recurse into that tree.

As an example, let's say that we do
	git-ls-tree HEAD drivers/char

_without_ the "-r". What will happen is that it will start out doing all the base tree, and for "drivers" it will notice that it's a proper subset of "drivers/char", so it will always recurse into _that_ tree (but not into other trees).

Then, it will not match anything else than "char" in that subdirectory, and because that's not a proper superset (it's an exact match), it will _not_ recurse into it, so you get:

	[torvalds@g5 linux]$ ~/git/git-ls-tree HEAD drivers/char
	040000 tree 9568cda453aae205bb58983747fa73b9696d9d51    drivers/char
which is what you got with the old git-ls-tree too.

But interestingly, if you add the slash, it will become a proper superset and it will recurse into _that_ subdirectory (but no deeper: so if you want all subdirectories _below_ drivers/char/, you still need to give "-r"):

	[torvalds@g5 linux]$ ~/git/git-ls-tree HEAD drivers/char/
	100644 blob 2b6b1d772ed776fff87927fc34adc2e40500218e    drivers/char/.gitignore
	100644 blob 56b8a2e76ab10a5c21787cb7068a846075cbaffd    drivers/char/ChangeLog
	100644 blob 970f70d498f4c814e1cf3362e33d7e23ac53c299    drivers/char/Kconfig
	...

See? This is on top of the previous two diffs, holler if you want a whole new "everything combined" version..

It hasn't gotten lots of testing, but it should work.

BTW! It fails a few of the tests, but it does so because now, with "-r", it will never show the tree entries, and because of the difference between

	git-ls-tree $tree path
and
	git-ls-tree $tree path/

that it didn't use to have (oh, and if you give multiple paths, it will now always consider them a "union pathspec", not an "iteration of paths"). But I _think_ the new behaviour is pretty useful and while not the same as "ls", it's perhaps still intuitive enough..

		Linus
---
diff --git a/ls-tree.c b/ls-tree.c
index cf0dbbc..4df5830 100644
--- a/ls-tree.c
+++ b/ls-tree.c
@@ -11,7 +11,8 @@
 static int line_termination = '\n';
 #define LS_RECURSIVE 1
 #define LS_TREE_ONLY 2
-static int ls_options = LS_RECURSIVE;
+static int ls_options = 0;
+const char **pathspec;
 
 static const char ls_tree_usage[] =
 	"git-ls-tree [-d] [-r] [-z] <tree-ish> [path...]";
@@ -21,8 +22,29 @@ static int show_tree(unsigned char *sha1
 	const char *type = "blob";
 
 	if (S_ISDIR(mode)) {
+		const char **s;
 		if (ls_options & LS_RECURSIVE)
 			return READ_TREE_RECURSIVE;
+		s = pathspec;
+		if (s) {
+			for (;;) {
+				const char *spec = *s++;
+				int len, speclen;
+
+				if (!spec)
+					break;
+				if (strncmp(base, spec, baselen))
+					continue;
+				len = strlen(pathname);
+				spec += baselen;
+				speclen = strlen(spec);
+				if (speclen <= len)
+					continue;
+				if (memcmp(pathname, spec, len))
+					continue;
+				return READ_TREE_RECURSIVE;
+			}
+		}
 		type = "tree";
 	}
 
@@ -32,7 +54,7 @@ static int show_tree(unsigned char *sha1
 
 int main(int argc, const char **argv)
 {
-	const char **path, *prefix;
+	const char *prefix;
 	unsigned char sha1[20];
 	char *buf;
 	unsigned long size;
@@ -60,11 +82,11 @@ int main(int argc, const char **argv)
 	if (get_sha1(argv[1], sha1) < 0)
 		usage(ls_tree_usage);
 
-	path = get_pathspec(prefix, argv + 2);
+	pathspec = get_pathspec(prefix, argv + 2);
 	buf = read_object_with_reference(sha1, "tree", &size, NULL);
 	if (!buf)
 		die("not a tree object");
-	read_tree_recursive(buf, size, "", 0, 0, path, show_tree);
+	read_tree_recursive(buf, size, "", 0, 0, pathspec, show_tree);
 
 	return 0;
 }
Previous: Junio C HamanoNext: Junio C Hamano
Message 39 of 62 in “Get rid of .git/branches/ and .git/remotes/?”
  1. Johannes SchindelinNov 20, 2005
  2. Linus TorvaldsNov 20, 2005
  3. Sven VerdoolaegeNov 20, 2005
  4. Linus TorvaldsNov 20, 2005
  5. Andreas EricssonNov 20, 2005
  6. Johannes SchindelinNov 20, 2005
  7. Petr BaudisNov 26, 2005
  8. Junio C HamanoNov 27, 2005
  9. Josef WeidendorferNov 20, 2005
  10. Johannes SchindelinNov 20, 2005
  11. Josef WeidendorferNov 22, 2005
  12. Johannes SchindelinNov 22, 2005
  13. Andreas EricssonNov 22, 2005
  14. Johannes SchindelinNov 23, 2005
  15. Junio C HamanoNov 23, 2005
  16. Andreas EricssonNov 23, 2005
  17. Johannes SchindelinNov 23, 2005
  18. Andreas EricssonNov 24, 2005
  19. Junio C HamanoNov 24, 2005
  20. Rename git-config-set to git-repo-configJohannes Schindelin, Nov 24, 2005
  21. Junio C HamanoNov 24, 2005
  22. Johannes SchindelinNov 24, 2005
  23. Junio C HamanoNov 24, 2005
  24. Johannes SchindelinNov 24, 2005
  25. Junio C HamanoNov 26, 2005
  26. Linus TorvaldsNov 26, 2005
  27. Linus TorvaldsNov 26, 2005
  28. 0/8 Make C-level operable from subdirectoriesJunio C Hamano, Nov 26, 2005
  29. Junio C HamanoNov 26, 2005
  30. Ryan AndersonNov 26, 2005
  31. Junio C HamanoNov 27, 2005
  32. Petr BaudisNov 27, 2005
  33. Linus TorvaldsNov 27, 2005
  34. Petr BaudisNov 27, 2005
  35. Linus TorvaldsNov 27, 2005
  36. Junio C HamanoNov 28, 2005
  37. Linus TorvaldsNov 28, 2005
  38. Junio C HamanoNov 28, 2005
  39. Linus TorvaldsNov 28, 2005
  40. Junio C HamanoNov 28, 2005
  41. Junio C HamanoNov 28, 2005
  42. ls-tree: Resurrect funny name quoting lost during rewrite.Junio C Hamano, Nov 28, 2005
  43. Junio C HamanoNov 26, 2005
  44. 1/8 git-apply: work from subdirectory.Junio C Hamano, Nov 26, 2005
  45. Linus TorvaldsNov 26, 2005
  46. Junio C HamanoNov 26, 2005
  47. Junio C HamanoNov 27, 2005
  48. Lars Magne IngebrigtsenNov 27, 2005
  49. 2/8 peek-remote: honor proxy config even from subdirectory.Junio C Hamano, Nov 26, 2005
  50. 3/8 fsck-objects: work from subdirectory.Junio C Hamano, Nov 26, 2005
  51. 4/8 checkout-index: work from subdirectory.Junio C Hamano, Nov 26, 2005
  52. 5/8 hash-object: work within subdirectory.Junio C Hamano, Nov 26, 2005
  53. 6/8 ls-tree: work from subdirectory.Junio C Hamano, Nov 26, 2005
  54. Linus TorvaldsNov 26, 2005
  55. 7/8 Make networking commands to work from a subdirectory.Junio C Hamano, Nov 26, 2005
  56. 8/8 Make the rest of commands work from a subdirectory.Junio C Hamano, Nov 26, 2005
  57. Josef WeidendorferNov 22, 2005
  58. Johannes SchindelinNov 23, 2005
  59. Josef WeidendorferNov 23, 2005
  60. Johannes SchindelinNov 23, 2005
  61. Lars Magne IngebrigtsenNov 27, 2005
  62. Junio C HamanoNov 27, 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.