Skip to content

Commit e2d4f09

Browse files
authored
Merge pull request libgit2#5076 from libgit2/ethomson/ignore_spaces
Ignore files: don't ignore whitespace
2 parents ac070af + 4bcebe2 commit e2d4f09

File tree

6 files changed

+1342
-11
lines changed

6 files changed

+1342
-11
lines changed

src/attr_file.c

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -583,8 +583,11 @@ int git_attr_fnmatch__parse(
583583

584584
pattern = *base;
585585

586-
while (git__isspace(*pattern)) pattern++;
587-
if (!*pattern || *pattern == '#') {
586+
while (!allow_space && git__isspace(*pattern))
587+
pattern++;
588+
589+
if (!*pattern || *pattern == '#' || *pattern == '\n' ||
590+
(*pattern == '\r' && *(pattern + 1) == '\n')) {
588591
*base = git__next_line(pattern);
589592
return GIT_ENOTFOUND;
590593
}
@@ -606,8 +609,12 @@ int git_attr_fnmatch__parse(
606609

607610
slash_count = 0;
608611
for (scan = pattern; *scan != '\0'; ++scan) {
609-
/* scan until (non-escaped) white space */
610-
if (git__isspace(*scan) && *(scan - 1) != '\\') {
612+
/*
613+
* Scan until a non-escaped whitespace: find a whitespace, then look
614+
* one char backward to ensure that it's not prefixed by a `\`.
615+
* Only look backward if we're not at the first position (`pattern`).
616+
*/
617+
if (git__isspace(*scan) && scan > pattern && *(scan - 1) != '\\') {
611618
if (!allow_space || (*scan != ' ' && *scan != '\t' && *scan != '\r'))
612619
break;
613620
}

tests/attr/file.c

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -181,16 +181,11 @@ void test_attr_file__assign_variants(void)
181181
git_attr_file__free(file);
182182
}
183183

184-
void test_attr_file__check_attr_examples(void)
184+
static void assert_examples(git_attr_file *file)
185185
{
186-
git_attr_file *file;
187186
git_attr_rule *rule;
188187
git_attr_assignment *assign;
189188

190-
cl_git_pass(git_attr_file__load_standalone(&file, cl_fixture("attr/attr3")));
191-
cl_assert_equal_s(cl_fixture("attr/attr3"), file->entry->path);
192-
cl_assert(file->rules.length == 3);
193-
194189
rule = get_rule(0);
195190
cl_assert_equal_s("*.java", rule->match.pattern);
196191
cl_assert(rule->assigns.length == 3);
@@ -219,6 +214,30 @@ void test_attr_file__check_attr_examples(void)
219214
assign = get_assign(rule, 0);
220215
cl_assert_equal_s("caveat", assign->name);
221216
cl_assert_equal_s("unspecified", assign->value);
217+
}
218+
219+
void test_attr_file__check_attr_examples(void)
220+
{
221+
git_attr_file *file;
222+
223+
cl_git_pass(git_attr_file__load_standalone(&file, cl_fixture("attr/attr3")));
224+
cl_assert_equal_s(cl_fixture("attr/attr3"), file->entry->path);
225+
cl_assert(file->rules.length == 3);
226+
227+
assert_examples(file);
228+
229+
git_attr_file__free(file);
230+
}
231+
232+
void test_attr_file__whitespace(void)
233+
{
234+
git_attr_file *file;
235+
236+
cl_git_pass(git_attr_file__load_standalone(&file, cl_fixture("attr/attr4")));
237+
cl_assert_equal_s(cl_fixture("attr/attr4"), file->entry->path);
238+
cl_assert(file->rules.length == 3);
239+
240+
assert_examples(file);
222241

223242
git_attr_file__free(file);
224243
}

tests/iterator/workdir.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ static void workdir_iterator_test(
100100

101101
void test_iterator_workdir__0(void)
102102
{
103-
workdir_iterator_test("attr", NULL, NULL, 23, 5, NULL, "ign");
103+
workdir_iterator_test("attr", NULL, NULL, 24, 5, NULL, "ign");
104104
}
105105

106106
static const char *status_paths[] = {

tests/resources/attr/attr4

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# This is a comment
2+
# This is also a comment
3+
*.java diff=java -crlf myAttr
4+
5+
NoMyAttr.java !myAttr
6+
7+
README caveat=unspecified

tests/status/ignore.c

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1236,3 +1236,33 @@ void test_status_ignore__skips_bom(void)
12361236
refute_is_ignored("foo.txt");
12371237
refute_is_ignored("bar.txt");
12381238
}
1239+
1240+
void test_status_ignore__leading_spaces_are_significant(void)
1241+
{
1242+
static const char *test_files[] = {
1243+
"empty_standard_repo/a.test",
1244+
"empty_standard_repo/b.test",
1245+
"empty_standard_repo/c.test",
1246+
"empty_standard_repo/d.test",
1247+
NULL
1248+
};
1249+
1250+
make_test_data("empty_standard_repo", test_files);
1251+
cl_git_mkfile(
1252+
"empty_standard_repo/.gitignore",
1253+
" a.test\n"
1254+
"# this is a comment\n"
1255+
"b.test\n"
1256+
"\tc.test\n"
1257+
" # not a comment\n"
1258+
"d.test\n");
1259+
1260+
refute_is_ignored("a.test");
1261+
assert_is_ignored(" a.test");
1262+
refute_is_ignored("# this is a comment");
1263+
assert_is_ignored("b.test");
1264+
refute_is_ignored("c.test");
1265+
assert_is_ignored("\tc.test");
1266+
assert_is_ignored(" # not a comment");
1267+
assert_is_ignored("d.test");
1268+
}

0 commit comments

Comments
 (0)