(&self)
| 86 | |
| 87 | impl Command for Split { |
| 88 | fn run(&self) -> CliResult<()> { |
| 89 | let repo_root = find_repository_root()?; |
| 90 | let mut repo = Repository::open(&repo_root).map_err(|e| match e { |
| 91 | atomic_repository::RepositoryError::NotFound { path } => CliError::RepositoryNotFound { |
| 92 | searched_path: path.into(), |
| 93 | }, |
| 94 | other => CliError::Repository(other), |
| 95 | })?; |
| 96 | |
| 97 | let from_view = self |
| 98 | .from |
| 99 | .clone() |
| 100 | .unwrap_or_else(|| repo.current_view().to_string()); |
| 101 | |
| 102 | // Resolve which changes to split: either an explicit list or --last N. |
| 103 | let change_hashes = self.resolve_changes(&repo, &from_view)?; |
| 104 | |
| 105 | let options = SplitOptions { |
| 106 | target_view: self.name.clone(), |
| 107 | from_view: Some(from_view.clone()), |
| 108 | changes: change_hashes, |
| 109 | cascade: self.cascade, |
| 110 | dry_run: self.dry_run, |
| 111 | // When switching, the draft is materialized by the switch below, so |
| 112 | // there's no need to reconcile the source we're leaving. Otherwise, |
| 113 | // refresh the source's working copy in place. |
| 114 | materialize: !self.switch, |
| 115 | }; |
| 116 | |
| 117 | let outcome = repo.split_view(options).map_err(CliError::Repository)?; |
| 118 | |
| 119 | // ── Dry run: report the analysis. ── |
| 120 | if outcome.was_dry_run { |
| 121 | print_info(&format!( |
| 122 | "Dry run: splitting {} change(s) out of {}", |
| 123 | outcome.requested.len(), |
| 124 | style_view(&outcome.from_view), |
| 125 | )); |
| 126 | for c in &outcome.requested { |
| 127 | println!(" requested {}", style_hash(c.hash.to_base32())); |
| 128 | } |
| 129 | if outcome.blocked { |
| 130 | print_warning(&format!( |
| 131 | "Blocked: {} change(s) remaining in '{}' depend on the split-out set:", |
| 132 | outcome.dependents.len(), |
| 133 | outcome.from_view, |
| 134 | )); |
| 135 | for c in &outcome.dependents { |
| 136 | println!(" dependent {}", style_hash(c.hash.to_base32())); |
| 137 | } |
| 138 | print_hint("Re-run with --cascade to move the dependents too."); |
| 139 | } else { |
| 140 | if !outcome.dependents.is_empty() { |
| 141 | print_info(&format!( |
| 142 | "{} dependent change(s) would be moved along (--cascade):", |
| 143 | outcome.dependents.len(), |
| 144 | )); |
| 145 | for c in &outcome.dependents { |
nothing calls this directly
no test coverage detected