@@ -7,6 +7,7 @@ use gix::bstr::{BString, Utf8Error};
7
7
use gix:: object:: tree:: diff:: change:: Event ;
8
8
use gix:: object:: tree:: diff:: { Action , Change } ;
9
9
use gix:: objs:: tree:: EntryMode ;
10
+ use gix:: prelude:: ObjectIdExt ;
10
11
use gix:: Commit ;
11
12
use regex:: Regex ;
12
13
use std:: collections:: HashMap ;
@@ -46,7 +47,7 @@ impl CommitMetrics {
46
47
let mailmap_config = repo. open_mailmap ( ) ;
47
48
let mut number_of_commits_by_signature: HashMap < Sig , usize > = HashMap :: new ( ) ;
48
49
let mut total_number_of_commits = 0 ;
49
- let mut number_of_commits_by_file_path: HashMap < String , usize > = HashMap :: new ( ) ;
50
+ let mut number_of_commits_by_file_path: HashMap < BString , usize > = HashMap :: new ( ) ;
50
51
51
52
// From newest to oldest
52
53
while let Some ( commit_id) = commit_iter_peekable. next ( ) {
@@ -113,20 +114,19 @@ impl CommitMetrics {
113
114
}
114
115
115
116
fn compute_file_churns (
116
- number_of_commits_by_file_path : HashMap < String , usize > ,
117
+ number_of_commits_by_file_path : HashMap < BString , usize > ,
117
118
number_of_file_churns_to_display : usize ,
118
119
number_separator : NumberSeparator ,
119
120
) -> Vec < FileChurn > {
120
- let mut number_of_commits_by_file_path_sorted: Vec < ( String , usize ) > =
121
- number_of_commits_by_file_path. into_iter ( ) . collect ( ) ;
121
+ let mut number_of_commits_by_file_path_sorted = Vec :: from_iter ( number_of_commits_by_file_path) ;
122
122
123
123
number_of_commits_by_file_path_sorted
124
124
. sort_by ( |( _, a_count) , ( _, b_count) | b_count. cmp ( a_count) ) ;
125
125
126
126
number_of_commits_by_file_path_sorted
127
127
. into_iter ( )
128
128
. map ( |( file_path, nbr_of_commits) | {
129
- FileChurn :: new ( file_path, nbr_of_commits, number_separator)
129
+ FileChurn :: new ( file_path. to_string ( ) , nbr_of_commits, number_separator)
130
130
} )
131
131
. take ( number_of_file_churns_to_display)
132
132
. collect ( )
@@ -168,40 +168,38 @@ fn compute_authors(
168
168
}
169
169
170
170
fn compute_diff (
171
- change_map : & mut HashMap < String , usize > ,
171
+ change_map : & mut HashMap < BString , usize > ,
172
172
commit : & Commit ,
173
173
repo : & gix:: Repository ,
174
174
) -> Result < ( ) > {
175
- // Handles the very first commit
176
- if commit. parent_ids ( ) . count ( ) == 0 {
177
- repo. empty_tree ( )
175
+ let mut parents = commit. parent_ids ( ) ;
176
+ let parents = (
177
+ parents
178
+ . next ( )
179
+ . map ( |parent_id| -> Result < _ > { Ok ( parent_id. object ( ) ?. into_commit ( ) . tree_id ( ) ?) } )
180
+ . unwrap_or_else ( || {
181
+ Ok ( gix:: hash:: ObjectId :: empty_tree ( repo. object_hash ( ) ) . attach ( repo) )
182
+ } ) ?,
183
+ parents. next ( ) ,
184
+ ) ;
185
+ // Ignore merge commits
186
+ if let ( tree_id, None ) = parents {
187
+ tree_id
188
+ . object ( ) ?
189
+ . into_tree ( )
178
190
. changes ( ) ?
179
191
. track_path ( )
180
192
. for_each_to_obtain_tree ( & commit. tree ( ) ?, |change| {
181
193
for_each_change ( change, change_map)
182
194
} ) ?;
183
195
}
184
- // Ignore merge commits
185
- else if commit. parent_ids ( ) . count ( ) == 1 {
186
- for parent_id in commit. parent_ids ( ) {
187
- parent_id
188
- . object ( ) ?
189
- . into_commit ( )
190
- . tree ( ) ?
191
- . changes ( ) ?
192
- . track_path ( )
193
- . for_each_to_obtain_tree ( & commit. tree ( ) ?, |change| {
194
- for_each_change ( change, change_map)
195
- } ) ?;
196
- }
197
- }
198
196
199
197
Ok ( ( ) )
200
198
}
201
199
202
200
fn for_each_change (
203
201
change : Change ,
204
- change_map : & mut HashMap < String , usize > ,
202
+ change_map : & mut HashMap < BString , usize > ,
205
203
) -> Result < Action , Utf8Error > {
206
204
let is_file_change = match change. event {
207
205
Event :: Addition { entry_mode, .. } | Event :: Modification { entry_mode, .. } => {
@@ -210,11 +208,11 @@ fn for_each_change(
210
208
Event :: Deletion { .. } | Event :: Rewrite { .. } => false ,
211
209
} ;
212
210
if is_file_change {
213
- let path = change. location . to_os_str ( ) ? . to_string_lossy ( ) ;
214
- * change_map. entry ( path. into_owned ( ) ) . or_insert ( 0 ) += 1 ;
211
+ let path = change. location ;
212
+ * change_map. entry ( path. to_owned ( ) ) . or_insert ( 0 ) += 1 ;
215
213
}
216
214
217
- Ok :: < Action , Utf8Error > ( Action :: Continue )
215
+ Ok ( Action :: Continue )
218
216
}
219
217
220
218
fn get_no_bots_regex ( no_bots : & Option < Option < MyRegex > > ) -> Result < Option < MyRegex > > {
@@ -304,10 +302,10 @@ mod tests {
304
302
#[ test]
305
303
fn test_compute_file_churns ( ) {
306
304
let mut number_of_commits_by_file_path = HashMap :: new ( ) ;
307
- number_of_commits_by_file_path. insert ( "path/to/file1.txt" . to_string ( ) , 2 ) ;
308
- number_of_commits_by_file_path. insert ( "path/to/file2.txt" . to_string ( ) , 5 ) ;
309
- number_of_commits_by_file_path. insert ( "path/to/file3.txt" . to_string ( ) , 3 ) ;
310
- number_of_commits_by_file_path. insert ( "path/to/file4.txt" . to_string ( ) , 7 ) ;
305
+ number_of_commits_by_file_path. insert ( "path/to/file1.txt" . into ( ) , 2 ) ;
306
+ number_of_commits_by_file_path. insert ( "path/to/file2.txt" . into ( ) , 5 ) ;
307
+ number_of_commits_by_file_path. insert ( "path/to/file3.txt" . into ( ) , 3 ) ;
308
+ number_of_commits_by_file_path. insert ( "path/to/file4.txt" . into ( ) , 7 ) ;
311
309
312
310
let number_of_file_churns_to_display = 3 ;
313
311
let number_separator = NumberSeparator :: Comma ;
0 commit comments