diff options
| author | Junio C Hamano <gitster@pobox.com> | 2025-11-04 14:11:20 -0800 |
|---|---|---|
| committer | Junio C Hamano <gitster@pobox.com> | 2025-11-04 14:12:24 -0800 |
| commit | 97660b2cfedeee452db8e852d6d476e333ac971d (patch) | |
| tree | f3ce2b7a798d73f814278379fda1a7987a4f0971 | |
| parent | Merge branch 'maint-2.47' into maint-2.48 (diff) | |
| download | git-97660b2cfedeee452db8e852d6d476e333ac971d.tar.gz git-97660b2cfedeee452db8e852d6d476e333ac971d.zip | |
dir.c: do not be fooled by :(exclude) pathspec elements
When exclude_matches_pathspec() tries to determine if an otherwise
excluded item matches the pathspec given, it goes through each
pathspec element and declares a hit, without checking if the element
is a negative ":(exclude)" element. Fix it be applying the usual "a
path matches if it matches any one of positive pathspec element, and
if it matches none of negative pathspec elements" rule in the
function.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
| -rw-r--r-- | dir.c | 14 | ||||
| -rwxr-xr-x | t/t2204-add-ignored.sh | 17 |
2 files changed, 29 insertions, 2 deletions
@@ -2219,6 +2219,8 @@ static int exclude_matches_pathspec(const char *path, int pathlen, const struct pathspec *pathspec) { int i; + int matches_exclude_magic = 0; + int matches_pathspec_elem = 0; if (!pathspec || !pathspec->nr) return 0; @@ -2235,15 +2237,23 @@ static int exclude_matches_pathspec(const char *path, int pathlen, for (i = 0; i < pathspec->nr; i++) { const struct pathspec_item *item = &pathspec->items[i]; int len = item->nowildcard_len; + int *matches; + + if (item->magic & PATHSPEC_EXCLUDE) + matches = &matches_exclude_magic; + else + matches = &matches_pathspec_elem; if (len == pathlen && !ps_strncmp(item, item->match, path, pathlen)) - return 1; + *matches = 1; if (len > pathlen && item->match[pathlen] == '/' && !ps_strncmp(item, item->match, path, pathlen)) - return 1; + *matches = 1; } + if (matches_pathspec_elem && !matches_exclude_magic) + return 1; return 0; } diff --git a/t/t2204-add-ignored.sh b/t/t2204-add-ignored.sh index 31eb233df5..aa55b219ab 100755 --- a/t/t2204-add-ignored.sh +++ b/t/t2204-add-ignored.sh @@ -89,4 +89,21 @@ do ' done +test_expect_success "exclude magic would not interfere with .gitignore" ' + test_write_lines dir file sub ign err out "*.o" >.gitignore && + >foo.o && + >foo.c && + test_must_fail git add foo.o 2>err && + test_grep "are ignored by one" err && + test_grep "hint: Use -f" err && + + git add ":(exclude)foo.o" && + git ls-files >actual && + cat >expect <<-\EOF && + .gitignore + foo.c + EOF + test_cmp expect actual +' + test_done |
