(
txn: &atomic_core::pristine::ReadTxn,
store: &C,
inode_graph_table: &redb::ReadOnlyMultimapTable<&'static [u8; 32], &'static [u8; 24]>,
change_filter_arc: &Arc<std::collections::Hash
| 185 | /// deterministic order so the rendering is stable across runs. |
| 186 | #[allow(clippy::too_many_arguments)] |
| 187 | fn render_name_conflict<C: atomic_core::change::ChangeStore>( |
| 188 | txn: &atomic_core::pristine::ReadTxn, |
| 189 | store: &C, |
| 190 | inode_graph_table: &redb::ReadOnlyMultimapTable<&'static [u8; 32], &'static [u8; 24]>, |
| 191 | change_filter_arc: &Arc<std::collections::HashSet<NodeId>>, |
| 192 | path: &str, |
| 193 | sides: &[(Inode, Position<NodeId>)], |
| 194 | ) -> Result<Vec<u8>, String> { |
| 195 | use atomic_core::output::repo::{ |
| 196 | output_graph_content_resolved, resolve_conflicts_semantically, |
| 197 | }; |
| 198 | use atomic_core::output::{compute_order, retrieve_graph, RetrieveOptions, Writer}; |
| 199 | use atomic_core::pristine::InodePreloadTxn; |
| 200 | |
| 201 | let mut out: Vec<u8> = Vec::new(); |
| 202 | for (i, (inode, position)) in sides.iter().enumerate() { |
| 203 | if i == 0 { |
| 204 | out.extend_from_slice(format!(">>>>>>> {} (name conflict)\n", path).as_bytes()); |
| 205 | } else { |
| 206 | out.extend_from_slice(b"=======\n"); |
| 207 | } |
| 208 | |
| 209 | let preloaded = InodePreloadTxn::from_table(txn, *inode, inode_graph_table) |
| 210 | .map_err(|e| format!("{}: name-conflict preload: {:?}", path, e))?; |
| 211 | let retrieve_opts = |
| 212 | RetrieveOptions::default().with_change_filter_arc(change_filter_arc.clone()); |
| 213 | let retrieve_result = retrieve_graph(&preloaded, *position, retrieve_opts) |
| 214 | .map_err(|e| format!("{}: name-conflict retrieve: {:?}", path, e))?; |
| 215 | let mut graph = retrieve_result.graph; |
| 216 | let order = compute_order(&mut graph); |
| 217 | let resolved = resolve_conflicts_semantically(&preloaded, store, &graph, &order); |
| 218 | let buffer = Vec::with_capacity(graph.total_bytes()); |
| 219 | let mut writer = Writer::new(buffer); |
| 220 | let hash_fn = |node_id: NodeId| -> Option<Hash> { |
| 221 | if node_id.is_root() { |
| 222 | return None; |
| 223 | } |
| 224 | preloaded.get_external(node_id).ok().flatten() |
| 225 | }; |
| 226 | output_graph_content_resolved(store, hash_fn, &graph, &order, &mut writer, &resolved) |
| 227 | .map_err(|e| format!("{}: name-conflict content: {:?}", path, e))?; |
| 228 | let side = writer.into_inner(); |
| 229 | out.extend_from_slice(&side); |
| 230 | if !side.ends_with(b"\n") { |
| 231 | out.push(b'\n'); |
| 232 | } |
| 233 | } |
| 234 | out.extend_from_slice(format!("<<<<<<< {} (name conflict)\n", path).as_bytes()); |
| 235 | Ok(out) |
| 236 | } |
| 237 | |
| 238 | impl Repository { |
| 239 | /// Persist the conflict state discovered by a materialize into the |
no test coverage detected