Skip to content

Commit 482d6f3

Browse files
committed
make sure that *foo* prefixes don't end up matching any directory.
Even though wildcard pathspecs shouldn't prevent recursion into direcotries, we should not end up declaring them as matches even though nothing inside matched.
1 parent a663e9f commit 482d6f3

File tree

3 files changed

+305
-18
lines changed

3 files changed

+305
-18
lines changed

gix-dir/src/walk/readdir.rs

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ pub(super) fn recursive(
6666
if can_recurse(current_bstr.as_bstr(), info, opts.for_deletion, delegate) {
6767
let (action, subdir_prevent_collapse) =
6868
recursive(false, current, current_bstr, info, ctx, opts, delegate, out, state)?;
69-
prevent_collapse = subdir_prevent_collapse;
69+
prevent_collapse |= subdir_prevent_collapse;
7070
if action != Action::Continue {
7171
break;
7272
}
@@ -158,6 +158,7 @@ impl Mark {
158158
} else {
159159
dir_info.disk_kind
160160
},
161+
pathspec_match: filter_dir_pathspec(dir_info.pathspec_match),
161162
..dir_info
162163
};
163164
if opts.should_hold(empty_info.status) {
@@ -174,18 +175,10 @@ impl Mark {
174175
}
175176
} else if *prevent_collapse {
176177
self.emit_all_held(state, opts, out, delegate)
177-
} else if let Some(action) = self.try_collapse(
178-
dir_rela_path,
179-
dir_info,
180-
state,
181-
prevent_collapse,
182-
out,
183-
opts,
184-
ctx,
185-
delegate,
186-
) {
178+
} else if let Some(action) = self.try_collapse(dir_rela_path, dir_info, state, out, opts, ctx, delegate) {
187179
action
188180
} else {
181+
*prevent_collapse = true;
189182
self.emit_all_held(state, opts, out, delegate)
190183
}
191184
}
@@ -213,7 +206,6 @@ impl Mark {
213206
dir_rela_path: &BStr,
214207
dir_info: classify::Outcome,
215208
state: &mut State,
216-
prevent_collapse: &mut bool,
217209
out: &mut walk::Outcome,
218210
opts: Options,
219211
ctx: &mut Context<'_>,
@@ -229,7 +221,6 @@ impl Mark {
229221
{
230222
entries += 1;
231223
if kind == Some(entry::Kind::Repository) {
232-
*prevent_collapse = true;
233224
return None;
234225
}
235226
if pathspec_match.map_or(false, |m| {
@@ -287,12 +278,10 @@ impl Mark {
287278
.filter_map(|e| e.pathspec_match)
288279
.max()
289280
.or_else(|| {
290-
// Only take directory matches for value if they are above the 'guessed' ones.
281+
// Only take directory matches as value if they are above the 'guessed' ones.
291282
// Otherwise we end up with seemingly matched entries in the parent directory which
292283
// affects proper folding.
293-
dir_info
294-
.pathspec_match
295-
.filter(|m| matches!(m, PathspecMatch::WildcardMatch | PathspecMatch::Verbatim))
284+
filter_dir_pathspec(dir_info.pathspec_match)
296285
});
297286
let mut removed_without_emitting = 0;
298287
let mut action = Action::Continue;
@@ -317,6 +306,15 @@ impl Mark {
317306
}
318307
}
319308

309+
fn filter_dir_pathspec(current: Option<PathspecMatch>) -> Option<PathspecMatch> {
310+
current.filter(|m| {
311+
matches!(
312+
m,
313+
PathspecMatch::Always | PathspecMatch::WildcardMatch | PathspecMatch::Verbatim
314+
)
315+
})
316+
}
317+
320318
impl Options {
321319
fn should_hold(&self, status: entry::Status) -> bool {
322320
if status.is_pruned() {

gix-dir/tests/fixtures/many.sh

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,16 @@ cp -R ignored-dir ignored-dir-with-nested-bare-repository
5757
git init --bare bare
5858
)
5959

60+
cp -R ignored-dir-with-nested-bare-repository ignored-dir-nested-minimal
61+
(cd ignored-dir-nested-minimal
62+
(cd bare
63+
rm -Rf hooks config description
64+
)
65+
(cd dir/subdir/nested-bare
66+
rm -Rf refs hooks config description
67+
)
68+
)
69+
6070
mkdir untracked-hidden-bare
6171
(cd untracked-hidden-bare
6272
mkdir subdir
@@ -245,6 +255,17 @@ git init expendable-and-precious
245255
git commit -m "init"
246256
)
247257

258+
git init expendable-and-precious-nested-in-ignored-dir
259+
(cd expendable-and-precious-nested-in-ignored-dir
260+
echo 'ignored/' > .gitignore
261+
git add .gitignore && git commit -m "init"
262+
mkdir -p ignored/other
263+
cp -Rv ../expendable-and-precious ignored/d
264+
rm -Rf ignored/d/*-by-filematch ignored/d/some-*
265+
mkdir -p other/ignored && >other/ignored/a
266+
)
267+
268+
248269
mkdir empty-and-untracked-dir
249270
(cd empty-and-untracked-dir
250271
mkdir empty untracked

0 commit comments

Comments
 (0)