threads / discuss / 2966

git-ls-files -o no recurse?

Subject: git-ls-files -o no recurse?

## tl;dr

9 messages between Jan 4, 2006 and Jan 7, 2006.

replies: 8people: 3as markdown or json

Darrin Thompson· Jan 4, 2006, 18:51 UTC · lore

git-ls-files -o reports _all_ the unknown files it finds in a work area. Subversion and probably other systems "simply ignore all the files and directories inside an unknown directory and just note the directory as unknown." (A quote from my porcelain's mailing list.)

I'd like to make this friendly behavior the default in my porcelain. Unfortunately, getting the same result from a porcelain requires implementing a non-trivial algorithm to discover common prefixes, worry about performance on large projects, etc.

Would it be hard to make git-ls-files optionally do this?

-- Darrin

Linus Torvalds· Jan 4, 2006, 21:31 UTC · re: Darrin Thompson · lore

Re: git-ls-files -o no recurse?

On Wed, 4 Jan 2006, Darrin Thompson wrote:
> 
> Would it be hard to make git-ls-files optionally do this?
Something like the appended may or may not be what you're looking for..
		Linus
---
diff --git a/ls-files.c b/ls-files.c
index 5e9ac71..2e3e2e8 100644
--- a/ls-files.c
+++ b/ls-files.c
@@ -19,6 +19,7 @@ static int show_stage = 0;
 static int show_unmerged = 0;
 static int show_modified = 0;
 static int show_killed = 0;
+static int show_ignored_directories = 0;
 static int line_terminator = '\n';
 
 static int prefix_len = 0, prefix_offset = 0;
@@ -233,6 +234,19 @@ static void add_name(const char *pathnam
 	dir[nr_dir++] = ent;
 }
 
+static int dir_exists(const char *dirname, int len)
+{
+	int pos = cache_name_pos(dirname, len);
+	if (pos >= 0)
+		return 1;
+	pos = -pos-1;
+	if (pos >= active_nr)
+		return 0;
+	if (strncmp(active_cache[pos]->name, dirname, len))
+		return 0;
+	return active_cache[pos]->name[len] == '/';
+}
+
 /*
  * Read a directory tree. We currently ignore anything but
  * directories, regular files and symlinks. That's because git
@@ -280,6 +294,10 @@ static void read_directory(const char *p
 					continue;
 				/* fallthrough */
 			case DT_DIR:
+				if (show_ignored_directories) {
+					if (!dir_exists(fullname, baselen + len))
+						break;
+				}
 				memcpy(fullname + baselen + len, "/", 2);
 				read_directory(fullname, fullname,
 					       baselen + len + 1);
@@ -622,6 +640,10 @@ int main(int argc, const char **argv)
 			show_killed = 1;
 			continue;
 		}
