diff --git a/src/attr_file.c b/src/attr_file.c index 8997946b9..eed39661f 100644 --- a/src/attr_file.c +++ b/src/attr_file.c @@ -394,6 +394,7 @@ bool git_attr_fnmatch__match( if ((match->flags & GIT_ATTR_FNMATCH_DIRECTORY) && !path->is_dir) { int matchval; + char *matchpath; /* for attribute checks or root ignore checks, fail match */ if (!(match->flags & GIT_ATTR_FNMATCH_IGNORE) || @@ -403,7 +404,13 @@ bool git_attr_fnmatch__match( /* for ignore checks, use container of current item for check */ path->basename[-1] = '\0'; flags |= FNM_LEADING_DIR; - matchval = p_fnmatch(match->pattern, path->path, flags); + + if (match->containing_dir) + matchpath = path->basename; + else + matchpath = path->path; + + matchval = p_fnmatch(match->pattern, matchpath, flags); path->basename[-1] = '/'; return (matchval != FNM_NOMATCH); } diff --git a/tests/attr/ignore.c b/tests/attr/ignore.c index b187db01c..aa5b87098 100644 --- a/tests/attr/ignore.c +++ b/tests/attr/ignore.c @@ -146,6 +146,24 @@ void test_attr_ignore__skip_gitignore_directory(void) assert_is_ignored(true, "NewFolder/NewFolder/File.txt"); } +void test_attr_ignore__subdirectory_gitignore(void) +{ + p_unlink("attr/.gitignore"); + cl_assert(!git_path_exists("attr/.gitignore")); + cl_git_mkfile( + "attr/.gitignore", + "file1\n"); + p_mkdir("attr/dir", 0777); + cl_git_mkfile( + "attr/dir/.gitignore", + "file2/\n"); + + assert_is_ignored(true, "file1"); + assert_is_ignored(true, "dir/file1"); + assert_is_ignored(true, "dir/file2"); /* in ignored dir */ + assert_is_ignored(false, "dir/file3"); +} + void test_attr_ignore__expand_tilde_to_homedir(void) { git_config *cfg;