Subject: [PATCH 1/1] add: fix handling literal filenames and wildcards

From: K Jayatheerth <[email-masked]>
Date: Sat, 12 Apr 2025 15:16:07 +0530

When `git add` is given a wildcard pathspec (e.g., 'f*'), and a file
with that *exact* name ('f*') also exists, Git incorrectly adds only
the literal file on the first invocation, ignoring other wildcard
matches like 'foo'. On subsequent invocations, the wildcard expands
as expected.

This occurs because the pathspec matching logic short-circuits when
an exact match is found, skipping wildcard evaluation.

With this fix, wildcard expansion is always performed, ensuring
consistent behavior even when a literal filename matches the
wildcard.

To explicitly add the literal file named 'f*', users should use:
    git add 'f\*'

reported-by: piotrsiupa <[email-masked]>
Mentored-by: Jeff King <[email-masked]>
Signed-off-by: K Jayatheerth <[email-masked]>
---
 dir.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/dir.c b/dir.c
index cbd82be6c9..0546c00952 100644
--- a/dir.c
+++ b/dir.c
@@ -519,7 +519,8 @@ static int do_match_pathspec(struct index_state *istate,
 		    ( exclude && !(ps->items[i].magic & PATHSPEC_EXCLUDE)))
 			continue;
 
-		if (seen && seen[i] == MATCHED_EXACTLY)
+		if (seen && seen[i] == MATCHED_EXACTLY &&
+			ps->items[i].nowildcard_len == ps->items[i].len)
 			continue;
 		/*
 		 * Make exclude patterns optional and never report
-- 
2.49.0