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

Method try_squash_insert

atomic-cli/src/commands/git/parallel.rs:2765–2861  ·  view source on GitHub ↗

Attempt to represent an atomic-origin squash commit by inserting its original change records into the target view instead of writing a new squash change (SPEC §4). Verifies that the insert reproduces the git tree for the touched paths; on divergence or missing originals it rolls back and skips the commit (SPEC §5, decision D1-A).

(
        &self,
        repo: &mut Repository,
        parsed: &ParsedCommit,
    )

Source from the content-addressed store, hash-verified

2763 /// tree for the touched paths; on divergence or missing originals it rolls
2764 /// back and skips the commit (SPEC §5, decision D1-A).
2765 fn try_squash_insert(
2766 &self,
2767 repo: &mut Repository,
2768 parsed: &ParsedCommit,
2769 ) -> CliResult<SquashDecision> {
2770 use atomic_repository::InsertOptions;
2771
2772 // Merges are handled by the normal path + the phase-3 merge tag.
2773 if parsed.is_merge {
2774 return Ok(SquashDecision::NotSquash);
2775 }
2776
2777 // Must carry Atomic-Changes trailers to be an atomic-origin squash.
2778 let message = parsed.full_message();
2779 let original_hashes = match parse_atomic_changes_trailer(&message) {
2780 Some(h) => h,
2781 None => return Ok(SquashDecision::NotSquash),
2782 };
2783 let pr_number = parse_pr_number(&message);
2784
2785 // Resolve every original to a Hash and confirm it exists locally. A
2786 // missing original means we cannot reconstruct the aggregate — skip and
2787 // advise `atomic pull` rather than fabricate a squash change (SPEC §5).
2788 let mut parsed_hashes: Vec<ContentHash> = Vec::with_capacity(original_hashes.len());
2789 for h in &original_hashes {
2790 match ContentHash::from_base32(h.as_bytes()) {
2791 Some(hash) if repo.has_change(&hash) => parsed_hashes.push(hash),
2792 _ => {
2793 print_warning(&format!(
2794 "Squash {} references change {} which is not present locally; \
2795 skipping (run `atomic pull` to fetch it, then re-import).",
2796 parsed.short_sha, h
2797 ));
2798 return Ok(SquashDecision::Skipped);
2799 }
2800 }
2801 }
2802
2803 let target = self.options.target_view.clone();
2804
2805 // Insert the originals (with dependency closure) into the target view.
2806 // Track exactly which changes we newly added, for rollback on divergence.
2807 let mut newly_applied: Vec<ContentHash> = Vec::new();
2808 for hash in &parsed_hashes {
2809 let options = InsertOptions::default()
2810 .view(target.clone())
2811 .apply_deps(true);
2812 match repo.insert_change_rec(hash, options) {
2813 Ok(outcome) => {
2814 newly_applied.extend(outcome.stats.applied_hashes.iter().copied());
2815 }
2816 Err(e) => {
2817 print_warning(&format!(
2818 "Squash {}: failed to insert original {}: {}; skipping.",
2819 parsed.short_sha,
2820 &hash.to_base32()[..12],
2821 e
2822 ));

Callers 1

phase2_writeMethod · 0.80

Calls 15

parse_pr_numberFunction · 0.85
print_warningFunction · 0.85
rollback_insertsFunction · 0.85
full_messageMethod · 0.80
apply_depsMethod · 0.80
insert_change_recMethod · 0.80
extendMethod · 0.80
lastMethod · 0.80
index_git_shaMethod · 0.80
lenMethod · 0.45

Tested by

no test coverage detected