+		if (!strcmp(arg, "--directory")) {
+			show_ignored_directories = 1;
+			continue;
+		}
 		if (!strcmp(arg, "-u") || !strcmp(arg, "--unmerged")) {
 			/* There's no point in showing unmerged unless
 			 * you also show the stage information.
Darrin Thompson· Jan 5, 2006, 17:15 UTC · re: Linus Torvalds · lore

Re: git-ls-files -o no recurse?

On Wed, 2006-01-04 at 13:31 -0800, Linus Torvalds wrote:
Show 7 quoted lines
> 
> On Wed, 4 Jan 2006, Darrin Thompson wrote:
> > 
> > Would it be hard to make git-ls-files optionally do this?
> 
> Something like the appended may or may not be what you're looking for..
> 
Worked great!
Show 6 quoted lines
> @@ -19,6 +19,7 @@ static int show_stage = 0;
>  static int show_unmerged = 0;
>  static int show_modified = 0;
>  static int show_killed = 0;
> +static int show_ignored_directories = 0;
>  static int line_terminator = '\n';

Did you perhaps mean s/ignored/other/g ? I thought maybe you were being clever but I couldn't get it to do anything useful with -i, only -o.

-- Darrin

Linus Torvalds· Jan 5, 2006, 17:31 UTC · re: Darrin Thompson · lore

Re: git-ls-files -o no recurse?

On Thu, 5 Jan 2006, Darrin Thompson wrote:
> 
> Worked great!

Ok. You can bug Junio about it when he returns, maybe he thinks it's a great feature.

> > +static int show_ignored_directories = 0;
> 
> Did you perhaps mean s/ignored/other/g ? I thought maybe you were being
> clever but I couldn't get it to do anything useful with -i, only -o.
Yeah. 
		Linus
Junio C Hamano· Jan 6, 2006, 22:38 UTC · re: Linus Torvalds · lore

Re: git-ls-files -o no recurse?

Linus Torvalds <torvalds@osdl.org> writes:
Show 7 quoted lines
> On Wed, 4 Jan 2006, Darrin Thompson wrote:
>> 
>> Would it be hard to make git-ls-files optionally do this?
>
> Something like the appended may or may not be what you're looking for..
>
> 		Linus

Not to mention test scripts, I suspect that making this the default would break existing callers including the famous "git-init-db && git-add ." pattern. The other commonplace use is git-status, which might benefit from this option. If we are going to use it in git-status, we may want to give them trailing slashes to make them stand out, though.

Darrin Thompson· Jan 7, 2006, 18:20 UTC · re: Junio C Hamano · lore

Re: git-ls-files -o no recurse?

This adds a test a test for the --directory option to git-ls-files.
Is '--directory' really what we want?
 t/t3003-ls-files-others-directory.sh |   38
++++++++++++++++++++++++++++++++++
 1 files changed, 38 insertions(+), 0 deletions(-)
 create mode 100644 t/t3003-ls-files-others-directory.sh

applies-to: 5001806332081159b00c35291d6aea232ed7e909 d484a8477d430a5fb2cefd2cf7008a5973d1fea5

diff --git a/t/t3003-ls-files-others-directory.sh
b/t/t3003-ls-files-others-directory.sh
new file mode 100644
index 0000000..d1d3d86
--- /dev/null
+++ b/t/t3003-ls-files-others-directory.sh
@@ -0,0 +1,38 @@
+#!/bin/sh
+#
+# Copyright (c) 2005 Darrin Thompson
+# Based on an earlier test by Junio C Hamano
+#
+
+test_description='git-ls-files test (--others --directory)
+
+This test runs git-ls-files --others --directory with the following on
+the filesystem.
+
+    path0       - a file
+    path1	- a symlink
+    path2/file2 - a file in a directory
+
+The --directory option should cause path2 to be in the listing, but
+not path2/file2.
+'
+. ./test-lib.sh
+
+date >path0
+ln -s xyzzy path1
+mkdir path2
+date >path2/file2
+test_expect_success \
+    'git-ls-files --directory --others to show output.' \
+    'git-ls-files --directory --others >output'
+cat >expected <<EOF
+output
+path0
+path1
+path2
+EOF
+
+test_expect_success \
+    'git-ls-files --directory --others should not pick up dir
contents.' \
+    'diff output expected'
+test_done
---
0.99.9i
Darrin Thompson· Jan 7, 2006, 18:23 UTC · re: Junio C Hamano · lore

Re: git-ls-files -o no recurse?

Here's a rejiggered version of the original Linus patch. The names have been changed a little.

Enjoy.

It prevents git from recursing into "other" directories when used with the -o option.

---
 ls-files.c |   22 ++++++++++++++++++++++
 1 files changed, 22 insertions(+), 0 deletions(-)

applies-to: 4e7e791ecc24975530de1f2855cf5f17f112140b 741ec8ad5b7f3717bb462c2becfd00974da7ec16

diff --git a/ls-files.c b/ls-files.c
index 5e9ac71..cba8ca1 100644
--- a/ls-files.c
+++ b/ls-files.c
@@ -19,6 +19,7 @@ static int show_stage = 0;
 static int show_unmerged = 0;
 static int show_modified = 0;
 static int show_killed = 0;
+static int show_other_directories = 0;
 static int line_terminator = '\n';
 
 static int prefix_len = 0, prefix_offset = 0;
@@ -233,6 +234,19 @@ static void add_name(const char *pathnam
 	dir[nr_dir++] = ent;
 }
 
+static int dir_exists(const char *dirname, int len)
+{
+	int pos = cache_name_pos(dirname, len);
+	if (pos >= 0)
+		return 1;
+	pos = -pos-1;
+	if (pos >= active_nr)
+		return 0;
+	if (strncmp(active_cache[pos]->name, dirname, len))
+		return 0;
+	return active_cache[pos]->name[len] == '/';
+}
+
 /*
  * Read a directory tree. We currently ignore anything but
  * directories, regular files and symlinks. That's because git
@@ -280,6 +294,10 @@ static void read_directory(const char *p
 					continue;
 				/* fallthrough */
 			case DT_DIR:
+				if (show_other_directories) {
+					if (!dir_exists(fullname, baselen + len))
+						break;
+				}
 				memcpy(fullname + baselen + len, "/", 2);
 				read_directory(fullname, fullname,
 					       baselen + len + 1);
@@ -622,6 +640,10 @@ int main(int argc, const char **argv)
 			show_killed = 1;
 			continue;
 		}
+		if (!strcmp(arg, "--directory")) {
+			show_other_directories = 1;
+			continue;
+		}
 		if (!strcmp(arg, "-u") || !strcmp(arg, "--unmerged")) {
 			/* There's no point in showing unmerged unless
 			 * you also show the stage information.
---
0.99.9i
Junio C Hamano· Jan 7, 2006, 18:45 UTC · re: Darrin Thompson · lore

Re: git-ls-files -o no recurse?

Darrin Thompson <darrint@progeny.com> writes:
Show 7 quoted lines
> Here's a rejiggered version of the original Linus patch. The names have
> been changed a little.
>
> Enjoy.
>
> It prevents git from recursing into "other" directories when used with
> the -o option.

Looks same to what I have in the proposed updates branch, so we are on the same page. Thanks.

I have been unsure about the name "--directory", like you said. The most accurate one I thought of so far is:

  --dont-recurse-into-directories-without-tracked-files

but it is way too long. We cannot even say "untracked directories" (we do not track directories) to shorten it a bit.

Linus Torvalds· Jan 7, 2006, 19:34 UTC · re: Junio C Hamano · lore

Re: git-ls-files -o no recurse?

On Sat, 7 Jan 2006, Junio C Hamano wrote:
> 
> I have been unsure about the name "--directory", like you said.

Well, I didn't like "--directory" either, but couldn't come up with anything better. How about just "--no-recurse", which is not technically accurate (we always recurse into directories we know about), but might be more understandable.

The reason I called it "--directory" was that it would talk about directories that it doesn't know about (as opposed to individual files it doesn't know about). So "--other --directory" kind of makes sense if you read it that way ("show files and directories we don't know about").

But yeah, it's not a great name.
		Linus

← back to recent threads