##// END OF EJS Templates
rhg: fix race when an ambiguous file is deleted on disk...
Raphaël Gomès -
r51121:8fcd5302 stable
parent child Browse files
Show More
@@ -299,25 +299,45 b' pub fn run(invocation: &crate::CliInvoca'
299 299 .unsure
300 300 .into_par_iter()
301 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 307 working_directory_vfs,
304 308 store_vfs,
305 309 &manifest,
306 310 &to_check.path,
307 )
308 .map(|modified| (to_check, modified))
311 ) {
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 322 .collect::<Result<_, _>>()?;
311 for (status_path, is_modified) in res.into_iter() {
312 if is_modified {
313 if display_states.modified {
314 ds_status.modified.push(status_path);
323 for (status_path, outcome) in res.into_iter() {
324 match outcome {
325 UnsureOutcome::Clean => {
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 {
317 if display_states.clean {
318 ds_status.clean.push(status_path.clone());
331 UnsureOutcome::Modified => {
332 if display_states.modified {
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 590 /// Check if a file is modified by comparing actual repo store and file system.
561 591 ///
562 592 /// This meant to be used for those that the dirstate cannot resolve, due
@@ -566,7 +596,7 b' fn unsure_is_modified('
566 596 store_vfs: hg::vfs::Vfs,
567 597 manifest: &Manifest,
568 598 hg_path: &HgPath,
569 ) -> Result<bool, HgError> {
599 ) -> Result<UnsureOutcome, HgError> {
570 600 let vfs = working_directory_vfs;
571 601 let fs_path = hg_path_to_path_buf(hg_path).expect("HgPath conversion");
572 602 let fs_metadata = vfs.symlink_metadata(&fs_path)?;
@@ -585,7 +615,7 b' fn unsure_is_modified('
585 615 .find_by_path(hg_path)?
586 616 .expect("ambgious file not in p1");
587 617 if entry.flags != fs_flags {
588 return Ok(true);
618 return Ok(UnsureOutcome::Modified);
589 619 }
590 620 let filelog = hg::filelog::Filelog::open_vfs(&store_vfs, hg_path)?;
591 621 let fs_len = fs_metadata.len();
@@ -599,7 +629,7 b' fn unsure_is_modified('
599 629 if filelog_entry.file_data_len_not_equal_to(fs_len) {
600 630 // No need to read file contents:
601 631 // it cannot be equal if it has a different length.
602 return Ok(true);
632 return Ok(UnsureOutcome::Modified);
603 633 }
604 634
605 635 let p1_filelog_data = filelog_entry.data()?;
@@ -607,7 +637,7 b' fn unsure_is_modified('
607 637 if p1_contents.len() as u64 != fs_len {
608 638 // No need to read file contents:
609 639 // it cannot be equal if it has a different length.
610 return Ok(true);
640 return Ok(UnsureOutcome::Modified);
611 641 }
612 642
613 643 let fs_contents = if is_symlink {
@@ -615,7 +645,12 b' fn unsure_is_modified('
615 645 } else {
616 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 656 fn print_pattern_file_warning(
General Comments 0
You need to be logged in to leave comments. Login now