From: K Jayatheerth <jayatheerthkulkarni2005@gmail.com>
To: git@vger.kernel.org
Cc: gitster@pobox.com, lucasseikioshiro@gmail.com, peff@peff.net,
piotrsiupa@gmail.com, sandals@crustytoothpaste.net,
jayatheerthkulkarni2005@gmail.com
Subject: [PATCH v2] Dir: Fix and test wildcard pathspec handling
Date: Tue, 22 Apr 2025 21:35:47 +0530 [thread overview]
Message-ID: <20250422160547.577524-1-jayatheerthkulkarni2005@gmail.com> (raw)
Ensure wildcards expand, even with literal file match.
Fixes 'git add f*' skipping files like 'foo' if 'f*' exists.
Use 'f\*' to add the literal.
Tests added for add and commit where dir.c logic applies.
Skips windows specific test.
reported-by: piotrsiupa <piotrsiupa@gmail.com>
Mentored-by: Jeff King <peff@peff.net>
Signed-off-by: K Jayatheerth <jayatheerthkulkarni2005@gmail.com>
---
dir.c | 3 +-
t/meson.build | 1 +
t/t6137-pathspec-wildcards-literal.sh | 282 ++++++++++++++++++++++++++
3 files changed, 285 insertions(+), 1 deletion(-)
create mode 100755 t/t6137-pathspec-wildcards-literal.sh
diff --git a/dir.c b/dir.c
index 28b0e03feb..9405fee83a 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
diff --git a/t/meson.build b/t/meson.build
index bfb744e886..61285852e9 100644
--- a/t/meson.build
+++ b/t/meson.build
@@ -788,6 +788,7 @@ integration_tests = [
't6134-pathspec-in-submodule.sh',
't6135-pathspec-with-attrs.sh',
't6136-pathspec-in-bare.sh',
+ 't6137-pathspec-wildcards-literal.sh',
't6200-fmt-merge-msg.sh',
't6300-for-each-ref.sh',
't6301-for-each-ref-errors.sh',
diff --git a/t/t6137-pathspec-wildcards-literal.sh b/t/t6137-pathspec-wildcards-literal.sh
new file mode 100755
index 0000000000..abf837bf6c
--- /dev/null
+++ b/t/t6137-pathspec-wildcards-literal.sh
@@ -0,0 +1,282 @@
+#!/bin/sh
+
+test_description='test wildcards and literals with various git commands'
+
+. ./test-lib.sh
+
+test_have_prereq FUNNYNAMES || {
+ skip_all='skipping: needs FUNNYNAMES (non-Windows only)'
+ test_done
+}
+
+reset_git_repo () {
+ rm -rf .git &&
+ git init &&
+ rm -rf "actual_files" "expected_files"
+}
+
+end_test_properly() {
+ cd .. &&
+ rm -rf "testdir"
+}
+
+
+test_expect_success 'setup' '
+ mkdir testdir &&
+ cd testdir &&
+ touch "*" "?" "[abc]" "f*" "f?z" "a" &&
+ touch "**" "foo*bar" "hello?world" "f**" "hello_world" &&
+ git init
+'
+
+test_expect_success 'check * wildcard in git add' '
+ git init &&
+ git add "*" &&
+ cat >expected_files <<EOF &&
+*
+**
+?
+[abc]
+a
+f*
+f**
+f?z
+foo*bar
+hello?world
+hello_world
+EOF
+ git ls-files >actual_files &&
+ test_cmp expected_files actual_files
+'
+
+test_expect_success 'check \* literal in git add' '
+ reset_git_repo &&
+ git add "\*" &&
+ cat >expected_files <<EOF &&
+*
+EOF
+ git ls-files >actual_files &&
+ test_cmp expected_files actual_files
+'
+
+test_expect_success 'check f* wildcard in git add' '
+ reset_git_repo &&
+ git add "f*" &&
+ cat >expected_files <<EOF &&
+f*
+f**
+f?z
+foo*bar
+EOF
+ git ls-files >actual_files &&
+ test_cmp expected_files actual_files
+'
+
+test_expect_success 'check f\* literal in git add' '
+ reset_git_repo &&
+ git add "f\*" &&
+ cat >expected_files <<EOF &&
+f*
+EOF
+ git ls-files >actual_files &&
+ test_cmp expected_files actual_files
+'
+
+test_expect_success 'check f** wildcard in git add' '
+ reset_git_repo &&
+ git add "f**" &&
+ cat >expected_files <<EOF &&
+f*
+f**
+f?z
+foo*bar
+EOF
+ git ls-files >actual_files &&
+ test_cmp expected_files actual_files
+'
+
+test_expect_success 'check f\*\* literal in git add' '
+ reset_git_repo &&
+ git add "f\*\*" &&
+ cat >expected_files <<EOF &&
+f**
+EOF
+ git ls-files >actual_files &&
+ test_cmp expected_files actual_files
+'
+
+test_expect_success 'check ? wildcard in git add' '
+ reset_git_repo &&
+ git add "?" &&
+ cat >expected_files <<EOF &&
+*
+?
+a
+EOF
+ git ls-files >actual_files &&
+ test_cmp expected_files actual_files
+'
+
+test_expect_success 'check \? literal in git add' '
+ reset_git_repo &&
+ git add "\?" &&
+ cat >expected_files <<EOF &&
+?
+EOF
+ git ls-files >actual_files &&
+ test_cmp expected_files actual_files
+'
+
+test_expect_success 'check hello?world wildcard in git add' '
+ reset_git_repo &&
+ git add "hello?world" &&
+ cat >expected_files <<EOF &&
+hello?world
+hello_world
+EOF
+ git ls-files >actual_files &&
+ test_cmp expected_files actual_files
+'
+
+test_expect_success 'check hello\?world literal in git add' '
+ reset_git_repo &&
+ git add "hello\?world" &&
+ cat >expected_files <<EOF &&
+hello?world
+EOF
+ git ls-files >actual_files &&
+ test_cmp expected_files actual_files
+'
+
+test_expect_success 'commit: wildcard *' '
+ reset_git_repo &&
+ git add . &&
+ git commit --allow-empty -m "Test" -- "*" &&
+ cat >expected_files <<-\EOF &&
+*
+**
+?
+[abc]
+a
+f*
+f**
+f?z
+foo*bar
+hello?world
+hello_world
+EOF
+ git ls-tree -r --name-only HEAD > actual_files &&
+ test_cmp expected_files actual_files
+'
+
+test_expect_success 'commit: literal *' '
+ reset_git_repo &&
+ git add . &&
+ git commit --allow-empty -m "Test" -- "\*" &&
+ cat >expected_files <<-\EOF &&
+*
+EOF
+ git ls-tree -r --name-only HEAD > actual_files &&
+ test_cmp expected_files actual_files
+'
+
+test_expect_success 'commit: wildcard f*' '
+ reset_git_repo &&
+ git add . &&
+ git commit --allow-empty -m "Test" -- "f*" &&
+ cat >expected_files <<-\EOF &&
+f*
+f**
+f?z
+foo*bar
+EOF
+ git ls-tree -r --name-only HEAD > actual_files &&
+ test_cmp expected_files actual_files
+'
+
+test_expect_success 'commit: literal f\*' '
+ reset_git_repo &&
+ git add . &&
+ git commit --allow-empty -m "Test" -- "f\*" &&
+ cat >expected_files <<-\EOF &&
+f*
+EOF
+ git ls-tree -r --name-only HEAD > actual_files &&
+ test_cmp expected_files actual_files
+'
+
+test_expect_success 'commit: wildcard pathspec limits commit' '
+ reset_git_repo &&
+ git add . &&
+ git commit --allow-empty -m "Test" -- "f**" &&
+ cat >expected_files <<-\EOF &&
+f*
+f**
+f?z
+foo*bar
+EOF
+ git ls-tree -r --name-only HEAD > actual_files &&
+ test_cmp expected_files actual_files
+'
+
+test_expect_success 'commit: literal f\*\*' '
+ reset_git_repo &&
+ git add . &&
+ git commit --allow-empty -m "Test" -- "f\*\*" &&
+ cat >expected_files <<-\EOF &&
+f**
+EOF
+ git ls-tree -r --name-only HEAD > actual_files &&
+ test_cmp expected_files actual_files
+'
+
+test_expect_success 'commit: wildcard ?' '
+ reset_git_repo &&
+ git add . &&
+ git commit --allow-empty -m "Test" -- "?" &&
+ cat >expected_files <<-\EOF &&
+*
+?
+a
+EOF
+ git ls-tree -r --name-only HEAD > actual_files &&
+ test_cmp expected_files actual_files
+'
+
+test_expect_success 'commit: literal \?' '
+ reset_git_repo &&
+ git add . &&
+ git commit --allow-empty -m "Test" -- "\?" &&
+ cat >expected_files <<-\EOF &&
+?
+EOF
+ git ls-tree -r --name-only HEAD > actual_files &&
+ test_cmp expected_files actual_files
+'
+
+test_expect_success 'check hello?world wildcard in git commit' '
+ reset_git_repo &&
+ git add . &&
+ git commit --allow-empty -m "Test" -- "hello?world" &&
+ cat >expected_files <<-\EOF &&
+hello?world
+hello_world
+EOF
+ git ls-tree -r --name-only HEAD > actual_files &&
+ test_cmp expected_files actual_files
+'
+
+test_expect_success 'check hello\?world literal in git commit' '
+ reset_git_repo &&
+ git add . &&
+ git commit --allow-empty -m "Test" -- "hello\?world" &&
+ cat >expected_files <<-\EOF &&
+hello?world
+EOF
+ git ls-tree -r --name-only HEAD > actual_files &&
+ test_cmp expected_files actual_files
+'
+
+end_test_properly
+
+test_done
--
2.49.0.223.ga3111b2db4.dirty
next reply other threads:[~2025-04-22 16:05 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-04-22 16:05 K Jayatheerth [this message]
2025-04-22 18:53 ` [PATCH v2] Dir: Fix and test wildcard pathspec handling Junio C Hamano
2025-05-03 6:07 ` [PATCH] dir.c: literal match with wildcard in pathspec should still glob K Jayatheerth
2025-05-03 6:24 ` JAYATHEERTH K
2025-05-05 14:41 ` Junio C Hamano
2025-05-05 15:02 ` K Jayatheerth
2025-05-05 15:03 ` JAYATHEERTH K
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20250422160547.577524-1-jayatheerthkulkarni2005@gmail.com \
--to=jayatheerthkulkarni2005@gmail.com \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--cc=lucasseikioshiro@gmail.com \
--cc=peff@peff.net \
--cc=piotrsiupa@gmail.com \
--cc=sandals@crustytoothpaste.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).