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@xxxxxxxxx> Mentored-by: Jeff King <peff@xxxxxxxx> Signed-off-by: K Jayatheerth <jayatheerthkulkarni2005@xxxxxxxxx> --- 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