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

Function plan_view_sync

atomic-cli/src/commands/push/helpers.rs:180–263  ·  view source on GitHub ↗

Compute the sync plan for one view: what to store and whether to declare. `remote` is the remote's parsed manifest, or `None` if the view does not exist on the remote (the remote log is empty). The fast-forward rule: the remote log must be a prefix of the local log. The suffix (everything beyond the prefix) is what needs storing — its dependencies are either earlier in the log or already on the

(
    local: &ViewManifest,
    remote: Option<&ViewManifest>,
    force: bool,
)

Source from the content-addressed store, hash-verified

178/// Identity mismatches (scope/parent) are never forced — they are
179/// structural, and the server would reject them regardless.
180pub fn plan_view_sync(
181 local: &ViewManifest,
182 remote: Option<&ViewManifest>,
183 force: bool,
184) -> Result<ViewSyncPlan, ViewSyncConflict> {
185 let remote = match remote {
186 None => {
187 // View absent on remote: the whole log is the suffix.
188 return Ok(ViewSyncPlan {
189 suffix: local.changes.clone(),
190 declare: true,
191 forced: false,
192 });
193 }
194 Some(r) => r,
195 };
196
197 // Identity must match: the manifest declares scope and parent, and the
198 // server refuses to mutate an existing view's identity.
199 if remote.scope != local.scope {
200 return Err(ViewSyncConflict::IdentityMismatch {
201 field: "scope",
202 local: local.scope.to_string(),
203 remote: remote.scope.to_string(),
204 });
205 }
206 if remote.parent != local.parent {
207 let show = |p: &Option<String>| p.clone().unwrap_or_else(|| "(none)".to_string());
208 return Err(ViewSyncConflict::IdentityMismatch {
209 field: "parent",
210 local: show(&local.parent),
211 remote: show(&remote.parent),
212 });
213 }
214
215 // Prefix rule.
216 let diverged = if remote.changes.len() > local.changes.len() {
217 Some(ViewSyncConflict::Diverged {
218 first_mismatch: None,
219 local_len: local.changes.len(),
220 remote_len: remote.changes.len(),
221 })
222 } else {
223 remote
224 .changes
225 .iter()
226 .zip(local.changes.iter())
227 .position(|(r, l)| r != l)
228 .map(|i| ViewSyncConflict::Diverged {
229 first_mismatch: Some(i),
230 local_len: local.changes.len(),
231 remote_len: remote.changes.len(),
232 })
233 };
234
235 if let Some(conflict) = diverged {
236 if !force {
237 return Err(conflict);

Calls 6

cloneMethod · 0.45
lenMethod · 0.45
positionMethod · 0.45
iterMethod · 0.45
containsMethod · 0.45
is_emptyMethod · 0.45