comparison rust/rhg/src/commands/status.rs @ 48575:e91aa800ae5b

rhg: desambiguate status without decompressing filelog if possible When status is unsure based on `stat()` and the dirstate if a file is clean or modified, we need to compare it against the filelog. This comparison can skip looking at contents if the lengths differ. This changeset optimize this further to deduce what we can about the length if the filelog without decompressing it or resolving deltas. Differential Revision: https://phab.mercurial-scm.org/D11965
author Simon Sapin <simon.sapin@octobus.net>
date Fri, 07 Jan 2022 14:40:21 +0100
parents 35c47015b9b7
children 99b1dfc06571
comparison
equal deleted inserted replaced
48574:5026a0d37526 48575:e91aa800ae5b
514 let fs_len = fs_metadata.len(); 514 let fs_len = fs_metadata.len();
515 let filelog_entry = 515 let filelog_entry =
516 filelog.entry_for_node(entry.node_id()?).map_err(|_| { 516 filelog.entry_for_node(entry.node_id()?).map_err(|_| {
517 HgError::corrupted("filelog missing node from manifest") 517 HgError::corrupted("filelog missing node from manifest")
518 })?; 518 })?;
519 // TODO: check `fs_len` here like below, but based on 519 if filelog_entry.file_data_len_not_equal_to(fs_len) {
520 // `RevlogEntry::uncompressed_len` without decompressing the full filelog 520 // No need to read file contents:
521 // contents where possible. This is only valid if the revlog data does not 521 // it cannot be equal if it has a different length.
522 // contain metadata. See how Python’s `revlog.rawsize` calls 522 return Ok(true);
523 // `storageutil.filerevisioncopied`. 523 }
524 // (Maybe also check for content-modifying flags? See `revlog.size`.) 524
525 let filelog_data = filelog_entry.data()?; 525 let p1_filelog_data = filelog_entry.data()?;
526 let contents_in_p1 = filelog_data.file_data()?; 526 let p1_contents = p1_filelog_data.file_data()?;
527 if contents_in_p1.len() as u64 != fs_len { 527 if p1_contents.len() as u64 != fs_len {
528 // No need to read the file contents: 528 // No need to read file contents:
529 // it cannot be equal if it has a different length. 529 // it cannot be equal if it has a different length.
530 return Ok(true); 530 return Ok(true);
531 } 531 }
532 532
533 let fs_contents = if is_symlink { 533 let fs_contents = if is_symlink {
534 get_bytes_from_os_string(vfs.read_link(fs_path)?.into_os_string()) 534 get_bytes_from_os_string(vfs.read_link(fs_path)?.into_os_string())
535 } else { 535 } else {
536 vfs.read(fs_path)? 536 vfs.read(fs_path)?
537 }; 537 };
538 Ok(contents_in_p1 != &*fs_contents) 538 Ok(p1_contents != &*fs_contents)
539 } 539 }