tree: don't read file contents on contents/executable "conflict"

If one side changes the contents and one side changes the executable
bit, we get a non-trivial conflict in the `TreeValue`s, but once we've
split them up into `FileId`s and bools, we can trivially resolve them
separately, without having to read file contents.
This commit is contained in:
Martin von Zweigbergk 2023-06-12 13:31:44 -07:00 committed by Martin von Zweigbergk
parent 6e6ca16fd4
commit 02bb3aecf3

View file

@ -680,11 +680,19 @@ fn try_resolve_file_conflict(
} }
let executable = if let Some(executable) = trivial_merge(&executable_removes, &executable_adds) let executable = if let Some(executable) = trivial_merge(&executable_removes, &executable_adds)
{ {
executable *executable
} else { } else {
// We're unable to determine whether the result should be executable // We're unable to determine whether the result should be executable
return Ok(None); return Ok(None);
}; };
if let Some(resolved_file_id) = trivial_merge(&removed_file_ids, &added_file_ids) {
// Don't bother reading the file contents if the conflict can be trivially
// resolved.
return Ok(Some(TreeValue::File {
id: resolved_file_id.clone(),
executable,
}));
}
let mut removed_contents = vec![]; let mut removed_contents = vec![];
let mut added_contents = vec![]; let mut added_contents = vec![];
for file_id in removed_file_ids { for file_id in removed_file_ids {
@ -716,10 +724,7 @@ fn try_resolve_file_conflict(
match merge_result { match merge_result {
MergeResult::Resolved(merged_content) => { MergeResult::Resolved(merged_content) => {
let id = store.write_file(filename, &mut merged_content.as_slice())?; let id = store.write_file(filename, &mut merged_content.as_slice())?;
Ok(Some(TreeValue::File { Ok(Some(TreeValue::File { id, executable }))
id,
executable: *executable,
}))
} }
MergeResult::Conflict(_) => Ok(None), MergeResult::Conflict(_) => Ok(None),
} }