Run a three-way merge given a known base.
(
&self,
base: &[u8],
left: &[u8],
right: &[u8],
v_left: &GraphNode<NodeId>,
v_right: &GraphNode<NodeId>,
)
| 251 | |
| 252 | /// Run a three-way merge given a known base. |
| 253 | fn run_three_way( |
| 254 | &self, |
| 255 | base: &[u8], |
| 256 | left: &[u8], |
| 257 | right: &[u8], |
| 258 | v_left: &GraphNode<NodeId>, |
| 259 | v_right: &GraphNode<NodeId>, |
| 260 | ) -> Result<MergeOutcome, PristineError> { |
| 261 | let base_tokens = tokenize(base); |
| 262 | let left_tokens = tokenize(left); |
| 263 | let right_tokens = tokenize(right); |
| 264 | |
| 265 | match three_way_merge(&base_tokens, &left_tokens, &right_tokens) { |
| 266 | ThreeWayResult::Merged(content) => { |
| 267 | log::debug!( |
| 268 | "try_merge: auto-merged {} + {} → {} bytes", |
| 269 | left.len(), |
| 270 | right.len(), |
| 271 | content.len(), |
| 272 | ); |
| 273 | let left_token_count = left_tokens |
| 274 | .iter() |
| 275 | .zip(base_tokens.iter()) |
| 276 | .filter(|(l, b)| l != b) |
| 277 | .count(); |
| 278 | let right_token_count = right_tokens |
| 279 | .iter() |
| 280 | .zip(base_tokens.iter()) |
| 281 | .filter(|(r, b)| r != b) |
| 282 | .count(); |
| 283 | Ok(MergeOutcome::AutoMerged { |
| 284 | content, |
| 285 | sources: vec![ |
| 286 | MergeSource::new(v_left.change, left_token_count), |
| 287 | MergeSource::new(v_right.change, right_token_count), |
| 288 | ], |
| 289 | }) |
| 290 | } |
| 291 | ThreeWayResult::Conflict => { |
| 292 | log::debug!("try_merge: conflict between {} and {}", v_left, v_right); |
| 293 | Ok(MergeOutcome::Conflict { |
| 294 | base: base.to_vec(), |
| 295 | left: left.to_vec(), |
| 296 | right: right.to_vec(), |
| 297 | left_change: v_left.change, |
| 298 | right_change: v_right.change, |
| 299 | }) |
| 300 | } |
| 301 | } |
| 302 | } |
| 303 | |
| 304 | /// Read the content bytes for a graph vertex from the change store. |
| 305 | /// |
no test coverage detected