Skip to main content

objects/transfer/
mod.rs

1// SPDX-License-Identifier: Apache-2.0
2//! Transfer planning for Heddle object lanes.
3//!
4//! One vocabulary for local sync, hosted sync, and the wire protocol:
5//! content-addressed objects that can ride the native pack, and signed
6//! sidecars that must use the out-of-pack verification paths.
7
8pub mod availability;
9pub mod graph;
10pub mod plan;
11
12pub use availability::{ObjectAvailabilityPlan, has_object, plan_object_availability};
13#[cfg(feature = "async-source")]
14pub use graph::is_ancestor_async;
15#[cfg(feature = "async-source")]
16pub use graph::{AncestryBudget, AncestryError, is_ancestor_async_bounded};
17pub use graph::{
18    ObjectId, ObjectInfo, ObjectType, ObjectTypeBucket, PlannedObject, StateClosureOptions,
19    StateClosureTransferObjects, enumerate_state_closure, enumerate_state_closure_plan,
20    enumerate_state_closure_plan_with_options, enumerate_state_closure_transfer_from_boundaries,
21    enumerate_state_closure_transfer_with_options, enumerate_state_closure_with_options,
22    is_ancestor, is_ancestor_from_source, missing_blobs_in_tree,
23};
24pub use plan::{
25    GitLaneTransferIntent, RepositoryTransferPlan, TransferPartitions, TransferPlanStats,
26};
27
28#[cfg(test)]
29mod tests {
30    use super::graph::ObjectType;
31
32    /// The push/pull packability split routes `StateAttachment` off the push
33    /// pack (weft#549 forgery seal) while leaving pull carriage and every other
34    /// type untouched.
35    #[test]
36    fn packable_predicates_split_state_attachment_by_direction() {
37        // Sidecar records are never packable in either direction.
38        for sidecar in [
39            ObjectType::Redaction,
40            ObjectType::StateVisibility,
41            ObjectType::KeyBinding,
42        ] {
43            assert!(!sidecar.packable_for_push(), "{sidecar:?} push");
44            assert!(!sidecar.packable_for_pull(), "{sidecar:?} pull");
45        }
46        // Content-addressed objects ride the pack in both directions.
47        for packable in [
48            ObjectType::Blob,
49            ObjectType::Tree,
50            ObjectType::State,
51            ObjectType::Action,
52        ] {
53            assert!(packable.packable_for_push(), "{packable:?} push");
54            assert!(packable.packable_for_pull(), "{packable:?} pull");
55        }
56        // The attachment record: excluded from the push pack. The pull
57        // predicate stays true so planners still list it; weft delivers the
58        // record on Frame::StateAttachment, not in the native pack.
59        assert!(!ObjectType::StateAttachment.packable_for_push());
60        assert!(ObjectType::StateAttachment.packable_for_pull());
61    }
62}