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 | impl Kind { | 193 | impl Kind { |
| 194 | fn is_recursable_dir(&self) -> bool { | 194 | pub(super) fn is_recursable_dir(&self) -> bool { |
| 195 | matches!(self, Kind::Directory) | 195 | matches!(self, Kind::Directory) |
| 196 | } | 196 | } |
| 197 | 197 | ||
| @@ -253,13 +253,6 @@ pub fn path( · 252 unmodified lines | |||
| 253 | .map_err(Error::ExcludesAccess)? | 253 | .map_err(Error::ExcludesAccess)? |
| 254 | { | 254 | { |
| 255 | if emit_ignored.is_some() { | 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 | if matches!( | 256 | if matches!( |
| 264 | for_deletion, | 257 | for_deletion, |
| 265 | Some( | 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 | return Ok(out | 276 | return Ok(out |
| 280 | .with_status(entry::Status::Ignored(excluded)) | 277 | .with_status(entry::Status::Ignored(excluded)) |
| @@ -159,6 +159,13 @@ git init partial-checkout-non-cone · 158 unmodified lines | |||
| 159 | mkdir d && touch d/file-created-manually | 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 | git init only-untracked | 169 | git init only-untracked |
| 163 | (cd only-untracked | 170 | (cd only-untracked |
| 164 | >a | 171 | >a |
| @@ -1208,6 +1208,38 @@ fn untracked_and_ignored_for_deletion_nonmatching_wildcard_spec() -> crate::Resu · 1207 unmodified lines | |||
| 1208 | ); | 1208 | ); |
| 1209 | Ok(()) | 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 | #[test] | 1244 | #[test] |
| 1213 | fn nested_ignored_dirs_for_deletion_nonmatching_wildcard_spec() -> crate::Result { | 1245 | fn nested_ignored_dirs_for_deletion_nonmatching_wildcard_spec() -> crate::Result { |