Show More
@@ -299,25 +299,45 b' pub fn run(invocation: &crate::CliInvoca' | |||||
299 | .unsure |
|
299 | .unsure | |
300 | .into_par_iter() |
|
300 | .into_par_iter() | |
301 | .map(|to_check| { |
|
301 | .map(|to_check| { | |
302 | unsure_is_modified( |
|
302 | // The compiler seems to get a bit confused with complex | |
|
303 | // inference when using a parallel iterator + map | |||
|
304 | // + map_err + collect, so let's just inline some of the | |||
|
305 | // logic. | |||
|
306 | match unsure_is_modified( | |||
303 | working_directory_vfs, |
|
307 | working_directory_vfs, | |
304 | store_vfs, |
|
308 | store_vfs, | |
305 | &manifest, |
|
309 | &manifest, | |
306 | &to_check.path, |
|
310 | &to_check.path, | |
307 | ) |
|
311 | ) { | |
308 | .map(|modified| (to_check, modified)) |
|
312 | Err(HgError::IoError { .. }) => { | |
|
313 | // IO errors most likely stem from the file being | |||
|
314 | // deleted even though we know it's in the | |||
|
315 | // dirstate. | |||
|
316 | Ok((to_check, UnsureOutcome::Deleted)) | |||
|
317 | } | |||
|
318 | Ok(outcome) => Ok((to_check, outcome)), | |||
|
319 | Err(e) => Err(e), | |||
|
320 | } | |||
309 | }) |
|
321 | }) | |
310 | .collect::<Result<_, _>>()?; |
|
322 | .collect::<Result<_, _>>()?; | |
311 |
for (status_path, |
|
323 | for (status_path, outcome) in res.into_iter() { | |
312 |
|
|
324 | match outcome { | |
313 | if display_states.modified { |
|
325 | UnsureOutcome::Clean => { | |
314 |
|
|
326 | if display_states.clean { | |
|
327 | ds_status.clean.push(status_path.clone()); | |||
|
328 | } | |||
|
329 | fixup.push(status_path.path.into_owned()) | |||
315 | } |
|
330 | } | |
316 | } else { |
|
331 | UnsureOutcome::Modified => { | |
317 |
if display_states. |
|
332 | if display_states.modified { | |
318 |
ds_status. |
|
333 | ds_status.modified.push(status_path); | |
|
334 | } | |||
319 | } |
|
335 | } | |
320 | fixup.push(status_path.path.into_owned()) |
|
336 | UnsureOutcome::Deleted => { | |
|
337 | if display_states.deleted { | |||
|
338 | ds_status.deleted.push(status_path); | |||
|
339 | } | |||
|
340 | } | |||
321 | } |
|
341 | } | |
322 | } |
|
342 | } | |
323 | } |
|
343 | } | |
@@ -557,6 +577,16 b" impl DisplayStatusPaths<'_> {" | |||||
557 | } |
|
577 | } | |
558 | } |
|
578 | } | |
559 |
|
579 | |||
|
580 | /// Outcome of the additional check for an ambiguous tracked file | |||
|
581 | enum UnsureOutcome { | |||
|
582 | /// The file is actually clean | |||
|
583 | Clean, | |||
|
584 | /// The file has been modified | |||
|
585 | Modified, | |||
|
586 | /// The file was deleted on disk (or became another type of fs entry) | |||
|
587 | Deleted, | |||
|
588 | } | |||
|
589 | ||||
560 | /// Check if a file is modified by comparing actual repo store and file system. |
|
590 | /// Check if a file is modified by comparing actual repo store and file system. | |
561 | /// |
|
591 | /// | |
562 | /// This meant to be used for those that the dirstate cannot resolve, due |
|
592 | /// This meant to be used for those that the dirstate cannot resolve, due | |
@@ -566,7 +596,7 b' fn unsure_is_modified(' | |||||
566 | store_vfs: hg::vfs::Vfs, |
|
596 | store_vfs: hg::vfs::Vfs, | |
567 | manifest: &Manifest, |
|
597 | manifest: &Manifest, | |
568 | hg_path: &HgPath, |
|
598 | hg_path: &HgPath, | |
569 |
) -> Result< |
|
599 | ) -> Result<UnsureOutcome, HgError> { | |
570 | let vfs = working_directory_vfs; |
|
600 | let vfs = working_directory_vfs; | |
571 | let fs_path = hg_path_to_path_buf(hg_path).expect("HgPath conversion"); |
|
601 | let fs_path = hg_path_to_path_buf(hg_path).expect("HgPath conversion"); | |
572 | let fs_metadata = vfs.symlink_metadata(&fs_path)?; |
|
602 | let fs_metadata = vfs.symlink_metadata(&fs_path)?; | |
@@ -585,7 +615,7 b' fn unsure_is_modified(' | |||||
585 | .find_by_path(hg_path)? |
|
615 | .find_by_path(hg_path)? | |
586 | .expect("ambgious file not in p1"); |
|
616 | .expect("ambgious file not in p1"); | |
587 | if entry.flags != fs_flags { |
|
617 | if entry.flags != fs_flags { | |
588 |
return Ok( |
|
618 | return Ok(UnsureOutcome::Modified); | |
589 | } |
|
619 | } | |
590 | let filelog = hg::filelog::Filelog::open_vfs(&store_vfs, hg_path)?; |
|
620 | let filelog = hg::filelog::Filelog::open_vfs(&store_vfs, hg_path)?; | |
591 | let fs_len = fs_metadata.len(); |
|
621 | let fs_len = fs_metadata.len(); | |
@@ -599,7 +629,7 b' fn unsure_is_modified(' | |||||
599 | if filelog_entry.file_data_len_not_equal_to(fs_len) { |
|
629 | if filelog_entry.file_data_len_not_equal_to(fs_len) { | |
600 | // No need to read file contents: |
|
630 | // No need to read file contents: | |
601 | // it cannot be equal if it has a different length. |
|
631 | // it cannot be equal if it has a different length. | |
602 |
return Ok( |
|
632 | return Ok(UnsureOutcome::Modified); | |
603 | } |
|
633 | } | |
604 |
|
634 | |||
605 | let p1_filelog_data = filelog_entry.data()?; |
|
635 | let p1_filelog_data = filelog_entry.data()?; | |
@@ -607,7 +637,7 b' fn unsure_is_modified(' | |||||
607 | if p1_contents.len() as u64 != fs_len { |
|
637 | if p1_contents.len() as u64 != fs_len { | |
608 | // No need to read file contents: |
|
638 | // No need to read file contents: | |
609 | // it cannot be equal if it has a different length. |
|
639 | // it cannot be equal if it has a different length. | |
610 |
return Ok( |
|
640 | return Ok(UnsureOutcome::Modified); | |
611 | } |
|
641 | } | |
612 |
|
642 | |||
613 | let fs_contents = if is_symlink { |
|
643 | let fs_contents = if is_symlink { | |
@@ -615,7 +645,12 b' fn unsure_is_modified(' | |||||
615 | } else { |
|
645 | } else { | |
616 | vfs.read(fs_path)? |
|
646 | vfs.read(fs_path)? | |
617 | }; |
|
647 | }; | |
618 | Ok(p1_contents != &*fs_contents) |
|
648 | ||
|
649 | Ok(if p1_contents != &*fs_contents { | |||
|
650 | UnsureOutcome::Modified | |||
|
651 | } else { | |||
|
652 | UnsureOutcome::Clean | |||
|
653 | }) | |||
619 | } |
|
654 | } | |
620 |
|
655 | |||
621 | fn print_pattern_file_warning( |
|
656 | fn print_pattern_file_warning( |
General Comments 0
You need to be logged in to leave comments.
Login now