dir.c: make 'git-status --ignored' work within leading directories

'git-status --ignored path/' doesn't list ignored files and directories within 'path' if some component of 'path' is classified as untracked. Disable the DIR_SHOW_OTHER_DIRECTORIES flag while traversing leading directories. This prevents treat_leading_path() with DIR_SHOW_IGNORED flag from aborting at the top level untracked directory. As a side effect, this also eliminates a recursive directory scan per leading directory level, as treat_directory() can no longer call read_directory_recursive() when called from treat_leading_path(). Signed-off-by: Karsten Blees <blees@dcon.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Karsten Blees committed Apr 15, 2013 at 21:09 UTC be8a84c526691667fc04a8241d93a3de1de298ab
2 files changed +22
dir.c
+3
@@ -1447,12 +1447,14 @@ static int treat_leading_path(struct dir_struct *dir,
1447 struct strbuf sb = STRBUF_INIT;
1448 int baselen, rc = 0;
1449 const char *cp;
1450 + int old_flags = dir->flags;
1451
1452 while (len && path[len - 1] == '/')
1453 len--;
1454 if (!len)
1455 return 1;
1456 baselen = 0;
1457 + dir->flags &= ~DIR_SHOW_OTHER_DIRECTORIES;
1458 while (1) {
1459 cp = path + baselen + !!baselen;
1460 cp = memchr(cp, '/', path + len - cp);
@@ -1475,6 +1477,7 @@ static int treat_leading_path(struct dir_struct *dir,
1477 }
1478 }
1479 strbuf_release(&sb);
1480 + dir->flags = old_flags;
1481 return rc;
1482 }
1483
t/t7061-wtstatus-ignore.sh
+19
@@ -32,6 +32,25 @@ test_expect_success 'status untracked directory with --ignored -u' '
32 git status --porcelain --ignored -u >actual &&
33 test_cmp expected actual
34 '
35 +cat >expected <<\EOF
36 +?? untracked/uncommitted
37 +!! untracked/ignored
38 +EOF
39 +
40 +test_expect_success 'status prefixed untracked directory with --ignored' '
41 + git status --porcelain --ignored untracked/ >actual &&
42 + test_cmp expected actual
43 +'
44 +
45 +cat >expected <<\EOF
46 +?? untracked/uncommitted
47 +!! untracked/ignored
48 +EOF
49 +
50 +test_expect_success 'status prefixed untracked sub-directory with --ignored -u' '
51 + git status --porcelain --ignored -u untracked/ >actual &&
52 + test_cmp expected actual
53 +'
54
55 cat >expected <<\EOF
56 ?? .gitignore