dir: fix directory-matching bug

This reverts the change from ed49584 (dir: fix pattern matching on dirs, 2021-09-24), which claimed to fix a directory-matching problem without a test case. It turns out to _create_ a bug, but it is a bit subtle. The bug would have been revealed by the first of two tests being added to t0008-ignores.sh. The first uses a pattern "/git/" inside the a/.gitignores file, which matches against 'a/git/foo' but not 'a/git-foo/bar'. This test would fail before the revert. The second test shows what happens if the test instead uses a pattern "git/" and this test passes both before and after the revert. The difference in these two cases are due to how last_matching_pattern_from_list() checks patterns both if they have the PATTERN_FLAG_MUSTBEDIR and PATTERN_FLAG_NODIR flags. In the case of "git/", the PATTERN_FLAG_NODIR is also provided, making the change in behavior in match_pathname() not affect the end result of last_matching_pattern_from_list(). Reported-by: Glen Choo <chooglen@google.com> Signed-off-by: Derrick Stolee <dstolee@microsoft.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Derrick Stolee committed Nov 2, 2021 at 10:40 UTC 5ceb663e926bd22248d1d72d70fa701c558587ea
2 files changed +27 -1
dir.c
+1 -1
@@ -1294,7 +1294,7 @@ int match_pathname(const char *pathname, int pathlen,
1294 * then our prefix match is all we need; we
1295 * do not need to call fnmatch at all.
1296 */
1297 - if (!patternlen && (!namelen || (flags & PATTERN_FLAG_MUSTBEDIR)))
1297 + if (!patternlen && !namelen)
1298 return 1;
1299 }
1300
t/t0008-ignores.sh
+26
@@ -802,6 +802,32 @@ test_expect_success 'existing directory and file' '
802 grep top-level-dir actual
803 '
804
805 +test_expect_success 'exact prefix matching (with root)' '
806 + test_when_finished rm -r a &&
807 + mkdir -p a/git a/git-foo &&
808 + touch a/git/foo a/git-foo/bar &&
809 + echo /git/ >a/.gitignore &&
810 + git check-ignore a/git a/git/foo a/git-foo a/git-foo/bar >actual &&
811 + cat >expect <<-\EOF &&
812 + a/git
813 + a/git/foo
814 + EOF
815 + test_cmp expect actual
816 +'
817 +
818 +test_expect_success 'exact prefix matching (without root)' '
819 + test_when_finished rm -r a &&
820 + mkdir -p a/git a/git-foo &&
821 + touch a/git/foo a/git-foo/bar &&
822 + echo git/ >a/.gitignore &&
823 + git check-ignore a/git a/git/foo a/git-foo a/git-foo/bar >actual &&
824 + cat >expect <<-\EOF &&
825 + a/git
826 + a/git/foo
827 + EOF
828 + test_cmp expect actual
829 +'
830 +
831 ############################################################################
832 #
833 # test whitespace handling