@@ -6,7 +6,6 @@ use crate::{CargoResult, GlobalContext};
66use anyhow:: Context ;
77use cargo_util:: paths;
88use gix:: bstr:: ByteSlice ;
9- use gix:: diff:: rewrites:: tracker:: Change ;
109use gix:: dir:: walk:: EmissionMode ;
1110use gix:: index:: entry:: Mode ;
1211use gix:: status:: tree_index:: TrackRenames ;
@@ -182,13 +181,11 @@ fn git(
182181 relative_package_root ( repo, pkg. root ( ) ) . as_deref ( ) ,
183182 & mut dirty_files,
184183 ) ?;
185- // super::collect_statuses(git_repo, &[pathspec.as_str()], &mut dirty_files)?;
186184
187185 // Include each submodule so that the error message can provide
188186 // specifically *which* files in a submodule are modified.
189187 status_submodules (
190188 repo,
191- workdir,
192189 & mut dirty_files,
193190 & mut dirty_files_outside_of_package_root,
194191 ) ?;
@@ -199,7 +196,22 @@ fn git(
199196 let cwd = ws. gctx ( ) . cwd ( ) ;
200197 let mut dirty_src_files: Vec < _ > = src_files
201198 . iter ( )
202- . filter ( |src_file| dirty_files. iter ( ) . any ( |path| src_file. starts_with ( path) ) )
199+ . filter ( |src_file| {
200+ if let Some ( canon_src_file) = src_file. is_symlink_or_under_symlink ( ) . then ( || {
201+ gix:: path:: realpath_opts (
202+ & src_file,
203+ ws. gctx ( ) . cwd ( ) ,
204+ gix:: path:: realpath:: MAX_SYMLINKS ,
205+ )
206+ . unwrap_or_else ( |_| src_file. to_path_buf ( ) )
207+ } ) {
208+ dirty_files
209+ . iter ( )
210+ . any ( |path| canon_src_file. starts_with ( path) )
211+ } else {
212+ dirty_files. iter ( ) . any ( |path| src_file. starts_with ( path) )
213+ }
214+ } )
203215 . map ( |p| p. as_ref ( ) )
204216 . chain (
205217 dirty_files_outside_pkg_root ( ws, pkg, & dirty_files_outside_of_package_root, src_files) ?
@@ -248,9 +260,10 @@ fn collect_statuses(
248260 . status ( gix:: progress:: Discard ) ?
249261 . dirwalk_options ( |opts| {
250262 opts. emit_untracked ( gix:: dir:: walk:: EmissionMode :: Matching )
251- // Also pick up ignored files (but not entire directories)
263+ // Also pick up ignored files or whole directories
252264 // to specifically catch overzealously ignored source files.
253- // Later we will match these dirs by prefix.
265+ // Later we will match these dirs by prefix, which is why collapsing
266+ // them is desirable here.
254267 . emit_ignored ( Some ( EmissionMode :: CollapseDirectory ) )
255268 . emit_tracked ( false )
256269 . recurse_repositories ( false )
@@ -295,13 +308,6 @@ fn collect_statuses(
295308 continue ;
296309 }
297310
298- // We completely ignore submodules
299- if matches ! (
300- status,
301- gix:: status:: Item :: TreeIndex ( change) if change. entry_mode( ) . is_commit( ) )
302- {
303- continue ;
304- }
305311 dirty_files. push ( path) ;
306312 }
307313 Ok ( dirty_files_outside_of_package_root)
@@ -310,7 +316,6 @@ fn collect_statuses(
310316/// Helper to collect dirty statuses while recursing into submodules.
311317fn status_submodules (
312318 repo : & gix:: Repository ,
313- workdir : & Path ,
314319 dirty_files : & mut Vec < PathBuf > ,
315320 dirty_files_outside_of_package_root : & mut Vec < PathBuf > ,
316321) -> CargoResult < ( ) > {
@@ -321,12 +326,10 @@ fn status_submodules(
321326 // Ignore submodules that don't open, they are probably not initialized.
322327 // If its files are required, then the verification step should fail.
323328 if let Some ( sub_repo) = submodule. open ( ) ? {
324- status_submodules (
325- & sub_repo,
326- workdir,
327- dirty_files,
328- dirty_files_outside_of_package_root,
329- ) ?;
329+ let Some ( workdir) = sub_repo. workdir ( ) else {
330+ continue ;
331+ } ;
332+ status_submodules ( & sub_repo, dirty_files, dirty_files_outside_of_package_root) ?;
330333 dirty_files_outside_of_package_root. extend ( collect_statuses (
331334 & sub_repo,
332335 workdir,
@@ -391,15 +394,10 @@ fn dirty_files_outside_pkg_root(
391394 )
392395 . unwrap_or_else ( |_| src_file. to_owned ( ) ) ;
393396
394- if dirty_files_outside_of_package_root
397+ dirty_files_outside_of_package_root
395398 . iter ( )
396399 . any ( |p| canon_src_path. starts_with ( p) )
397- {
398- // Use the canonicalized path as later we want to truncate it by the CWD, which is also canonicalized.
399- Some ( canon_src_path)
400- } else {
401- None
402- }
400+ . then_some ( canon_src_path)
403401 } )
404402 . collect ( ) ;
405403 Ok ( dirty_files)
0 commit comments