Phase 1: Parse all commits in parallel using rayon.
(&self, commit_oids: &[Oid])
| 2504 | |
| 2505 | /// Phase 1: Parse all commits in parallel using rayon. |
| 2506 | fn phase1_parse(&self, commit_oids: &[Oid]) -> CliResult<Vec<ParsedCommit>> { |
| 2507 | // Build a map from OID to index for parent lookups |
| 2508 | let oid_to_index: std::collections::HashMap<Oid, usize> = commit_oids |
| 2509 | .iter() |
| 2510 | .enumerate() |
| 2511 | .map(|(i, oid)| (*oid, i)) |
| 2512 | .collect(); |
| 2513 | |
| 2514 | // Progress counter for large repos |
| 2515 | let progress = Arc::new(AtomicUsize::new(0)); |
| 2516 | let total = commit_oids.len(); |
| 2517 | |
| 2518 | // Share the repo path for thread-local repo opening |
| 2519 | let repo_path = self.git_repo_path.clone(); |
| 2520 | |
| 2521 | // Parse commits in parallel - each thread opens its own git repo |
| 2522 | let results: Vec<CliResult<ParsedCommit>> = commit_oids |
| 2523 | .par_iter() |
| 2524 | .enumerate() |
| 2525 | .map(|(idx, oid)| { |
| 2526 | // Progress reporting (every 100 commits) |
| 2527 | let count = progress.fetch_add(1, Ordering::Relaxed); |
| 2528 | if total > 100 && count.is_multiple_of(100) { |
| 2529 | print_info(&format!(" Parsed {}/{} commits...", count, total)); |
| 2530 | } |
| 2531 | |
| 2532 | // Open a thread-local git repo |
| 2533 | let git_repo = GitRepository::open(&repo_path).map_err(|e| CliError::GitError { |
| 2534 | message: format!("Failed to open git repository: {}", e), |
| 2535 | })?; |
| 2536 | |
| 2537 | let mut commit = parse_commit(&git_repo, *oid, idx, &oid_to_index)?; |
| 2538 | self.apply_import_ignores(&mut commit); |
| 2539 | Ok(commit) |
| 2540 | }) |
| 2541 | .collect(); |
| 2542 | |
| 2543 | // Collect results, filtering out errors (with warnings) |
| 2544 | let mut parsed = Vec::with_capacity(results.len()); |
| 2545 | for (idx, result) in results.into_iter().enumerate() { |
| 2546 | match result { |
| 2547 | Ok(commit) => parsed.push(commit), |
| 2548 | Err(e) => { |
| 2549 | print_warning(&format!("Skipping commit {}: {}", idx, e)); |
| 2550 | } |
| 2551 | } |
| 2552 | } |
| 2553 | |
| 2554 | // Sort by original index to restore topological order |
| 2555 | // (rayon may have processed them out of order) |
| 2556 | parsed.sort_by_key(|c| { |
| 2557 | commit_oids |
| 2558 | .iter() |
| 2559 | .position(|oid| oid.to_string() == c.git_sha) |
| 2560 | .unwrap_or(usize::MAX) |
| 2561 | }); |
| 2562 | |
| 2563 | Ok(parsed) |
no test coverage detected