@@ -18,6 +18,8 @@ pub struct Context<W> {
1818 pub ignore_bots : bool ,
1919 /// Show personally identifiable information before the summary. Includes names and email addresses.
2020 pub show_pii : bool ,
21+ /// Collect additional information like tree changes and changed lines.
22+ pub stats : bool ,
2123 /// Omit unifying identities by name and email which can lead to the same author appear multiple times
2224 /// due to using different names or email addresses.
2325 pub omit_unify_identities : bool ,
@@ -38,6 +40,7 @@ pub fn estimate<W, P>(
3840 Context {
3941 show_pii,
4042 ignore_bots,
43+ stats : _,
4144 omit_unify_identities,
4245 mut out,
4346 } : Context < W > ,
@@ -52,80 +55,77 @@ where
5255
5356 let ( all_commits, is_shallow) = {
5457 let mut progress = progress. add_child ( "Traverse commit graph" ) ;
55- let string_heap = & mut string_heap;
56- std:: thread:: scope (
57- move |scope| -> anyhow:: Result < ( Vec < actor:: SignatureRef < ' static > > , bool ) > {
58- let start = Instant :: now ( ) ;
59- progress. init ( None , progress:: count ( "commits" ) ) ;
60- let ( tx, rx) = std:: sync:: mpsc:: channel :: < Vec < u8 > > ( ) ;
61- let mailmap = repo. open_mailmap ( ) ;
58+ std:: thread:: scope ( |scope| -> anyhow:: Result < ( Vec < actor:: SignatureRef < ' static > > , bool ) > {
59+ let start = Instant :: now ( ) ;
60+ progress. init ( None , progress:: count ( "commits" ) ) ;
61+ let ( tx, rx) = std:: sync:: mpsc:: channel :: < Vec < u8 > > ( ) ;
62+ let mailmap = repo. open_mailmap ( ) ;
6263
63- let handle = scope. spawn ( move || -> anyhow:: Result < Vec < actor:: SignatureRef < ' static > > > {
64- let mut out = Vec :: new ( ) ;
65- for commit_data in rx {
66- if let Some ( author) = objs:: CommitRefIter :: from_bytes ( & commit_data)
67- . author ( )
68- . map ( |author| mailmap. resolve_cow ( author. trim ( ) ) )
69- . ok ( )
70- {
71- let mut string_ref = |s : & [ u8 ] | -> & ' static BStr {
72- match string_heap. get ( s) {
73- Some ( n) => n. as_bstr ( ) ,
74- None => {
75- let sv: Vec < u8 > = s. to_owned ( ) . into ( ) ;
76- string_heap. insert ( Box :: leak ( sv. into_boxed_slice ( ) ) ) ;
77- ( * string_heap. get ( s) . expect ( "present" ) ) . as_ref ( )
78- }
64+ let handle = scope. spawn ( move || -> anyhow:: Result < Vec < actor:: SignatureRef < ' static > > > {
65+ let mut out = Vec :: new ( ) ;
66+ for commit_data in rx {
67+ if let Some ( author) = objs:: CommitRefIter :: from_bytes ( & commit_data)
68+ . author ( )
69+ . map ( |author| mailmap. resolve_cow ( author. trim ( ) ) )
70+ . ok ( )
71+ {
72+ let mut string_ref = |s : & [ u8 ] | -> & ' static BStr {
73+ match string_heap. get ( s) {
74+ Some ( n) => n. as_bstr ( ) ,
75+ None => {
76+ let sv: Vec < u8 > = s. to_owned ( ) . into ( ) ;
77+ string_heap. insert ( Box :: leak ( sv. into_boxed_slice ( ) ) ) ;
78+ ( * string_heap. get ( s) . expect ( "present" ) ) . as_ref ( )
7979 }
80- } ;
81- let name = string_ref ( author. name . as_ref ( ) ) ;
82- let email = string_ref ( & author. email . as_ref ( ) ) ;
80+ }
81+ } ;
82+ let name = string_ref ( author. name . as_ref ( ) ) ;
83+ let email = string_ref ( & author. email . as_ref ( ) ) ;
8384
84- out. push ( actor:: SignatureRef {
85- name,
86- email,
87- time : author. time ,
88- } ) ;
89- }
85+ out. push ( actor:: SignatureRef {
86+ name,
87+ email,
88+ time : author. time ,
89+ } ) ;
9090 }
91- out. shrink_to_fit ( ) ;
92- out. sort_by ( |a, b| {
93- a. email . cmp ( & b. email ) . then (
94- a. time
95- . seconds_since_unix_epoch
96- . cmp ( & b. time . seconds_since_unix_epoch )
97- . reverse ( ) ,
98- )
99- } ) ;
100- Ok ( out)
91+ }
92+ out. shrink_to_fit ( ) ;
93+ out. sort_by ( |a, b| {
94+ a. email . cmp ( & b. email ) . then (
95+ a. time
96+ . seconds_since_unix_epoch
97+ . cmp ( & b. time . seconds_since_unix_epoch )
98+ . reverse ( ) ,
99+ )
101100 } ) ;
101+ Ok ( out)
102+ } ) ;
102103
103- let commit_iter = interrupt:: Iter :: new (
104- commit_id. ancestors ( |oid, buf| {
105- progress. inc ( ) ;
106- repo. objects . find ( oid, buf) . map ( |o| {
107- tx. send ( o. data . to_owned ( ) ) . ok ( ) ;
108- objs:: CommitRefIter :: from_bytes ( o. data )
109- } )
110- } ) ,
111- || anyhow ! ( "Cancelled by user" ) ,
112- ) ;
113- let mut is_shallow = false ;
114- for c in commit_iter {
115- match c? {
116- Ok ( c) => c,
117- Err ( git:: traverse:: commit:: ancestors:: Error :: FindExisting { .. } ) => {
118- is_shallow = true ;
119- break ;
120- }
121- Err ( err) => return Err ( err. into ( ) ) ,
122- } ;
123- }
124- drop ( tx) ;
125- progress. show_throughput ( start) ;
126- Ok ( ( handle. join ( ) . expect ( "no panic" ) ?, is_shallow) )
127- } ,
128- ) ?
104+ let commit_iter = interrupt:: Iter :: new (
105+ commit_id. ancestors ( |oid, buf| {
106+ progress. inc ( ) ;
107+ repo. objects . find ( oid, buf) . map ( |o| {
108+ tx. send ( o. data . to_owned ( ) ) . ok ( ) ;
109+ objs:: CommitRefIter :: from_bytes ( o. data )
110+ } )
111+ } ) ,
112+ || anyhow ! ( "Cancelled by user" ) ,
113+ ) ;
114+ let mut is_shallow = false ;
115+ for c in commit_iter {
116+ match c? {
117+ Ok ( c) => c,
118+ Err ( git:: traverse:: commit:: ancestors:: Error :: FindExisting { .. } ) => {
119+ is_shallow = true ;
120+ break ;
121+ }
122+ Err ( err) => return Err ( err. into ( ) ) ,
123+ } ;
124+ }
125+ drop ( tx) ;
126+ progress. show_throughput ( start) ;
127+ Ok ( ( handle. join ( ) . expect ( "no panic" ) ?, is_shallow) )
128+ } ) ?
129129 } ;
130130
131131 if all_commits. is_empty ( ) {
0 commit comments