mirror of
https://git.proxmox.com/git/libgit2
synced 2025-11-03 00:21:33 +00:00
Merge pull request #2598 from libgit2/cmn/stacked-ignore
ignore: don't leak rules into higher directores
This commit is contained in:
commit
64dc248577
@ -347,6 +347,21 @@ bool git_attr_fnmatch__match(
|
||||
const char *filename;
|
||||
int flags = 0;
|
||||
|
||||
/*
|
||||
* If the rule was generated in a subdirectory, we must only
|
||||
* use it for paths inside that directory. We can thus return
|
||||
* a non-match if the prefixes don't match.
|
||||
*/
|
||||
if (match->containing_dir) {
|
||||
if (match->flags & GIT_ATTR_FNMATCH_ICASE) {
|
||||
if (git__strncasecmp(path->path, match->containing_dir, match->containing_dir_length))
|
||||
return 0;
|
||||
} else {
|
||||
if (git__prefixcmp(path->path, match->containing_dir))
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (match->flags & GIT_ATTR_FNMATCH_ICASE)
|
||||
flags |= FNM_CASEFOLD;
|
||||
if (match->flags & GIT_ATTR_FNMATCH_LEADINGDIR)
|
||||
@ -588,6 +603,17 @@ int git_attr_fnmatch__parse(
|
||||
/* leave FULLPATH match on, however */
|
||||
}
|
||||
|
||||
if (context) {
|
||||
char *slash = strchr(context, '/');
|
||||
size_t len;
|
||||
if (slash) {
|
||||
/* include the slash for easier matching */
|
||||
len = slash - context + 1;
|
||||
spec->containing_dir = git_pool_strndup(pool, context, len);
|
||||
spec->containing_dir_length = len;
|
||||
}
|
||||
}
|
||||
|
||||
if ((spec->flags & GIT_ATTR_FNMATCH_FULLPATH) != 0 &&
|
||||
context != NULL && git_path_root(pattern) < 0)
|
||||
{
|
||||
|
||||
@ -52,6 +52,8 @@ extern const char *git_attr__unset;
|
||||
typedef struct {
|
||||
char *pattern;
|
||||
size_t length;
|
||||
char *containing_dir;
|
||||
size_t containing_dir_length;
|
||||
unsigned int flags;
|
||||
} git_attr_fnmatch;
|
||||
|
||||
|
||||
@ -915,3 +915,35 @@ void test_status_ignore__filename_with_cr(void)
|
||||
cl_git_pass(git_ignore_path_is_ignored(&ignored, g_repo, "Icon"));
|
||||
cl_assert_equal_i(1, ignored);
|
||||
}
|
||||
|
||||
void test_status_ignore__subdir_doesnt_match_above(void)
|
||||
{
|
||||
int ignored, icase = 0, error;
|
||||
git_config *cfg;
|
||||
|
||||
g_repo = cl_git_sandbox_init("empty_standard_repo");
|
||||
|
||||
cl_git_pass(git_repository_config_snapshot(&cfg, g_repo));
|
||||
error = git_config_get_bool(&icase, cfg, "core.ignorecase");
|
||||
if (error == GIT_ENOTFOUND)
|
||||
error = 0;
|
||||
|
||||
cl_git_pass(error);
|
||||
|
||||
cl_git_pass(p_mkdir("empty_standard_repo/src", 0777));
|
||||
cl_git_pass(p_mkdir("empty_standard_repo/src/src", 0777));
|
||||
cl_git_mkfile("empty_standard_repo/src/.gitignore", "src\n");
|
||||
cl_git_mkfile("empty_standard_repo/.gitignore", "");
|
||||
|
||||
cl_git_pass(git_ignore_path_is_ignored(&ignored, g_repo, "src/test.txt"));
|
||||
cl_assert_equal_i(0, ignored);
|
||||
cl_git_pass(git_ignore_path_is_ignored(&ignored, g_repo, "src/src/test.txt"));
|
||||
cl_assert_equal_i(1, ignored);
|
||||
cl_git_pass(git_ignore_path_is_ignored(&ignored, g_repo, "src/foo/test.txt"));
|
||||
cl_assert_equal_i(0, ignored);
|
||||
|
||||
cl_git_pass(git_ignore_path_is_ignored(&ignored, g_repo, "SRC/src/test.txt"));
|
||||
cl_assert_equal_i(icase, ignored);
|
||||
cl_git_pass(git_ignore_path_is_ignored(&ignored, g_repo, "src/SRC/test.txt"));
|
||||
cl_assert_equal_i(icase, ignored);
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user