Patterns in .gitattributes are separated by whitespaces, which makes it impossible to specify exact spaces in the pattern. '?' can be used as a workaround, but it matches other characters too. This patch makes a space following a backslash part of the pattern, not a pattern separator. Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@xxxxxxxxx> --- A similar patch was posted twice (during freeze time iirc). I think this is a good change, so I will keep reposting until someone turns it down. We could use wildmatch for parsing here, which would support patterns like "Hello[ ]world". But that's not going to happen until wildmatch graduates and somebody brings it up again. Documentation/gitattributes.txt | 6 +++--- attr.c | 8 +++++++- t/t0003-attributes.sh | 5 +++++ 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/Documentation/gitattributes.txt b/Documentation/gitattributes.txt index 2698f63..113b1f8 100644 --- a/Documentation/gitattributes.txt +++ b/Documentation/gitattributes.txt @@ -20,9 +20,9 @@ Each line in `gitattributes` file is of form: pattern attr1 attr2 ... -That is, a pattern followed by an attributes list, -separated by whitespaces. When the pattern matches the -path in question, the attributes listed on the line are given to +That is, a pattern followed by an attributes list, separated by +whitespaces that are not quoted by a backslash. When the pattern matches +the path in question, the attributes listed on the line are given to the path. Each attribute can be in one of these states for a given path: diff --git a/attr.c b/attr.c index 097ae87..776f34e 100644 --- a/attr.c +++ b/attr.c @@ -209,7 +209,13 @@ static struct match_attr *parse_attr_line(const char *line, const char *src, if (!*cp || *cp == '#') return NULL; name = cp; - namelen = strcspn(name, blank); + namelen = 0; + while (name[namelen] != '\0' && !strchr(blank, name[namelen])) { + if (name[namelen] == '\\' && name[namelen + 1] != '\0') + namelen += 2; + else + namelen++; + } if (strlen(ATTRIBUTE_MACRO_PREFIX) < namelen && !prefixcmp(name, ATTRIBUTE_MACRO_PREFIX)) { if (!macro_ok) { diff --git a/t/t0003-attributes.sh b/t/t0003-attributes.sh index 807b8b8..6a5d8ab 100755 --- a/t/t0003-attributes.sh +++ b/t/t0003-attributes.sh @@ -24,6 +24,7 @@ test_expect_success 'setup' ' echo "offon -test test" echo "no notest" echo "A/e/F test=A/e/F" + echo "A\\ b test=space" ) >.gitattributes && ( echo "g test=a/g" && @@ -196,6 +197,10 @@ test_expect_success 'root subdir attribute test' ' attr_check subdir/a/i unspecified ' +test_expect_success 'quoting in pattern' ' + attr_check "A b" space +' + test_expect_success 'negative patterns' ' echo "!f test=bar" >.gitattributes && test_must_fail git check-attr test -- f -- 1.8.0.rc2.23.g1fb49df -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html