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

[PATCH 2/2] dir: avoid prematurely marking nonbare repositories as matches

From
Elijah Newren via GitGitGadget <gitgitgadget@gmail.com>
Date
Aug 12, 2020, 07:12 UTC
Message-ID
<11a286b071ca8a6b96f4fba6658e9bafb9314be4.1597216356.git.gitgitgadget@gmail.com>
In-Reply-To
<pull.829.git.git.1597216356.gitgitgadget@gmail.com>
From: Elijah Newren <newren@gmail.com>

Nonbare repositories are special directories. Unlike normal directories that we might recurse into to list the files they contain, nonbare repositories must themselves match and then we always report only on the nonbare repository directory itself and not on any of its contents.

Separately, when traversing directories to try to find untracked or excluded files, we often think in terms of paths either matching the specified pathspec, or not matching them. However, there is a special value that do_match_pathspec() uses named MATCHED_RECURSIVELY_LEADING_PATHSPEC which means "this directory does not match any pathspec BUT it is possible a file or directory underneath it does." That special value prevents us from prematurely thinking that some directory and everything under it is irrelevant, but also allows us to differentiate from "this is a match".

The combination of these two special cases was previously uncovered. Add a test to the testsuite to cover it, and make sure that we return a nonbare repository as a non-match if the best match it got was MATCHED_RECURSIVELY_LEADING_PATHSPEC.

Reported-by: christian w <usebees@gmail.com>
Simplified-testcase-and-bisection-by: Kyle Meyer <kyle@kyleam.com>
Signed-off-by: Elijah Newren <newren@gmail.com>
---
 dir.c                      |  9 ++++++---
 t/t3000-ls-files-others.sh | 16 ++++++++++++++++
 2 files changed, 22 insertions(+), 3 deletions(-)
diff --git a/dir.c b/dir.c
index 1045cc9c6f..b5082ca05f 100644
--- a/dir.c
+++ b/dir.c
@@ -1792,9 +1792,12 @@ static enum path_treatment treat_directory(struct dir_struct *dir,
 		nested_repo = is_nonbare_repository_dir(&sb);
 		strbuf_release(&sb);
 	}
-	if (nested_repo)
-		return ((dir->flags & DIR_SKIP_NESTED_GIT) ? path_none :
-			(excluded ? path_excluded : path_untracked));
+	if (nested_repo) {
+		if ((dir->flags & DIR_SKIP_NESTED_GIT) ||
+		    (matches_how == MATCHED_RECURSIVELY_LEADING_PATHSPEC))
+			return path_none;
+		return excluded ? path_excluded : path_untracked;
+	}
 
 	if (!(dir->flags & DIR_SHOW_OTHER_DIRECTORIES)) {
 		if (excluded &&
diff --git a/t/t3000-ls-files-others.sh b/t/t3000-ls-files-others.sh
index 1b9327b780..740ce56eab 100755
--- a/t/t3000-ls-files-others.sh
+++ b/t/t3000-ls-files-others.sh
@@ -212,4 +212,20 @@ test_expect_success 'ls-files -o --directory to get immediate paths under one di
 	)
 '
 
+test_expect_success 'ls-files -o avoids listing untracked non-matching gitdir' '
+	test_when_finished "rm -rf nested/untracked/deep/empty" &&
+	(
+		cd nested &&
+
+		git init untracked/deep/empty &&
+		git ls-files --others "untracked/*.c" >actual &&
+
+		cat <<-EOF >expect &&
+		untracked/deep/foo.c
+		EOF
+
+		test_cmp expect actual
+	)
+'
+
 test_done
-- 
gitgitgadget
Previous: Elijah Newren via GitGitGadgetNext: Elijah Newren via GitGitGadget
Message 2 of 3 in “Fix handling of matching nonbare repo vs. matching something under nonbare repo”
  1. 0/2 Fix handling of matching nonbare repo vs. matching something under nonbare repoElijah Newren via GitGitGadget, Aug 12, 2020
  2. 2/2 dir: avoid prematurely marking nonbare repositories as matchesElijah Newren via GitGitGadget, Aug 12, 2020
  3. 1/2 t3000: fix some test description typosElijah Newren via GitGitGadget, Aug 12, 2020

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.