dir.c: fix ignore processing within not-ignored directories

As of 95c6f271 "dir.c: unify is_excluded and is_path_excluded APIs", the is_excluded API no longer recurses into directories that match an ignore pattern, and returns the directory's ignored state for all contained paths. This is OK for normal ignore patterns, i.e. ignoring a directory affects the entire contents recursively. Unfortunately, this also "works" for negated ignore patterns ('!dir'), i.e. the entire contents is "not-ignored" recursively, regardless of ignore patterns that match the contents directly. In prep_exclude, skip recursing into a directory only if it is really ignored (i.e. the ignore pattern is not negated). Signed-off-by: Karsten Blees <blees@dcon.de> Tested-by: Øystein Walle <oystwa@gmail.com> Reviewed-by: Duy Nguyen <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Karsten Blees committed May 29, 2013 at 22:32 UTC c3c327deeaf018e727a27f5ae88e140ff7a48595
2 files changed +21
dir.c
+3
@@ -821,6 +821,9 @@ static void prep_exclude(struct dir_struct *dir, const char *base, int baselen)
821 dir->basebuf, stk->baselen - 1,
822 dir->basebuf + current, &dt);
823 dir->basebuf[stk->baselen - 1] = '/';
824 + if (dir->exclude &&
825 + dir->exclude->flags & EXC_FLAG_NEGATIVE)
826 + dir->exclude = NULL;
827 if (dir->exclude) {
828 dir->basebuf[stk->baselen] = 0;
829 dir->exclude_stack = stk;
t/t3001-ls-files-others-exclude.sh
+18
@@ -175,6 +175,24 @@ test_expect_success 'negated exclude matches can override previous ones' '
175 grep "^a.1" output
176 '
177
178 +test_expect_success 'excluded directory overrides content patterns' '
179 +
180 + git ls-files --others --exclude="one" --exclude="!one/a.1" >output &&
181 + if grep "^one/a.1" output
182 + then
183 + false
184 + fi
185 +'
186 +
187 +test_expect_success 'negated directory doesn'\''t affect content patterns' '
188 +
189 + git ls-files --others --exclude="!one" --exclude="one/a.1" >output &&
190 + if grep "^one/a.1" output
191 + then
192 + false
193 + fi
194 +'
195 +
196 test_expect_success 'subdirectory ignore (setup)' '
197 mkdir -p top/l1/l2 &&
198 (