8b1bd02 (Make !pattern in .gitattributes non-fatal - 2013-03-01) raises the fact that even though '!' should have been a negative pattern indicator, people have been misusing for plain '!' and old Git versions accept that. This makes the leading '!' a de facto literal. We can't ever make it negative indicator again because we can't distinguish the literal '!' in existing repos and the negative '!' in future repos. Acknowledge it in document and code that the leading '!' is forever literal. Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@xxxxxxxxx> --- Perhaps this on top of Thomas' patch? I see no way else that we can change the meaning of '!' again if such patterns are already stored in repositories. Documentation/gitattributes.txt | 3 ++- attr.c | 8 ++------ dir.c | 7 ++++--- dir.h | 6 +++++- t/t0003-attributes.sh | 5 ++--- 5 files changed, 15 insertions(+), 14 deletions(-) diff --git a/Documentation/gitattributes.txt b/Documentation/gitattributes.txt index 2698f63..02bff9d 100644 --- a/Documentation/gitattributes.txt +++ b/Documentation/gitattributes.txt @@ -56,7 +56,8 @@ When more than one pattern matches the path, a later line overrides an earlier line. This overriding is done per attribute. The rules how the pattern matches paths are the same as in `.gitignore` files; see linkgit:gitignore[5]. -Unlike `.gitignore`, negative patterns are forbidden. +Unlike `.gitignore`, the leading `!` is treated as a literal +exclamation, not an indicator of negative patterns. When deciding what attributes are assigned to a path, git consults `$GIT_DIR/info/attributes` file (which has the highest diff --git a/attr.c b/attr.c index d181d98..838ec21 100644 --- a/attr.c +++ b/attr.c @@ -254,12 +254,8 @@ static struct match_attr *parse_attr_line(const char *line, const char *src, parse_exclude_pattern(&res->u.pat.pattern, &res->u.pat.patternlen, &res->u.pat.flags, - &res->u.pat.nowildcardlen); - if (res->u.pat.flags & EXC_FLAG_NEGATIVE) { - warning(_("Negative patterns are ignored in git attributes\n" - "Use '\\!' for literal leading exclamation.")); - return NULL; - } + &res->u.pat.nowildcardlen, + 1); } res->is_macro = is_macro; res->num_attr = num_attr; diff --git a/dir.c b/dir.c index a473ca2..609ab99 100644 --- a/dir.c +++ b/dir.c @@ -311,13 +311,14 @@ static int no_wildcard(const char *string) void parse_exclude_pattern(const char **pattern, int *patternlen, int *flags, - int *nowildcardlen) + int *nowildcardlen, + int gitattributes) { const char *p = *pattern; size_t i, len; *flags = 0; - if (*p == '!') { + if (!gitattributes && *p == '!') { *flags |= EXC_FLAG_NEGATIVE; p++; } @@ -354,7 +355,7 @@ void add_exclude(const char *string, const char *base, int flags; int nowildcardlen; - parse_exclude_pattern(&string, &patternlen, &flags, &nowildcardlen); + parse_exclude_pattern(&string, &patternlen, &flags, &nowildcardlen, 0); if (flags & EXC_FLAG_MUSTBEDIR) { char *s; x = xmalloc(sizeof(*x) + patternlen + 1); diff --git a/dir.h b/dir.h index f5c89e3..3aeb519 100644 --- a/dir.h +++ b/dir.h @@ -107,7 +107,11 @@ extern int path_excluded(struct path_exclude_check *, const char *, int namelen, extern int add_excludes_from_file_to_list(const char *fname, const char *base, int baselen, char **buf_p, struct exclude_list *which, int check_index); extern void add_excludes_from_file(struct dir_struct *, const char *fname); -extern void parse_exclude_pattern(const char **string, int *patternlen, int *flags, int *nowildcardlen); +extern void parse_exclude_pattern(const char **string, + int *patternlen, + int *flags, + int *nowildcardlen, + int gitattributes); extern void add_exclude(const char *string, const char *base, int baselen, struct exclude_list *which); extern void free_excludes(struct exclude_list *el); diff --git a/t/t0003-attributes.sh b/t/t0003-attributes.sh index 1035a14..7ca283f 100755 --- a/t/t0003-attributes.sh +++ b/t/t0003-attributes.sh @@ -197,9 +197,8 @@ test_expect_success 'root subdir attribute test' ' ' test_expect_success 'negative patterns' ' - echo "!f test=bar" >.gitattributes && - git check-attr test -- '"'"'!f'"'"' 2>errors && - test_i18ngrep "Negative patterns are ignored" errors + echo "!f test=foo" >.gitattributes && + attr_check "!f" foo ' test_expect_success 'patterns starting with exclamation' ' -- 1.8.1.2.536.gf441e6d -- 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