@@ -7,7 +7,7 @@ use gix_object::{
77 bstr:: { BStr , BString } ,
88 FindExt ,
99} ;
10- use gix_traverse:: commit:: find;
10+ use gix_traverse:: commit:: find as find_commit ;
1111use smallvec:: SmallVec ;
1212use std:: num:: NonZeroU32 ;
1313use std:: ops:: Range ;
@@ -79,13 +79,7 @@ pub fn file(
7979 commit_id : suspect,
8080 } ) ?;
8181 let blamed_file_blob = odb. find_blob ( & blamed_file_entry_id, & mut buf) ?. data . to_vec ( ) ;
82- let num_lines_in_blamed = {
83- let mut interner = gix_diff:: blob:: intern:: Interner :: new ( blamed_file_blob. len ( ) / 100 ) ;
84- tokens_for_diffing ( & blamed_file_blob)
85- . tokenize ( )
86- . map ( |token| interner. intern ( token) )
87- . count ( )
88- } as u32 ;
82+ let num_lines_in_blamed = tokens_for_diffing ( & blamed_file_blob) . tokenize ( ) . count ( ) as u32 ;
8983
9084 // Binary or otherwise empty?
9185 if num_lines_in_blamed == 0 {
@@ -98,36 +92,29 @@ pub fn file(
9892 suspects: [ ( suspect, range_in_blamed_file) ] . into( ) ,
9993 } ] ;
10094
101- let mut buf = Vec :: new ( ) ;
102- let commit = find ( cache. as_ref ( ) , & odb, & suspect, & mut buf) ?;
103-
95+ let ( mut buf, mut buf2) = ( Vec :: new ( ) , Vec :: new ( ) ) ;
96+ let commit = find_commit ( cache. as_ref ( ) , & odb, & suspect, & mut buf) ?;
10497 let mut queue: gix_revwalk:: PriorityQueue < CommitTime , ObjectId > = gix_revwalk:: PriorityQueue :: new ( ) ;
105-
106- let commit_time = commit_time ( commit) ;
107- queue. insert ( commit_time, suspect) ;
98+ queue. insert ( commit_time ( commit) ?, suspect) ;
10899
109100 let mut out = Vec :: new ( ) ;
110101 let mut diff_state = gix_diff:: tree:: State :: default ( ) ;
111102 let mut previous_entry: Option < ( ObjectId , ObjectId ) > = None ;
112103 ' outer: while let Some ( suspect) = queue. pop_value ( ) {
104+ stats. commits_traversed += 1 ;
113105 if hunks_to_blame. is_empty ( ) {
114106 break ;
115107 }
116108
117109 let is_still_suspect = hunks_to_blame. iter ( ) . any ( |hunk| hunk. suspects . contains_key ( & suspect) ) ;
118-
119110 if !is_still_suspect {
120111 // There are no `UnblamedHunk`s associated with this `suspect`, so we can continue with
121112 // the next one.
122113 continue ' outer;
123114 }
124115
125- stats. commits_traversed += 1 ;
126-
127- let commit = find ( cache. as_ref ( ) , & odb, & suspect, & mut buf) ?;
128-
129- let parent_ids: ParentIds = collect_parents ( commit, & odb, cache. as_ref ( ) ) ;
130-
116+ let commit = find_commit ( cache. as_ref ( ) , & odb, & suspect, & mut buf) ?;
117+ let parent_ids: ParentIds = collect_parents ( commit, & odb, cache. as_ref ( ) , & mut buf2) ?;
131118 if parent_ids. is_empty ( ) {
132119 if queue. is_empty ( ) {
133120 // I’m not entirely sure if this is correct yet. `suspect`, at this point, is the
@@ -139,7 +126,6 @@ pub fn file(
139126 break ' outer;
140127 }
141128 }
142-
143129 // There is more, keep looking.
144130 continue ;
145131 }
@@ -639,27 +625,12 @@ fn find_path_entry_in_commit(
639625
640626type CommitTime = i64 ;
641627
642- fn commit_time ( commit : gix_traverse:: commit:: Either < ' _ , ' _ > ) -> CommitTime {
628+ fn commit_time ( commit : gix_traverse:: commit:: Either < ' _ , ' _ > ) -> Result < CommitTime , gix_object :: decode :: Error > {
643629 match commit {
644630 gix_traverse:: commit:: Either :: CommitRefIter ( commit_ref_iter) => {
645- let mut commit_time = 0 ;
646- for token in commit_ref_iter {
647- use gix_object:: commit:: ref_iter:: Token as T ;
648- match token {
649- Ok ( T :: Tree { .. } ) => continue ,
650- Ok ( T :: Parent { .. } ) => continue ,
651- Ok ( T :: Author { .. } ) => continue ,
652- Ok ( T :: Committer { signature } ) => {
653- commit_time = signature. time . seconds ;
654- break ;
655- }
656- Ok ( _unused_token) => break ,
657- Err ( _err) => todo ! ( ) ,
658- }
659- }
660- commit_time
631+ commit_ref_iter. committer ( ) . map ( |c| c. time . seconds )
661632 }
662- gix_traverse:: commit:: Either :: CachedCommit ( commit) => commit. committer_timestamp ( ) as i64 ,
633+ gix_traverse:: commit:: Either :: CachedCommit ( commit) => Ok ( commit. committer_timestamp ( ) as i64 ) ,
663634 }
664635}
665636
@@ -669,46 +640,30 @@ fn collect_parents(
669640 commit : gix_traverse:: commit:: Either < ' _ , ' _ > ,
670641 odb : & impl gix_object:: Find ,
671642 cache : Option < & gix_commitgraph:: Graph > ,
672- ) -> ParentIds {
643+ buf : & mut Vec < u8 > ,
644+ ) -> Result < ParentIds , Error > {
673645 let mut parent_ids: ParentIds = Default :: default ( ) ;
674-
675646 match commit {
676647 gix_traverse:: commit:: Either :: CachedCommit ( commit) => {
677648 let cache = cache
678649 . as_ref ( )
679650 . expect ( "find returned a cached commit, so we expect cache to be present" ) ;
680- for parent_id in commit. iter_parents ( ) {
681- match parent_id {
682- Ok ( pos) => {
683- let parent = cache. commit_at ( pos) ;
684-
685- parent_ids. push ( ( parent. id ( ) . to_owned ( ) , parent. committer_timestamp ( ) as i64 ) ) ;
686- }
687- Err ( _) => todo ! ( ) ,
688- }
651+ for parent_pos in commit. iter_parents ( ) {
652+ let parent = cache. commit_at ( parent_pos?) ;
653+ parent_ids. push ( ( parent. id ( ) . to_owned ( ) , parent. committer_timestamp ( ) as i64 ) ) ;
689654 }
690655 }
691656 gix_traverse:: commit:: Either :: CommitRefIter ( commit_ref_iter) => {
692- for token in commit_ref_iter {
693- match token {
694- Ok ( gix_object:: commit:: ref_iter:: Token :: Tree { .. } ) => continue ,
695- Ok ( gix_object:: commit:: ref_iter:: Token :: Parent { id } ) => {
696- let mut buf = Vec :: new ( ) ;
697- let parent = odb. find_commit_iter ( id. as_ref ( ) , & mut buf) . ok ( ) ;
698- let parent_commit_time = parent
699- . and_then ( |parent| parent. committer ( ) . ok ( ) . map ( |committer| committer. time . seconds ) )
700- . unwrap_or_default ( ) ;
701-
702- parent_ids. push ( ( id, parent_commit_time) ) ;
703- }
704- Ok ( _unused_token) => break ,
705- Err ( _err) => todo ! ( ) ,
706- }
657+ for id in commit_ref_iter. parent_ids ( ) {
658+ let parent = odb. find_commit_iter ( id. as_ref ( ) , buf) . ok ( ) ;
659+ let parent_commit_time = parent
660+ . and_then ( |parent| parent. committer ( ) . ok ( ) . map ( |committer| committer. time . seconds ) )
661+ . unwrap_or_default ( ) ;
662+ parent_ids. push ( ( id, parent_commit_time) ) ;
707663 }
708664 }
709665 } ;
710-
711- parent_ids
666+ Ok ( parent_ids)
712667}
713668
714669/// Return an iterator over tokens for use in diffing. These are usually lines, but it's important
0 commit comments