working_copy: avoid adding unchanged values to tree builder

If the value at a path hasn't changed, there's no need to send it over
the channel and have the receiver add it to `TreeBuilder`. I couldn't
measure any performance impact.

Now we should no longer send `TreeValue::Conflict` variants over the
tree entry channel.
This commit is contained in:
Martin von Zweigbergk 2023-08-14 10:57:59 -07:00 committed by Martin von Zweigbergk
parent eacdad3ebd
commit 3f97a6da78

View file

@ -955,16 +955,24 @@ impl TreeState {
} else { } else {
let new_file_type = new_file_state.file_type.clone(); let new_file_type = new_file_state.file_type.clone();
let current_tree_value = current_tree.path_value(repo_path); let current_tree_value = current_tree.path_value(repo_path);
let new_tree_value = let new_tree_value = self.write_path_to_store(
self.write_path_to_store(repo_path, &disk_path, current_tree_value, new_file_type)?; repo_path,
&disk_path,
&current_tree_value,
new_file_type,
)?;
if new_tree_value.as_resolved() != Some(&current_tree_value) {
Ok(Some(new_tree_value)) Ok(Some(new_tree_value))
} else {
Ok(None)
}
} }
} }
fn write_path_to_store( fn write_path_to_store(
&self, &self,
repo_path: &RepoPath, repo_path: &RepoPath,
disk_path: &Path, disk_path: &Path,
current_tree_value: Option<TreeValue>, current_tree_value: &Option<TreeValue>,
file_type: FileType, file_type: FileType,
) -> Result<Merge<Option<TreeValue>>, SnapshotError> { ) -> Result<Merge<Option<TreeValue>>, SnapshotError> {
let executable = match file_type { let executable = match file_type {
@ -978,7 +986,7 @@ impl TreeState {
// If the file contained a conflict before and is now a normal file on disk, we // If the file contained a conflict before and is now a normal file on disk, we
// try to parse any conflict markers in the file into a conflict. // try to parse any conflict markers in the file into a conflict.
if let Some(TreeValue::Conflict(conflict_id)) = &current_tree_value { if let Some(TreeValue::Conflict(conflict_id)) = current_tree_value {
let conflict = self.store.read_conflict(repo_path, conflict_id)?; let conflict = self.store.read_conflict(repo_path, conflict_id)?;
if let Some(old_file_ids) = conflict.to_file_merge() { if let Some(old_file_ids) = conflict.to_file_merge() {
let content = fs::read(disk_path).map_err(|err| SnapshotError::IoError { let content = fs::read(disk_path).map_err(|err| SnapshotError::IoError {
@ -1021,7 +1029,7 @@ impl TreeState {
let executable = { let executable = {
let () = executable; // use the variable let () = executable; // use the variable
if let Some(TreeValue::File { id: _, executable }) = current_tree_value { if let Some(TreeValue::File { id: _, executable }) = current_tree_value {
executable *executable
} else { } else {
false false
} }