Parse a single git commit (called in parallel from rayon threads). This is a free function rather than a method because each rayon thread opens its own git repository instance (git2::Repository is not Sync).
(
git_repo: &GitRepository,
oid: Oid,
_index: usize,
oid_to_index: &std::collections::HashMap<Oid, usize>,
)
| 3592 | /// This is a free function rather than a method because each rayon thread |
| 3593 | /// opens its own git repository instance (git2::Repository is not Sync). |
| 3594 | fn parse_commit( |
| 3595 | git_repo: &GitRepository, |
| 3596 | oid: Oid, |
| 3597 | _index: usize, |
| 3598 | oid_to_index: &std::collections::HashMap<Oid, usize>, |
| 3599 | ) -> CliResult<ParsedCommit> { |
| 3600 | let parse_start = Instant::now(); |
| 3601 | let commit = git_repo.find_commit(oid).map_err(|e| CliError::GitError { |
| 3602 | message: format!("Failed to find commit {}: {}", oid, e), |
| 3603 | })?; |
| 3604 | |
| 3605 | let sha = oid.to_string(); |
| 3606 | let short_sha = sha[..8.min(sha.len())].to_string(); |
| 3607 | |
| 3608 | // Extract metadata |
| 3609 | let metadata = extract_commit_metadata(&commit)?; |
| 3610 | |
| 3611 | // Get parent index |
| 3612 | let parent_index = if commit.parent_count() > 0 { |
| 3613 | commit |
| 3614 | .parent_id(0) |
| 3615 | .ok() |
| 3616 | .and_then(|parent_oid| oid_to_index.get(&parent_oid).copied()) |
| 3617 | } else { |
| 3618 | None |
| 3619 | }; |
| 3620 | |
| 3621 | let is_merge = commit.parent_count() > 1; |
| 3622 | |
| 3623 | // Get trees for diff |
| 3624 | let tree = commit.tree().map_err(|e| CliError::GitError { |
| 3625 | message: format!("Failed to get tree: {}", e), |
| 3626 | })?; |
| 3627 | |
| 3628 | let parent_tree = if commit.parent_count() > 0 { |
| 3629 | Some( |
| 3630 | commit |
| 3631 | .parent(0) |
| 3632 | .map_err(|e| CliError::GitError { |
| 3633 | message: format!("Failed to get parent: {}", e), |
| 3634 | })? |
| 3635 | .tree() |
| 3636 | .map_err(|e| CliError::GitError { |
| 3637 | message: format!("Failed to get parent tree: {}", e), |
| 3638 | })?, |
| 3639 | ) |
| 3640 | } else { |
| 3641 | None |
| 3642 | }; |
| 3643 | |
| 3644 | // Use git's default diff algorithm here. Harness parity compares against |
| 3645 | // plain `git diff`, so the captured +/- lines need to reflect the same |
| 3646 | // default edit classification rather than `--patience`. |
| 3647 | let mut diff_opts = DiffOptions::new(); |
| 3648 | diff_opts.include_untracked(false); |
| 3649 | |
| 3650 | let diff_start = Instant::now(); |
| 3651 | let mut diff = git_repo |
no test coverage detected