Phase 1: Parse all commits in parallel using rayon.
(&self, commit_oids: &[Oid])
| 2575 | |
| 2576 | /// Phase 1: Parse all commits in parallel using rayon. |
| 2577 | fn phase1_parse(&self, commit_oids: &[Oid]) -> CliResult<Vec<ParsedCommit>> { |
| 2578 | // Build a map from OID to index for parent lookups |
| 2579 | let oid_to_index: std::collections::HashMap<Oid, usize> = commit_oids |
| 2580 | .iter() |
| 2581 | .enumerate() |
| 2582 | .map(|(i, oid)| (*oid, i)) |
| 2583 | .collect(); |
| 2584 | |
| 2585 | // Progress counter for large repos |
| 2586 | let progress = Arc::new(AtomicUsize::new(0)); |
| 2587 | let total = commit_oids.len(); |
| 2588 | |
| 2589 | // Share the repo path for thread-local repo opening |
| 2590 | let repo_path = self.git_repo_path.clone(); |
| 2591 | |
| 2592 | // Parse commits in parallel - each thread opens its own git repo |
| 2593 | let results: Vec<CliResult<ParsedCommit>> = commit_oids |
| 2594 | .par_iter() |
| 2595 | .enumerate() |
| 2596 | .map(|(idx, oid)| { |
| 2597 | // Progress reporting (every 100 commits) |
| 2598 | let count = progress.fetch_add(1, Ordering::Relaxed); |
| 2599 | if total > 100 && count.is_multiple_of(100) { |
| 2600 | print_info(&format!(" Parsed {}/{} commits...", count, total)); |
| 2601 | } |
| 2602 | |
| 2603 | // Open a thread-local git repo |
| 2604 | let git_repo = GitRepository::open(&repo_path).map_err(|e| CliError::GitError { |
| 2605 | message: format!("Failed to open git repository: {}", e), |
| 2606 | })?; |
| 2607 | |
| 2608 | let mut commit = parse_commit(&git_repo, *oid, idx, &oid_to_index)?; |
| 2609 | self.apply_import_ignores(&mut commit); |
| 2610 | Ok(commit) |
| 2611 | }) |
| 2612 | .collect(); |
| 2613 | |
| 2614 | // Collect results, filtering out errors (with warnings) |
| 2615 | let mut parsed = Vec::with_capacity(results.len()); |
| 2616 | for (idx, result) in results.into_iter().enumerate() { |
| 2617 | match result { |
| 2618 | Ok(commit) => parsed.push(commit), |
| 2619 | Err(e) => { |
| 2620 | print_warning(&format!("Skipping commit {}: {}", idx, e)); |
| 2621 | } |
| 2622 | } |
| 2623 | } |
| 2624 | |
| 2625 | // Sort by original index to restore topological order |
| 2626 | // (rayon may have processed them out of order) |
| 2627 | parsed.sort_by_key(|c| { |
| 2628 | commit_oids |
| 2629 | .iter() |
| 2630 | .position(|oid| oid.to_string() == c.git_sha) |
| 2631 | .unwrap_or(usize::MAX) |
| 2632 | }); |
| 2633 | |
| 2634 | Ok(parsed) |
no test coverage detected