Clone every remote view not already applied by the primary chain. Each view arrives as a manifest and is applied with the same primitive as the primary view, so scope and parent are preserved. Manifests are ordered parents-before-children; changes are content-addressed and deduplicated against everything already downloaded. Returns the number of additional views cloned.
(
&self,
repo: &mut Repository,
pack: &SyncPack,
change_objects: &HashMap<String, Vec<u8>>,
stats: &mut CloneStats,
applied: &mut HashSet<String>,
)
| 701 | /// content-addressed and deduplicated against everything already |
| 702 | /// downloaded. Returns the number of additional views cloned. |
| 703 | fn clone_additional_views( |
| 704 | &self, |
| 705 | repo: &mut Repository, |
| 706 | pack: &SyncPack, |
| 707 | change_objects: &HashMap<String, Vec<u8>>, |
| 708 | stats: &mut CloneStats, |
| 709 | applied: &mut HashSet<String>, |
| 710 | ) -> CliResult<usize> { |
| 711 | // With `--all-views` the primary pull requested every view, so the pack |
| 712 | // already carries all view refs + snapshots. Derive the inventory from |
| 713 | // it — no separate `GET /refs/views` round-trip. |
| 714 | let names: Vec<String> = pack.refs.iter().map(|r| r.name.clone()).collect(); |
| 715 | let others = match classify_inventory(&names, applied) { |
| 716 | InventoryOutcome::Views(others) => others, |
| 717 | InventoryOutcome::NothingNew => return Ok(0), |
| 718 | InventoryOutcome::Unsupported => { |
| 719 | return Err(CliError::RemoteError { |
| 720 | message: "--all-views requires the view inventory (?views), but this \ |
| 721 | server does not support it (empty inventory). Upgrade the \ |
| 722 | server, or clone a single view without --all-views." |
| 723 | .to_string(), |
| 724 | url: Some(self.url.clone()), |
| 725 | }) |
| 726 | } |
| 727 | }; |
| 728 | |
| 729 | print_blank(); |
| 730 | println!( |
| 731 | "Cloning {} additional {}:", |
| 732 | others.len(), |
| 733 | if others.len() == 1 { "view" } else { "views" } |
| 734 | ); |
| 735 | |
| 736 | // Fetch manifests for every remaining view. |
| 737 | let mut manifests: Vec<ViewManifest> = Vec::with_capacity(others.len()); |
| 738 | for name in &others { |
| 739 | match self.view_manifest_from_pack(pack, name) { |
| 740 | Ok(Some(m)) => manifests.push(m), |
| 741 | Ok(None) => { |
| 742 | print_warning(&format!( |
| 743 | "View '{}' vanished from the remote — skipped", |
| 744 | name |
| 745 | )); |
| 746 | } |
| 747 | Err(e) => { |
| 748 | print_warning(&format!( |
| 749 | "Failed to fetch manifest for view '{}': {}", |
| 750 | name, e |
| 751 | )); |
| 752 | } |
| 753 | } |
| 754 | } |
| 755 | |
| 756 | // Parents must apply before children; anything unorderable (parent |
| 757 | // cycle or a parent that exists nowhere) is reported and skipped. |
| 758 | let (order, stuck) = manifest_apply_order(&manifests, applied); |
| 759 | for &i in &stuck { |
| 760 | print_warning(&format!( |
no test coverage detected