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

git-ls-tree: add "-t" option to always show the tree entries

From
Linus Torvalds <torvalds@osdl.org>
Date
Dec 1, 2005, 18:35 UTC
Message-ID
<Pine.LNX.4.64.0512011022520.3099@g5.osdl.org>
In-Reply-To
<20051201085433.GA7866@c165.ib.student.liu.se>

The old (new) behaviour was that it only shows trees if the object is specified exactly, and recursive is not set. That makes sense, because there is obviously nothing else it can show for that case.

However, with the new "-t" option, it will show the tree even with "-r", as it traverses down into it.

NOTE! This also means that it will show all trees leading up to that tree. 
For example, if you do a
	git-ls-tree -t HEAD -- drivers/char/this/file/does/not/exist
it will show the trees that lead up to the files that do not exist:
	[torvalds@g5 linux]$ git-ls-tree -t HEAD -- drivers/char/this/file/does/not/exist
	040000 tree 9cb687b77dcd64bf82e9a73214db467c964c1266    drivers
	040000 tree 298e2fadf0ff3867d1ef49936fd2c7bf6ce1eb66    drivers/char
	[torvalds@g5 linux]$

and note how this is true even though I didn't specify "-r": the fact that I supplied a pathspec automatically implies "enough recursion" for that particular pathspec.

I think the code is cleaner and easier to understand too: the patch looks bigger, but it's really just splitting up the "should we recurse into this tree" into a function of its own.

Signed-off-by: Linus Torvalds <torvalds@osdl.org>
----

This obviously means that to fix merge-recursive, we should add that "-t" flag to it, but then hopefully everything should be ok? Do you have a test-case, and perhaps something we could add to "make test".

Talking about "make test", this doesn't break any (since it doesn't change behaviour without the "-t" flag), but maybe it should add some. But I'm lazy.

On Thu, 1 Dec 2005, Fredrik Kuivinen wrote:
Show 9 quoted lines
> 
> It turns out that this change breaks the directory/file conflict
> handling in git-merge-recursive. Right now merge-recursive uses
> 
>    git-ls-tree -r -z <tree SHA1>
> 
> to get a listing of every blob object (which corresponds to files) and
> every tree object (which corresponds to directories) in the tree
> designated by the SHA1.
diff --git a/ls-tree.c b/ls-tree.c
index d4b6219..a2a5eb0 100644
--- a/ls-tree.c
+++ b/ls-tree.c
@@ -11,39 +11,53 @@
 static int line_termination = '\n';
 #define LS_RECURSIVE 1
 #define LS_TREE_ONLY 2
+#define LS_SHOW_TREES 4
 static int ls_options = 0;
 const char **pathspec;
 
 static const char ls_tree_usage[] =
-	"git-ls-tree [-d] [-r] [-z] <tree-ish> [path...]";
+	"git-ls-tree [-d] [-r] [-t] [-z] <tree-ish> [path...]";
+
+static int show_recursive(const char *base, int baselen, const char *pathname)
+{
+	const char **s;
+
+	if (ls_options & LS_RECURSIVE)
+		return 1;
+
+	s = pathspec;
+	if (!s)
+		return 0;
+
+	for (;;) {
+		const char *spec = *s++;
+		int len, speclen;
+
+		if (!spec)
+			return 0;
+		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 1;
+	}
+}
 
 static int show_tree(unsigned char *sha1, const char *base, int baselen, const char *pathname, unsigned mode, int stage)
 {
+	int retval = 0;
 	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;
-			}
+		if (show_recursive(base, baselen, pathname)) {
+			retval = READ_TREE_RECURSIVE;
+			if (!(ls_options & LS_SHOW_TREES))
+				return retval;
 		}
 		type = "tree";
 	}
@@ -51,7 +65,7 @@ static int show_tree(unsigned char *sha1
 	printf("%06o %s %s\t", mode, type, sha1_to_hex(sha1));
 	write_name_quoted(base, baselen, pathname, line_termination, stdout);
 	putchar(line_termination);
-	return 0;
+	return retval;
 }
 
 int main(int argc, const char **argv)
@@ -73,6 +87,9 @@ int main(int argc, const char **argv)
 		case 'd':
 			ls_options |= LS_TREE_ONLY;
 			break;
+		case 't':
+			ls_options |= LS_SHOW_TREES;
+			break;
 		default:
 			usage(ls_tree_usage);
 		}
Previous: Junio C HamanoNext: Junio C Hamano
Message 9 of 15 in “What's new in git.git master branch”
  1. Junio C HamanoNov 30, 2005
  2. Fredrik KuivinenDec 1, 2005
  3. Junio C HamanoDec 1, 2005
  4. Junio C HamanoDec 2, 2005
  5. Junio C HamanoDec 2, 2005
  6. Fredrik KuivinenDec 2, 2005
  7. Fredrik KuivinenDec 2, 2005
  8. 3/3 update-index: allow --index-info to add higher stages.Junio C Hamano, Dec 7, 2005
  9. git-ls-tree: add "-t" option to always show the tree entriesLinus Torvalds, Dec 1, 2005
  10. Junio C HamanoDec 1, 2005
  11. Linus TorvaldsDec 1, 2005
  12. Junio C HamanoDec 1, 2005
  13. ls-tree: --name-onlyJunio C Hamano, Dec 1, 2005
  14. Junio C HamanoDec 2, 2005
  15. Linus TorvaldsDec 2, 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.