diff --git a/gix-blame/src/file/function.rs b/gix-blame/src/file/function.rs index f6368dde18f..621da6f0d0f 100644 --- a/gix-blame/src/file/function.rs +++ b/gix-blame/src/file/function.rs @@ -73,8 +73,16 @@ pub fn file( let mut stats = Statistics::default(); let (mut buf, mut buf2, mut buf3) = (Vec::new(), Vec::new(), Vec::new()); - let blamed_file_entry_id = find_path_entry_in_commit(&odb, &suspect, file_path, &mut buf, &mut buf2, &mut stats)? - .ok_or_else(|| Error::FileMissing { + let blamed_file_entry_id = find_path_entry_in_commit( + &odb, + &suspect, + file_path, + cache.as_ref(), + &mut buf, + &mut buf2, + &mut stats, + )? + .ok_or_else(|| Error::FileMissing { file_path: file_path.to_owned(), commit_id: suspect, })?; @@ -135,7 +143,15 @@ pub fn file( .filter(|(id, _)| *id == suspect) .map(|(_, entry)| entry); if entry.is_none() { - entry = find_path_entry_in_commit(&odb, &suspect, file_path, &mut buf, &mut buf2, &mut stats)?; + entry = find_path_entry_in_commit( + &odb, + &suspect, + file_path, + cache.as_ref(), + &mut buf, + &mut buf2, + &mut stats, + )?; } let Some(entry_id) = entry else { @@ -177,9 +193,15 @@ pub fn file( } for (pid, (parent_id, parent_commit_time)) in parent_ids.iter().enumerate() { - if let Some(parent_entry_id) = - find_path_entry_in_commit(&odb, parent_id, file_path, &mut buf, &mut buf2, &mut stats)? - { + if let Some(parent_entry_id) = find_path_entry_in_commit( + &odb, + parent_id, + file_path, + cache.as_ref(), + &mut buf, + &mut buf2, + &mut stats, + )? { let no_change_in_entry = entry_id == parent_entry_id; if pid == 0 { previous_entry = Some((*parent_id, parent_entry_id)); @@ -200,6 +222,7 @@ pub fn file( file_path, suspect, parent_id, + cache.as_ref(), &mut stats, &mut diff_state, &mut buf, @@ -401,20 +424,19 @@ fn tree_diff_at_file_path( file_path: &BStr, id: ObjectId, parent_id: ObjectId, + cache: Option<&gix_commitgraph::Graph>, stats: &mut Statistics, state: &mut gix_diff::tree::State, commit_buf: &mut Vec, lhs_tree_buf: &mut Vec, rhs_tree_buf: &mut Vec, ) -> Result, Error> { - let parent_tree = odb.find_commit(&parent_id, commit_buf)?.tree(); - stats.commits_to_tree += 1; + let parent_tree_id = tree_id(find_commit(cache, &odb, &parent_id, commit_buf)?)?; - let parent_tree_iter = odb.find_tree_iter(&parent_tree, lhs_tree_buf)?; + let parent_tree_iter = odb.find_tree_iter(&parent_tree_id, lhs_tree_buf)?; stats.trees_decoded += 1; - let tree_id = odb.find_commit(&id, commit_buf)?.tree(); - stats.commits_to_tree += 1; + let tree_id = tree_id(find_commit(cache, &odb, &id, commit_buf)?)?; let tree_iter = odb.find_tree_iter(&tree_id, rhs_tree_buf)?; stats.trees_decoded += 1; @@ -605,13 +627,13 @@ fn find_path_entry_in_commit( odb: &impl gix_object::Find, commit: &gix_hash::oid, file_path: &BStr, + cache: Option<&gix_commitgraph::Graph>, buf: &mut Vec, buf2: &mut Vec, stats: &mut Statistics, ) -> Result, Error> { - let commit_id = odb.find_commit(commit, buf)?.tree(); - stats.commits_to_tree += 1; - let tree_iter = odb.find_tree_iter(&commit_id, buf)?; + let tree_id = tree_id(find_commit(cache, odb, commit, buf)?)?; + let tree_iter = odb.find_tree_iter(&tree_id, buf)?; stats.trees_decoded += 1; let res = tree_iter.lookup_entry( @@ -666,6 +688,13 @@ fn collect_parents( Ok(parent_ids) } +fn tree_id(commit: gix_traverse::commit::Either<'_, '_>) -> Result { + match commit { + gix_traverse::commit::Either::CommitRefIter(mut commit_ref_iter) => Ok(commit_ref_iter.tree_id()?), + gix_traverse::commit::Either::CachedCommit(commit) => Ok(commit.root_tree_id().into()), + } +} + /// Return an iterator over tokens for use in diffing. These are usually lines, but it's important /// to unify them so the later access shows the right thing. pub(crate) fn tokens_for_diffing(data: &[u8]) -> impl TokenSource { diff --git a/gix-blame/src/types.rs b/gix-blame/src/types.rs index 462c812034d..f539b11ed87 100644 --- a/gix-blame/src/types.rs +++ b/gix-blame/src/types.rs @@ -24,8 +24,6 @@ pub struct Outcome { pub struct Statistics { /// The amount of commits it traversed until the blame was complete. pub commits_traversed: usize, - /// The amount of commits whose trees were extracted. - pub commits_to_tree: usize, /// The amount of trees that were decoded to find the entry of the file to blame. pub trees_decoded: usize, /// The amount of tree-diffs to see if the filepath was added, deleted or modified. These diffs