MCPcopy Create free account
hub / github.com/atomicdotdev/atomic / try_merge

Method try_merge

atomic-core/src/merge/engine.rs:89–250  ·  view source on GitHub ↗

Attempt to merge a conflict group using token-level semantics. # Algorithm 1. Extract the two competing vertices (only 2-way supported). 2. Retrieve content bytes for both from the [`ChangeStore`]. 3. Find the common ancestor vertex — the dead vertex that both competing changes deleted. 4. Retrieve content bytes for the ancestor. 5. Tokenize all three byte sequences. 6. Run a three-way diff at t

(&self, group: &ConflictGroup)

Source from the content-addressed store, hash-verified

87 ///
88 /// Returns [`PristineError`] on database access failure.
89 pub fn try_merge(&self, group: &ConflictGroup) -> Result<MergeOutcome, PristineError> {
90 // ── Step 1: Read content for every vertex in the group ────────
91 //
92 // If any vertex's content is unreadable we give up immediately.
93 let mut vertex_contents: Vec<(GraphNode<NodeId>, Vec<u8>)> = Vec::new();
94 for v in &group.vertices {
95 match self.get_vertex_content(v) {
96 Ok(c) => vertex_contents.push((*v, c)),
97 Err(e) => {
98 log::debug!("try_merge: cannot read vertex {}: {}", v, e);
99 return Ok(MergeOutcome::NoCrdtData);
100 }
101 }
102 }
103 if vertex_contents.is_empty() {
104 return Ok(MergeOutcome::NoCrdtData);
105 }
106
107 // ── Step 2: Deduplicate identical-content vertices ────────────
108 //
109 // Collapse vertices that share byte-identical content into a
110 // single representative. This handles the common N-way fork
111 // where multiple concurrent changes insert the same whitespace
112 // or the same boilerplate line. Indices of surviving (unique)
113 // vertices are collected in `unique`; everything else lands in
114 // `skipped` so the caller can mark them.
115 let mut unique: Vec<usize> = vec![0];
116 let mut skipped: Vec<usize> = Vec::new();
117 for i in 1..vertex_contents.len() {
118 if unique
119 .iter()
120 .any(|&j| vertex_contents[j].1 == vertex_contents[i].1)
121 {
122 skipped.push(i);
123 } else {
124 unique.push(i);
125 }
126 }
127
128 // All vertices identical — no conflict at all.
129 if unique.len() == 1 && !skipped.is_empty() {
130 log::info!(
131 "try_merge: all {} vertices identical ({} bytes), deduplicating",
132 vertex_contents.len(),
133 vertex_contents[0].1.len(),
134 );
135 return Ok(MergeOutcome::AutoMerged {
136 content: vertex_contents[0].1.clone(),
137 sources: vec![MergeSource::new(vertex_contents[0].0.change, 0)],
138 });
139 }
140
141 // Partial dedup: log, but continue with the unique subset.
142 if !skipped.is_empty() {
143 log::info!(
144 "try_merge: dedup reduced {}-way fork to {}-way",
145 vertex_contents.len(),
146 unique.len(),

Calls 10

is_token_subsequenceFunction · 0.85
get_vertex_contentMethod · 0.80
find_ancestor_contentMethod · 0.80
run_three_wayMethod · 0.80
tokenizeFunction · 0.70
pushMethod · 0.45
is_emptyMethod · 0.45
lenMethod · 0.45
iterMethod · 0.45
cloneMethod · 0.45