@@ -7,7 +7,7 @@ use gix_object::{
7
7
bstr:: { BStr , BString } ,
8
8
FindExt ,
9
9
} ;
10
- use gix_traverse:: commit:: find;
10
+ use gix_traverse:: commit:: find as find_commit ;
11
11
use smallvec:: SmallVec ;
12
12
use std:: num:: NonZeroU32 ;
13
13
use std:: ops:: Range ;
@@ -79,13 +79,7 @@ pub fn file(
79
79
commit_id : suspect,
80
80
} ) ?;
81
81
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 ;
89
83
90
84
// Binary or otherwise empty?
91
85
if num_lines_in_blamed == 0 {
@@ -98,36 +92,29 @@ pub fn file(
98
92
suspects: [ ( suspect, range_in_blamed_file) ] . into( ) ,
99
93
} ] ;
100
94
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) ?;
104
97
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) ;
108
99
109
100
let mut out = Vec :: new ( ) ;
110
101
let mut diff_state = gix_diff:: tree:: State :: default ( ) ;
111
102
let mut previous_entry: Option < ( ObjectId , ObjectId ) > = None ;
112
103
' outer: while let Some ( suspect) = queue. pop_value ( ) {
104
+ stats. commits_traversed += 1 ;
113
105
if hunks_to_blame. is_empty ( ) {
114
106
break ;
115
107
}
116
108
117
109
let is_still_suspect = hunks_to_blame. iter ( ) . any ( |hunk| hunk. suspects . contains_key ( & suspect) ) ;
118
-
119
110
if !is_still_suspect {
120
111
// There are no `UnblamedHunk`s associated with this `suspect`, so we can continue with
121
112
// the next one.
122
113
continue ' outer;
123
114
}
124
115
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) ?;
131
118
if parent_ids. is_empty ( ) {
132
119
if queue. is_empty ( ) {
133
120
// I’m not entirely sure if this is correct yet. `suspect`, at this point, is the
@@ -139,7 +126,6 @@ pub fn file(
139
126
break ' outer;
140
127
}
141
128
}
142
-
143
129
// There is more, keep looking.
144
130
continue ;
145
131
}
@@ -639,27 +625,12 @@ fn find_path_entry_in_commit(
639
625
640
626
type CommitTime = i64 ;
641
627
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 > {
643
629
match commit {
644
630
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 )
661
632
}
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 ) ,
663
634
}
664
635
}
665
636
@@ -669,46 +640,30 @@ fn collect_parents(
669
640
commit : gix_traverse:: commit:: Either < ' _ , ' _ > ,
670
641
odb : & impl gix_object:: Find ,
671
642
cache : Option < & gix_commitgraph:: Graph > ,
672
- ) -> ParentIds {
643
+ buf : & mut Vec < u8 > ,
644
+ ) -> Result < ParentIds , Error > {
673
645
let mut parent_ids: ParentIds = Default :: default ( ) ;
674
-
675
646
match commit {
676
647
gix_traverse:: commit:: Either :: CachedCommit ( commit) => {
677
648
let cache = cache
678
649
. as_ref ( )
679
650
. 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 ) ) ;
689
654
}
690
655
}
691
656
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) ) ;
707
663
}
708
664
}
709
665
} ;
710
-
711
- parent_ids
666
+ Ok ( parent_ids)
712
667
}
713
668
714
669
/// Return an iterator over tokens for use in diffing. These are usually lines, but it's important
0 commit comments