@@ -73,8 +73,10 @@ pub fn file(
7373
7474    let  mut  stats = Statistics :: default ( ) ; 
7575    let  ( mut  buf,  mut  buf2,  mut  buf3)  = ( Vec :: new ( ) ,  Vec :: new ( ) ,  Vec :: new ( ) ) ; 
76-     let  blamed_file_entry_id = find_path_entry_in_commit ( & odb,  & suspect,  file_path,  & mut  buf,  & mut  buf2,  & mut  stats) ?
77-         . ok_or_else ( || Error :: FileMissing  { 
76+     let  blamed_file_entry_id = find_path_entry_in_commit ( 
77+         & odb,  & suspect,  file_path,  & cache,  & mut  buf,  & mut  buf2,  & mut  stats, 
78+     ) ?
79+     . ok_or_else ( || Error :: FileMissing  { 
7880        file_path :  file_path. to_owned ( ) , 
7981        commit_id :  suspect, 
8082    } ) ?; 
@@ -135,7 +137,7 @@ pub fn file(
135137            . filter ( |( id,  _) | * id == suspect) 
136138            . map ( |( _,  entry) | entry) ; 
137139        if  entry. is_none ( )  { 
138-             entry = find_path_entry_in_commit ( & odb,  & suspect,  file_path,  & mut  buf,  & mut  buf2,  & mut  stats) ?; 
140+             entry = find_path_entry_in_commit ( & odb,  & suspect,  file_path,  & cache ,   & mut  buf,  & mut  buf2,  & mut  stats) ?; 
139141        } 
140142
141143        let  Some ( entry_id)  = entry else  { 
@@ -178,7 +180,7 @@ pub fn file(
178180
179181        for  ( pid,  ( parent_id,  parent_commit_time) )  in  parent_ids. iter ( ) . enumerate ( )  { 
180182            if  let  Some ( parent_entry_id)  =
181-                 find_path_entry_in_commit ( & odb,  parent_id,  file_path,  & mut  buf,  & mut  buf2,  & mut  stats) ?
183+                 find_path_entry_in_commit ( & odb,  parent_id,  file_path,  & cache ,   & mut  buf,  & mut  buf2,  & mut  stats) ?
182184            { 
183185                let  no_change_in_entry = entry_id == parent_entry_id; 
184186                if  pid == 0  { 
@@ -200,6 +202,7 @@ pub fn file(
200202                file_path, 
201203                suspect, 
202204                parent_id, 
205+                 & cache, 
203206                & mut  stats, 
204207                & mut  diff_state, 
205208                & mut  buf, 
@@ -401,20 +404,19 @@ fn tree_diff_at_file_path(
401404    file_path :  & BStr , 
402405    id :  ObjectId , 
403406    parent_id :  ObjectId , 
407+     cache :  & Option < gix_commitgraph:: Graph > , 
404408    stats :  & mut  Statistics , 
405409    state :  & mut  gix_diff:: tree:: State , 
406410    commit_buf :  & mut  Vec < u8 > , 
407411    lhs_tree_buf :  & mut  Vec < u8 > , 
408412    rhs_tree_buf :  & mut  Vec < u8 > , 
409413)  -> Result < Option < gix_diff:: tree:: recorder:: Change > ,  Error >  { 
410-     let  parent_tree = odb. find_commit ( & parent_id,  commit_buf) ?. tree ( ) ; 
411-     stats. commits_to_tree  += 1 ; 
414+     let  parent_tree_id = tree_id ( find_commit ( cache. as_ref ( ) ,  & odb,  & parent_id,  commit_buf) ?) ?; 
412415
413-     let  parent_tree_iter = odb. find_tree_iter ( & parent_tree ,  lhs_tree_buf) ?; 
416+     let  parent_tree_iter = odb. find_tree_iter ( & parent_tree_id ,  lhs_tree_buf) ?; 
414417    stats. trees_decoded  += 1 ; 
415418
416-     let  tree_id = odb. find_commit ( & id,  commit_buf) ?. tree ( ) ; 
417-     stats. commits_to_tree  += 1 ; 
419+     let  tree_id = tree_id ( find_commit ( cache. as_ref ( ) ,  & odb,  & id,  commit_buf) ?) ?; 
418420
419421    let  tree_iter = odb. find_tree_iter ( & tree_id,  rhs_tree_buf) ?; 
420422    stats. trees_decoded  += 1 ; 
@@ -605,13 +607,13 @@ fn find_path_entry_in_commit(
605607    odb :  & impl  gix_object:: Find , 
606608    commit :  & gix_hash:: oid , 
607609    file_path :  & BStr , 
610+     cache :  & Option < gix_commitgraph:: Graph > , 
608611    buf :  & mut  Vec < u8 > , 
609612    buf2 :  & mut  Vec < u8 > , 
610613    stats :  & mut  Statistics , 
611614)  -> Result < Option < ObjectId > ,  Error >  { 
612-     let  commit_id = odb. find_commit ( commit,  buf) ?. tree ( ) ; 
613-     stats. commits_to_tree  += 1 ; 
614-     let  tree_iter = odb. find_tree_iter ( & commit_id,  buf) ?; 
615+     let  tree_id = tree_id ( find_commit ( cache. as_ref ( ) ,  & odb,  & commit,  buf) ?) ?; 
616+     let  tree_iter = odb. find_tree_iter ( & tree_id,  buf) ?; 
615617    stats. trees_decoded  += 1 ; 
616618
617619    let  res = tree_iter. lookup_entry ( 
@@ -666,6 +668,13 @@ fn collect_parents(
666668    Ok ( parent_ids) 
667669} 
668670
671+ fn  tree_id ( commit :  gix_traverse:: commit:: Either < ' _ ,  ' _ > )  -> Result < ObjectId ,  Error >  { 
672+     match  commit { 
673+         gix_traverse:: commit:: Either :: CommitRefIter ( mut  commit_ref_iter)  => Ok ( commit_ref_iter. tree_id ( ) ?) , 
674+         gix_traverse:: commit:: Either :: CachedCommit ( commit)  => Ok ( commit. root_tree_id ( ) . into ( ) ) , 
675+     } 
676+ } 
677+ 
669678/// Return an iterator over tokens for use in diffing. These are usually lines, but it's important 
670679/// to unify them so the later access shows the right thing. 
671680pub ( crate )  fn  tokens_for_diffing ( data :  & [ u8 ] )  -> impl  TokenSource < Token  = & [ u8 ] >  { 
0 commit comments