diff --git a/lib/src/conflicts.rs b/lib/src/conflicts.rs index b3f5c0827..48fb718d6 100644 --- a/lib/src/conflicts.rs +++ b/lib/src/conflicts.rs @@ -225,28 +225,37 @@ async fn materialize_tree_value_no_access_denied( Ok(Some(TreeValue::Conflict(_))) => { panic!("cannot materialize legacy conflict object at path {path:?}"); } - Err(conflict) => { - let Some(file_merge) = conflict.to_file_merge() else { - return Ok(MaterializedTreeValue::OtherConflict { id: conflict }); - }; - let file_merge = file_merge.simplify(); - let contents = extract_as_single_hunk(&file_merge, store, path).await?; - let executable = if let Some(merge) = conflict.to_executable_merge() { - merge.resolve_trivial().copied().unwrap_or_default() - } else { - false - }; - Ok(MaterializedTreeValue::FileConflict( - MaterializedFileConflictValue { - ids: file_merge, - contents, - executable, - }, - )) - } + Err(conflict) => match try_materialize_file_conflict_value(store, path, &conflict).await? { + Some(file) => Ok(MaterializedTreeValue::FileConflict(file)), + None => Ok(MaterializedTreeValue::OtherConflict { id: conflict }), + }, } } +/// Suppose `conflict` contains only files or absent entries, reads the file +/// contents. +async fn try_materialize_file_conflict_value( + store: &Store, + path: &RepoPath, + conflict: &MergedTreeValue, +) -> BackendResult> { + let Some(unsimplified_ids) = conflict.to_file_merge() else { + return Ok(None); + }; + let ids = unsimplified_ids.simplify(); + let contents = extract_as_single_hunk(&ids, store, path).await?; + let executable = if let Some(merge) = conflict.to_executable_merge() { + merge.resolve_trivial().copied().unwrap_or_default() + } else { + false + }; + Ok(Some(MaterializedFileConflictValue { + ids, + contents, + executable, + })) +} + /// Describes what style should be used when materializing conflicts. #[derive(Clone, Copy, PartialEq, Eq, Debug, Default, serde::Deserialize)] #[serde(rename_all = "kebab-case")]