Phase 1: Parse all commits in parallel using rayon.
(&self, commit_oids: &[Oid])
| 2430 | |
| 2431 | /// Phase 1: Parse all commits in parallel using rayon. |
| 2432 | fn phase1_parse(&self, commit_oids: &[Oid]) -> CliResult<Vec<ParsedCommit>> { |
| 2433 | // Build a map from OID to index for parent lookups |
| 2434 | let oid_to_index: std::collections::HashMap<Oid, usize> = commit_oids |
| 2435 | .iter() |
| 2436 | .enumerate() |
| 2437 | .map(|(i, oid)| (*oid, i)) |
| 2438 | .collect(); |
| 2439 | |
| 2440 | // Progress counter for large repos |
| 2441 | let progress = Arc::new(AtomicUsize::new(0)); |
| 2442 | let total = commit_oids.len(); |
| 2443 | |
| 2444 | // Share the repo path for thread-local repo opening |
| 2445 | let repo_path = self.git_repo_path.clone(); |
| 2446 | |
| 2447 | // Parse commits in parallel - each thread opens its own git repo |
| 2448 | let results: Vec<CliResult<ParsedCommit>> = commit_oids |
| 2449 | .par_iter() |
| 2450 | .enumerate() |
| 2451 | .map(|(idx, oid)| { |
| 2452 | // Progress reporting (every 100 commits) |
| 2453 | let count = progress.fetch_add(1, Ordering::Relaxed); |
| 2454 | if total > 100 && count.is_multiple_of(100) { |
| 2455 | print_info(&format!(" Parsed {}/{} commits...", count, total)); |
| 2456 | } |
| 2457 | |
| 2458 | // Open a thread-local git repo |
| 2459 | let git_repo = GitRepository::open(&repo_path).map_err(|e| CliError::GitError { |
| 2460 | message: format!("Failed to open git repository: {}", e), |
| 2461 | })?; |
| 2462 | |
| 2463 | let mut commit = parse_commit(&git_repo, *oid, idx, &oid_to_index)?; |
| 2464 | self.apply_import_ignores(&mut commit); |
| 2465 | Ok(commit) |
| 2466 | }) |
| 2467 | .collect(); |
| 2468 | |
| 2469 | // Collect results, filtering out errors (with warnings) |
| 2470 | let mut parsed = Vec::with_capacity(results.len()); |
| 2471 | for (idx, result) in results.into_iter().enumerate() { |
| 2472 | match result { |
| 2473 | Ok(commit) => parsed.push(commit), |
| 2474 | Err(e) => { |
| 2475 | print_warning(&format!("Skipping commit {}: {}", idx, e)); |
| 2476 | } |
| 2477 | } |
| 2478 | } |
| 2479 | |
| 2480 | // Sort by original index to restore topological order |
| 2481 | // (rayon may have processed them out of order) |
| 2482 | parsed.sort_by_key(|c| { |
| 2483 | commit_oids |
| 2484 | .iter() |
| 2485 | .position(|oid| oid.to_string() == c.git_sha) |
| 2486 | .unwrap_or(usize::MAX) |
| 2487 | }); |
| 2488 | |
| 2489 | Ok(parsed) |
no test coverage detected