A repository may be emitted on its own accord, without having to go through the folding logic which filters directories that have been 'prefix' matched.
Unified · Split
| @@ -191,7 +191,7 @@ impl Status { · 190 unmodified lines | ||
| 191 | 191 | } |
| 192 | 192 | |
| 193 | 193 | impl Kind { |
| 194 | − fn is_recursable_dir(&self) -> bool { | |
| 194 | + pub(super) fn is_recursable_dir(&self) -> bool { | |
| 195 | 195 | matches!(self, Kind::Directory) |
| 196 | 196 | } |
| 197 | 197 | |
| @@ -253,13 +253,6 @@ pub fn path( · 252 unmodified lines | ||
| 253 | 253 | .map_err(Error::ExcludesAccess)? |
| 254 | 254 | { |
| 255 | 255 | if emit_ignored.is_some() { |
| 256 | − if kind.map_or(false, |d| d.is_dir()) && out.pathspec_match.is_none() { | |
| 257 | − // we have patterns that didn't match at all. Try harder. | |
| 258 | − out.pathspec_match = ctx | |
| 259 | − .pathspec | |
| 260 | − .directory_matches_prefix(rela_path.as_bstr(), true) | |
| 261 | − .then_some(PathspecMatch::Prefix); | |
| 262 | − } | |
| 263 | 256 | if matches!( |
| 264 | 257 | for_deletion, |
| 265 | 258 | Some( |
| @@ -275,6 +268,10 @@ pub fn path( · 9 unmodified lines | ||
| 275 | 268 | ), |
| 276 | 269 | ); |
| 277 | 270 | } |
| 271 | + if kind.map_or(false, |d| d.is_recursable_dir()) && out.pathspec_match.is_none() { | |
| 272 | + // we have patterns that didn't match at all, *yet*. We want to look inside. | |
| 273 | + out.pathspec_match = Some(PathspecMatch::Prefix); | |
| 274 | + } | |
| 278 | 275 | } |
| 279 | 276 | return Ok(out |
| 280 | 277 | .with_status(entry::Status::Ignored(excluded)) |
| @@ -159,6 +159,13 @@ git init partial-checkout-non-cone · 158 unmodified lines | ||
| 159 | 159 | mkdir d && touch d/file-created-manually |
| 160 | 160 | ) |
| 161 | 161 | |
| 162 | +git init precious-nested-repository | |
| 163 | +(cd precious-nested-repository | |
| 164 | + echo '$precious*/' > .gitignore | |
| 165 | + git init precious-repo | |
| 166 | + git add .gitignore && git commit -m "init" | |
| 167 | +) | |
| 168 | + | |
| 162 | 169 | git init only-untracked |
| 163 | 170 | (cd only-untracked |
| 164 | 171 | >a |
| @@ -1208,6 +1208,38 @@ fn untracked_and_ignored_for_deletion_nonmatching_wildcard_spec() -> crate::Resu · 1207 unmodified lines | ||
| 1208 | 1208 | ); |
| 1209 | 1209 | Ok(()) |
| 1210 | 1210 | } |
| 1211 | +#[test] | |
| 1212 | +fn nested_precious_repo_respects_wildcards() -> crate::Result { | |
| 1213 | + let root = fixture("precious-nested-repository"); | |
| 1214 | + for for_deletion in [ | |
| 1215 | + Some(ForDeletionMode::FindNonBareRepositoriesInIgnoredDirectories), | |
| 1216 | + Some(ForDeletionMode::FindRepositoriesInIgnoredDirectories), | |
| 1217 | + ] { | |
| 1218 | + let (_out, entries) = collect_filtered( | |
| 1219 | + &root, | |
| 1220 | + None, | |
| 1221 | + |keep, ctx| { | |
| 1222 | + walk( | |
| 1223 | + &root, | |
| 1224 | + ctx, | |
| 1225 | + walk::Options { | |
| 1226 | + emit_ignored: Some(CollapseDirectory), | |
| 1227 | + emit_untracked: CollapseDirectory, | |
| 1228 | + emit_pruned: false, | |
| 1229 | + for_deletion, | |
| 1230 | + ..options() | |
| 1231 | + }, | |
| 1232 | + keep, | |
| 1233 | + ) | |
| 1234 | + }, | |
| 1235 | + Some("*foo/"), | |
| 1236 | + ); | |
| 1237 | + // NOTE: do not use `_out` as `.git` directory contents can change, it's controlled by Git, causing flakiness. | |
| 1238 | + | |
| 1239 | + assert_eq!(entries, [], "nothing matches, of course"); | |
| 1240 | + } | |
| 1241 | + Ok(()) | |
| 1242 | +} | |
| 1211 | 1243 | |
| 1212 | 1244 | #[test] |
| 1213 | 1245 | fn nested_ignored_dirs_for_deletion_nonmatching_wildcard_spec() -> crate::Result { |