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