@@ -615,6 +615,50 @@ pub fn process_changes(
615615    new_hunks_to_blame
616616} 
617617
618+ fn  get_changes_for_file_path ( 
619+     odb :  impl  gix_object:: Find  + gix_object:: FindHeader , 
620+     file_path :  & BStr , 
621+     id :  ObjectId , 
622+     parent_id :  ObjectId , 
623+ )  -> Vec < gix_diff:: tree:: recorder:: Change >  { 
624+     let  mut  buffer = Vec :: new ( ) ; 
625+ 
626+     let  parent = odb. find_commit ( & parent_id,  & mut  buffer) . unwrap ( ) ; 
627+ 
628+     let  mut  buffer = Vec :: new ( ) ; 
629+     let  parent_tree_iter = odb
630+         . find ( & parent. tree ( ) ,  & mut  buffer) 
631+         . unwrap ( ) 
632+         . try_into_tree_iter ( ) 
633+         . unwrap ( ) ; 
634+ 
635+     let  mut  buffer = Vec :: new ( ) ; 
636+     let  commit = odb. find_commit ( & id,  & mut  buffer) . unwrap ( ) ; 
637+ 
638+     let  mut  buffer = Vec :: new ( ) ; 
639+     let  tree_iter = odb
640+         . find ( & commit. tree ( ) ,  & mut  buffer) 
641+         . unwrap ( ) 
642+         . try_into_tree_iter ( ) 
643+         . unwrap ( ) ; 
644+ 
645+     let  mut  recorder = gix_diff:: tree:: Recorder :: default ( ) ; 
646+     gix_diff:: tree:: Changes :: from ( parent_tree_iter) 
647+         . needed_to_obtain ( tree_iter,  gix_diff:: tree:: State :: default ( ) ,  & odb,  & mut  recorder) 
648+         . unwrap ( ) ; 
649+ 
650+     recorder
651+         . records 
652+         . iter ( ) 
653+         . filter ( |change| match  change { 
654+             gix_diff:: tree:: recorder:: Change :: Modification  {  path,  .. }  => path == file_path, 
655+             gix_diff:: tree:: recorder:: Change :: Addition  {  path,  .. }  => path == file_path, 
656+             gix_diff:: tree:: recorder:: Change :: Deletion  {  path,  .. }  => path == file_path, 
657+         } ) 
658+         . cloned ( ) 
659+         . collect ( ) 
660+ } 
661+ 
618662/// This function merges adjacent blame entries. It merges entries that are adjacent both in the 
619663/// blamed file and in the original file that introduced them. This follows `git`’s 
620664/// behaviour. `libgit2`, as of 2024-09-19, only checks whether two entries are adjacent in the 
@@ -731,43 +775,9 @@ pub fn blame_file<E>(
731775
732776        let  last_parent_id:  ObjectId  = * parent_ids. last ( ) . unwrap ( ) ; 
733777
734-         let  mut  buffer = Vec :: new ( ) ; 
735- 
736-         let  last_parent = odb. find_commit ( & last_parent_id,  & mut  buffer) . unwrap ( ) ; 
737- 
738-         let  mut  buffer = Vec :: new ( ) ; 
739-         let  last_parent_tree_iter = odb
740-             . find ( & last_parent. tree ( ) ,  & mut  buffer) 
741-             . unwrap ( ) 
742-             . try_into_tree_iter ( ) 
743-             . unwrap ( ) ; 
744- 
745-         let  mut  buffer = Vec :: new ( ) ; 
746-         let  commit = odb. find_commit ( & item. id ,  & mut  buffer) . unwrap ( ) ; 
747- 
748-         let  mut  buffer = Vec :: new ( ) ; 
749-         let  tree_iter = odb
750-             . find ( & commit. tree ( ) ,  & mut  buffer) 
751-             . unwrap ( ) 
752-             . try_into_tree_iter ( ) 
753-             . unwrap ( ) ; 
754- 
755-         let  mut  recorder = gix_diff:: tree:: Recorder :: default ( ) ; 
756-         gix_diff:: tree:: Changes :: from ( last_parent_tree_iter) 
757-             . needed_to_obtain ( tree_iter,  gix_diff:: tree:: State :: default ( ) ,  & odb,  & mut  recorder) 
758-             . unwrap ( ) ; 
778+         let  changes_for_file_path = get_changes_for_file_path ( & odb,  file_path,  item. id ,  last_parent_id) ; 
759779
760-         let  records_for_file_path:  Vec < & gix_diff:: tree:: recorder:: Change >  = recorder
761-             . records 
762-             . iter ( ) 
763-             . filter ( |change| match  change { 
764-                 gix_diff:: tree:: recorder:: Change :: Modification  {  path,  .. }  => path == file_path, 
765-                 gix_diff:: tree:: recorder:: Change :: Addition  {  path,  .. }  => path == file_path, 
766-                 gix_diff:: tree:: recorder:: Change :: Deletion  {  path,  .. }  => path == file_path, 
767-             } ) 
768-             . collect ( ) ; 
769- 
770-         let  [ modification] :  [ & gix_diff:: tree:: recorder:: Change ]  = records_for_file_path[ ..]  else  { 
780+         let  [ ref  modification] :  [ gix_diff:: tree:: recorder:: Change ]  = changes_for_file_path[ ..]  else  { 
771781            // None of the changes affected the file we’re currently blaming. 
772782            continue ; 
773783        } ; 
0 commit comments