Skip to content

Commit 906623b

Browse files
committed
attr: honor ignorecase in attribute matching
`.gitattributes` is case-insensitive when `core.ignorecase=true`.
1 parent 9692f45 commit 906623b

File tree

2 files changed

+21
-2
lines changed

2 files changed

+21
-2
lines changed

src/libgit2/attr_file.c

+9-2
Original file line numberDiff line numberDiff line change
@@ -347,7 +347,7 @@ int git_attr_file__parse_buffer(
347347
{
348348
const char *scan = data, *context = NULL;
349349
git_attr_rule *rule = NULL;
350-
int error = 0;
350+
int ignorecase = 0, error = 0;
351351

352352
/* If subdir file path, convert context for file paths */
353353
if (attrs->entry && git_fs_path_root(attrs->entry->path) < 0 &&
@@ -379,6 +379,13 @@ int git_attr_file__parse_buffer(
379379
continue;
380380
}
381381

382+
if (repo &&
383+
(error = git_repository__configmap_lookup(&ignorecase, repo, GIT_CONFIGMAP_IGNORECASE)) < 0)
384+
goto out;
385+
386+
if (ignorecase)
387+
rule->match.flags |= GIT_ATTR_FNMATCH_ICASE;
388+
382389
if (rule->match.flags & GIT_ATTR_FNMATCH_MACRO) {
383390
/* TODO: warning if macro found in file below repo root */
384391
if (!allow_macros)
@@ -482,7 +489,7 @@ bool git_attr_fnmatch__match(
482489
*/
483490
if (match->containing_dir) {
484491
if (match->flags & GIT_ATTR_FNMATCH_ICASE) {
485-
if (git__strncasecmp(path->path, match->containing_dir, match->containing_dir_length))
492+
if (git__prefixcmp_icase(path->path, match->containing_dir))
486493
return 0;
487494
} else {
488495
if (git__prefixcmp(path->path, match->containing_dir))

tests/libgit2/filter/query.c

+12
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,18 @@ void test_filter_query__filters(void)
5353
cl_assert_equal_i(1, filter_for("id.binident", "ident"));
5454
}
5555

56+
void test_filter_query__filters_ignorecase(void)
57+
{
58+
if (!cl_repo_get_bool(g_repo, "core.ignorecase"))
59+
cl_skip();
60+
61+
cl_assert_equal_i(1, filter_for("TEXT.TXT", "crlf"));
62+
cl_assert_equal_i(0, filter_for("Binary.bin", "crlf"));
63+
64+
cl_assert_equal_i(1, filter_for("id.Ident", "crlf"));
65+
cl_assert_equal_i(1, filter_for("ID.IdEnT", "ident"));
66+
}
67+
5668
void test_filter_query__autocrlf_true_implies_crlf(void)
5769
{
5870
cl_repo_set_bool(g_repo, "core.autocrlf", true);

0 commit comments

Comments
 (0)