Classify the commits an incremental import would bring in and print a per-shape recommendation (SPEC §4.4). Purely advisory — writes nothing.
(
&self,
git_repo: &GitRepository,
head_oid: git2::Oid,
imported_shas: &HashSet<String>,
known_states: &HashSet<atomic_core::types::Merkle>,
target_view
| 458 | /// Classify the commits an incremental import would bring in and print a |
| 459 | /// per-shape recommendation (SPEC §4.4). Purely advisory — writes nothing. |
| 460 | fn print_forecast_recommendations( |
| 461 | &self, |
| 462 | git_repo: &GitRepository, |
| 463 | head_oid: git2::Oid, |
| 464 | imported_shas: &HashSet<String>, |
| 465 | known_states: &HashSet<atomic_core::types::Merkle>, |
| 466 | target_view: &str, |
| 467 | repo: Option<&Repository>, |
| 468 | ) -> CliResult<()> { |
| 469 | use atomic_core::types::{Base32, Hash}; |
| 470 | |
| 471 | let mut revwalk = git_repo.revwalk().map_err(|e| CliError::GitError { |
| 472 | message: format!("Failed to create revwalk: {}", e), |
| 473 | })?; |
| 474 | revwalk.push(head_oid).map_err(|e| CliError::GitError { |
| 475 | message: format!("Failed to push HEAD to revwalk: {}", e), |
| 476 | })?; |
| 477 | if !self.all_branches { |
| 478 | revwalk |
| 479 | .simplify_first_parent() |
| 480 | .map_err(|e| CliError::GitError { |
| 481 | message: format!("Failed to simplify revwalk: {}", e), |
| 482 | })?; |
| 483 | } |
| 484 | revwalk |
| 485 | .set_sorting(Sort::TOPOLOGICAL | Sort::REVERSE) |
| 486 | .map_err(|e| CliError::GitError { |
| 487 | message: format!("Failed to set sorting: {}", e), |
| 488 | })?; |
| 489 | |
| 490 | let mut insertable = 0usize; |
| 491 | let mut missing = 0usize; |
| 492 | let mut merges = 0usize; |
| 493 | let mut normal = 0usize; |
| 494 | |
| 495 | for oid_result in revwalk { |
| 496 | let oid = oid_result.map_err(|e| CliError::GitError { |
| 497 | message: format!("Revwalk error: {}", e), |
| 498 | })?; |
| 499 | let sha = oid.to_string(); |
| 500 | let commit = git_repo.find_commit(oid).map_err(|e| CliError::GitError { |
| 501 | message: format!("Failed to load commit {}: {}", sha, e), |
| 502 | })?; |
| 503 | let message = commit.message().unwrap_or(""); |
| 504 | if incremental_import_skips(&sha, message, imported_shas, target_view, known_states) { |
| 505 | continue; |
| 506 | } |
| 507 | let is_merge = commit.parent_count() > 1; |
| 508 | let records_present = |h: &str| { |
| 509 | repo.map(|r| { |
| 510 | Hash::from_base32(h.as_bytes()) |
| 511 | .map(|hash| r.has_change(&hash)) |
| 512 | .unwrap_or(false) |
| 513 | }) |
| 514 | .unwrap_or(false) |
| 515 | }; |
| 516 | match forecast_commit_kind(message, is_merge, records_present) { |
| 517 | ForecastKind::SquashInsertable { count, pr } => { |
no test coverage detected