Skip to content

Commit 76b620d

Browse files
committed
Merge branch 'nd/exclusion-regression-fix'
The ignore mechanism saw a few regressions around untracked file listing and sparse checkout selection areas in 2.7.0; the change that is responsible for the regression has been reverted. * nd/exclusion-regression-fix: Revert "dir.c: don't exclude whole dir prematurely if neg pattern may match"
2 parents ceef512 + 8c72236 commit 76b620d

File tree

3 files changed

+6
-118
lines changed

3 files changed

+6
-118
lines changed

Documentation/gitignore.txt

Lines changed: 4 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -82,12 +82,12 @@ PATTERN FORMAT
8282

8383
- An optional prefix "`!`" which negates the pattern; any
8484
matching file excluded by a previous pattern will become
85-
included again.
85+
included again. It is not possible to re-include a file if a parent
86+
directory of that file is excluded. Git doesn't list excluded
87+
directories for performance reasons, so any patterns on contained
88+
files have no effect, no matter where they are defined.
8689
Put a backslash ("`\`") in front of the first "`!`" for patterns
8790
that begin with a literal "`!`", for example, "`\!important!.txt`".
88-
It is possible to re-include a file if a parent directory of that
89-
file is excluded if certain conditions are met. See section NOTES
90-
for detail.
9191

9292
- If the pattern ends with a slash, it is removed for the
9393
purpose of the following description, but it would only find
@@ -141,21 +141,6 @@ not tracked by Git remain untracked.
141141
To stop tracking a file that is currently tracked, use
142142
'git rm --cached'.
143143

144-
To re-include files or directories when their parent directory is
145-
excluded, the following conditions must be met:
146-
147-
- The rules to exclude a directory and re-include a subset back must
148-
be in the same .gitignore file.
149-
150-
- The directory part in the re-include rules must be literal (i.e. no
151-
wildcards)
152-
153-
- The rules to exclude the parent directory must not end with a
154-
trailing slash.
155-
156-
- The rules to exclude the parent directory must have at least one
157-
slash.
158-
159144
EXAMPLES
160145
--------
161146

dir.c

Lines changed: 2 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -880,74 +880,13 @@ int match_pathname(const char *pathname, int pathlen,
880880
*/
881881
if (!patternlen && !namelen)
882882
return 1;
883-
/*
884-
* This can happen when we ignore some exclude rules
885-
* on directories in other to see if negative rules
886-
* may match. E.g.
887-
*
888-
* /abc
889-
* !/abc/def/ghi
890-
*
891-
* The pattern of interest is "/abc". On the first
892-
* try, we should match path "abc" with this pattern
893-
* in the "if" statement right above, but the caller
894-
* ignores it.
895-
*
896-
* On the second try with paths within "abc",
897-
* e.g. "abc/xyz", we come here and try to match it
898-
* with "/abc".
899-
*/
900-
if (!patternlen && namelen && *name == '/')
901-
return 1;
902883
}
903884

904885
return fnmatch_icase_mem(pattern, patternlen,
905886
name, namelen,
906887
WM_PATHNAME) == 0;
907888
}
908889

909-
/*
910-
* Return non-zero if pathname is a directory and an ancestor of the
911-
* literal path in a (negative) pattern. This is used to keep
912-
* descending in "foo" and "foo/bar" when the pattern is
913-
* "!foo/bar/.gitignore". "foo/notbar" will not be descended however.
914-
*/
915-
static int match_neg_path(const char *pathname, int pathlen, int *dtype,
916-
const char *base, int baselen,
917-
const char *pattern, int prefix, int patternlen,
918-
int flags)
919-
{
920-
assert((flags & EXC_FLAG_NEGATIVE) && !(flags & EXC_FLAG_NODIR));
921-
922-
if (*dtype == DT_UNKNOWN)
923-
*dtype = get_dtype(NULL, pathname, pathlen);
924-
if (*dtype != DT_DIR)
925-
return 0;
926-
927-
if (*pattern == '/') {
928-
pattern++;
929-
patternlen--;
930-
prefix--;
931-
}
932-
933-
if (baselen) {
934-
if (((pathlen < baselen && base[pathlen] == '/') ||
935-
pathlen == baselen) &&
936-
!strncmp_icase(pathname, base, pathlen))
937-
return 1;
938-
pathname += baselen + 1;
939-
pathlen -= baselen + 1;
940-
}
941-
942-
943-
if (prefix &&
944-
((pathlen < prefix && pattern[pathlen] == '/') &&
945-
!strncmp_icase(pathname, pattern, pathlen)))
946-
return 1;
947-
948-
return 0;
949-
}
950-
951890
/*
952891
* Scan the given exclude list in reverse to see whether pathname
953892
* should be ignored. The first match (i.e. the last on the list), if
@@ -961,7 +900,7 @@ static struct exclude *last_exclude_matching_from_list(const char *pathname,
961900
struct exclude_list *el)
962901
{
963902
struct exclude *exc = NULL; /* undecided */
964-
int i, matched_negative_path = 0;
903+
int i;
965904

966905
if (!el->nr)
967906
return NULL; /* undefined */
@@ -996,18 +935,7 @@ static struct exclude *last_exclude_matching_from_list(const char *pathname,
996935
exc = x;
997936
break;
998937
}
999-
1000-
if ((x->flags & EXC_FLAG_NEGATIVE) && !matched_negative_path &&
1001-
match_neg_path(pathname, pathlen, dtype, x->base,
1002-
x->baselen ? x->baselen - 1 : 0,
1003-
exclude, prefix, x->patternlen, x->flags))
1004-
matched_negative_path = 1;
1005-
}
1006-
if (exc &&
1007-
!(exc->flags & EXC_FLAG_NEGATIVE) &&
1008-
!(exc->flags & EXC_FLAG_NODIR) &&
1009-
matched_negative_path)
1010-
exc = NULL;
938+
}
1011939
return exc;
1012940
}
1013941

t/t3001-ls-files-others-exclude.sh

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -305,29 +305,4 @@ test_expect_success 'ls-files with "**" patterns and no slashes' '
305305
test_cmp expect actual
306306
'
307307

308-
test_expect_success 'negative patterns' '
309-
git init reinclude &&
310-
(
311-
cd reinclude &&
312-
cat >.gitignore <<-\EOF &&
313-
/fooo
314-
/foo
315-
!foo/bar/bar
316-
EOF
317-
mkdir fooo &&
318-
cat >fooo/.gitignore <<-\EOF &&
319-
!/*
320-
EOF
321-
mkdir -p foo/bar &&
322-
touch abc foo/def foo/bar/ghi foo/bar/bar &&
323-
git ls-files -o --exclude-standard >../actual &&
324-
cat >../expected <<-\EOF &&
325-
.gitignore
326-
abc
327-
foo/bar/bar
328-
EOF
329-
test_cmp ../expected ../actual
330-
)
331-
'
332-
333308
test_done

0 commit comments

Comments
 (0)