attr: honor ignorecase in attribute matching

`.gitattributes` is case-insensitive when `core.ignorecase=true`.
This commit is contained in:
Edward Thomson
2025-01-15 22:07:14 +00:00
parent 9692f45ca8
commit 906623b8f9
2 changed files with 21 additions and 2 deletions

View File

@@ -347,7 +347,7 @@ int git_attr_file__parse_buffer(
{
const char *scan = data, *context = NULL;
git_attr_rule *rule = NULL;
int error = 0;
int ignorecase = 0, error = 0;
/* If subdir file path, convert context for file paths */
if (attrs->entry && git_fs_path_root(attrs->entry->path) < 0 &&
@@ -379,6 +379,13 @@ int git_attr_file__parse_buffer(
continue;
}
if (repo &&
(error = git_repository__configmap_lookup(&ignorecase, repo, GIT_CONFIGMAP_IGNORECASE)) < 0)
goto out;
if (ignorecase)
rule->match.flags |= GIT_ATTR_FNMATCH_ICASE;
if (rule->match.flags & GIT_ATTR_FNMATCH_MACRO) {
/* TODO: warning if macro found in file below repo root */
if (!allow_macros)
@@ -482,7 +489,7 @@ bool git_attr_fnmatch__match(
*/
if (match->containing_dir) {
if (match->flags & GIT_ATTR_FNMATCH_ICASE) {
if (git__strncasecmp(path->path, match->containing_dir, match->containing_dir_length))
if (git__prefixcmp_icase(path->path, match->containing_dir))
return 0;
} else {
if (git__prefixcmp(path->path, match->containing_dir))

View File

@@ -53,6 +53,18 @@ void test_filter_query__filters(void)
cl_assert_equal_i(1, filter_for("id.binident", "ident"));
}
void test_filter_query__filters_ignorecase(void)
{
if (!cl_repo_get_bool(g_repo, "core.ignorecase"))
cl_skip();
cl_assert_equal_i(1, filter_for("TEXT.TXT", "crlf"));
cl_assert_equal_i(0, filter_for("Binary.bin", "crlf"));
cl_assert_equal_i(1, filter_for("id.Ident", "crlf"));
cl_assert_equal_i(1, filter_for("ID.IdEnT", "ident"));
}
void test_filter_query__autocrlf_true_implies_crlf(void)
{
cl_repo_set_bool(g_repo, "core.autocrlf", true);