Skip to content

Commit

Permalink
git-ls-tree: add "-t" option to always show the tree entries
Browse files Browse the repository at this point in the history
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>
Signed-off-by: Junio C Hamano <junkio@cox.net>
  • Loading branch information
Linus Torvalds authored and Junio C Hamano committed Dec 1, 2005
1 parent 2731d04 commit 0f8f45c
Showing 1 changed file with 41 additions and 24 deletions.
65 changes: 41 additions & 24 deletions ls-tree.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,47 +11,61 @@
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";
}

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)
Expand All @@ -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);
}
Expand Down

0 comments on commit 0f8f45c

Please sign in to comment.