Mercurial > hg-stable
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 } |