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>,
)
| 4073 | /// This is a free function rather than a method because each rayon thread |
| 4074 | /// opens its own git repository instance (git2::Repository is not Sync). |
| 4075 | fn parse_commit( |
| 4076 | git_repo: &GitRepository, |
| 4077 | oid: Oid, |
| 4078 | _index: usize, |
| 4079 | oid_to_index: &std::collections::HashMap<Oid, usize>, |
| 4080 | ) -> CliResult<ParsedCommit> { |
| 4081 | let parse_start = Instant::now(); |
| 4082 | let commit = git_repo.find_commit(oid).map_err(|e| CliError::GitError { |
| 4083 | message: format!("Failed to find commit {}: {}", oid, e), |
| 4084 | })?; |
| 4085 | |
| 4086 | let sha = oid.to_string(); |
| 4087 | let short_sha = sha[..8.min(sha.len())].to_string(); |
| 4088 | |
| 4089 | // Extract metadata |
| 4090 | let metadata = extract_commit_metadata(&commit)?; |
| 4091 | |
| 4092 | // Get parent index |
| 4093 | let parent_index = if commit.parent_count() > 0 { |
| 4094 | commit |
| 4095 | .parent_id(0) |
| 4096 | .ok() |
| 4097 | .and_then(|parent_oid| oid_to_index.get(&parent_oid).copied()) |
| 4098 | } else { |
| 4099 | None |
| 4100 | }; |
| 4101 | |
| 4102 | let is_merge = commit.parent_count() > 1; |
| 4103 | |
| 4104 | // Get trees for diff |
| 4105 | let tree = commit.tree().map_err(|e| CliError::GitError { |
| 4106 | message: format!("Failed to get tree: {}", e), |
| 4107 | })?; |
| 4108 | |
| 4109 | let parent_tree = if commit.parent_count() > 0 { |
| 4110 | Some( |
| 4111 | commit |
| 4112 | .parent(0) |
| 4113 | .map_err(|e| CliError::GitError { |
| 4114 | message: format!("Failed to get parent: {}", e), |
| 4115 | })? |
| 4116 | .tree() |
| 4117 | .map_err(|e| CliError::GitError { |
| 4118 | message: format!("Failed to get parent tree: {}", e), |
| 4119 | })?, |
| 4120 | ) |
| 4121 | } else { |
| 4122 | None |
| 4123 | }; |
| 4124 | |
| 4125 | // Use git's default diff algorithm here. Harness parity compares against |
| 4126 | // plain `git diff`, so the captured +/- lines need to reflect the same |
| 4127 | // default edit classification rather than `--patience`. |
| 4128 | let mut diff_opts = DiffOptions::new(); |
| 4129 | diff_opts.include_untracked(false); |
| 4130 | |
| 4131 | let diff_start = Instant::now(); |
| 4132 | let mut diff = git_repo |
no test coverage detected