@@ -51,7 +51,7 @@ Diff Commands:
5151
5252 m : toggle ignoring metadata
5353 d : toggle show only different entries
54- s : compute information for (sub-)dirs
54+ s : compute information for (sub-)dirs and show totals
5555 I : show information about snapshots
5656
5757General Commands:
@@ -233,48 +233,61 @@ impl<'a, P: ProgressBars, S: IndexedFull> Diff<'a, P, S> {
233233 !self . ignore_identical || !self . node_changed ( node) . is_identical ( )
234234 }
235235
236- fn ls_row ( & self , node : & DiffNode , stat : & mut DiffStatistics ) -> Vec < Text < ' static > > {
236+ #[ allow( clippy:: type_complexity) ]
237+ fn sizes (
238+ & self ,
239+ node : & DiffNode ,
240+ ) -> (
241+ Option < u64 > ,
242+ Option < u64 > ,
243+ Option < u64 > ,
244+ Option < u64 > ,
245+ Option < u64 > ,
246+ ) {
237247 let node_info = |node : & Node | {
238- let size = node. subtree . map_or ( node. meta . size , |id| {
248+ node. subtree . map_or ( node. meta . size , |id| {
239249 self . summary_map
240250 . get ( & id)
241251 . map_or ( node. meta . size , |summary| summary. summary . size )
242- } ) ;
243- (
244- bytes_size_to_string ( size) ,
245- node. meta . mtime . map_or_else (
246- || "?" . to_string ( ) ,
247- |t| format ! ( "{}" , t. format( "%Y-%m-%d %H:%M:%S" ) ) ,
248- ) ,
249- )
252+ } )
250253 } ;
251254
252255 let ( left, right) = node. 0 . as_ref ( ) . left_and_right ( ) ;
253256 let left_blobs = left. map ( |node| BlobInfoRef :: from_node_or_map ( node, & self . summary_map ) ) ;
254257 let right_blobs = right. map ( |node| BlobInfoRef :: from_node_or_map ( node, & self . summary_map ) ) ;
255- let left_only = BlobInfoRef :: text_diff ( & left_blobs , & right_blobs , self . repo ) ;
256- let right_only = BlobInfoRef :: text_diff ( & right_blobs , & left_blobs , self . repo ) ;
258+ let ( left_only , right_only , both ) =
259+ BlobInfoRef :: size_diff ( & left_blobs , & right_blobs , self . repo ) . unwrap_or_default ( ) ;
257260
261+ let left_size = left. map ( node_info) ;
262+ let right_size = right. map ( node_info) ;
263+
264+ ( left_size, left_only, right_size, right_only, both)
265+ }
266+
267+ fn ls_row ( & self , node : & DiffNode , stat : & mut DiffStatistics ) -> Vec < Text < ' static > > {
268+ let node_mtime = |node : & Node | {
269+ node. meta . mtime . map_or_else (
270+ || "?" . to_string ( ) ,
271+ |t| format ! ( "{}" , t. format( "%Y-%m-%d %H:%M:%S" ) ) ,
272+ )
273+ } ;
274+
275+ let ( left_size, left_only, right_size, right_only, _) = self . sizes ( node) ;
258276 let changed = self . node_changed ( node) ;
259277 stat. apply ( changed) ;
260278 let name = node. name ( ) ;
261279 let name = format ! ( "{changed} {}" , name. to_string_lossy( ) ) ;
262- let ( left_size, left_mtime) = match & node. 0 {
263- EitherOrBoth :: Left ( node) | EitherOrBoth :: Both ( node, _) => node_info ( node) ,
264- _ => ( String :: new ( ) , String :: new ( ) ) ,
265- } ;
266- let ( right_size, right_mtime) = match & node. 0 {
267- EitherOrBoth :: Right ( node) | EitherOrBoth :: Both ( _, node) => node_info ( node) ,
268- _ => ( String :: new ( ) , String :: new ( ) ) ,
269- } ;
280+ let ( left, right) = node. 0 . as_ref ( ) . left_and_right ( ) ;
281+ let left_mtime = left. map_or_else ( String :: new, node_mtime) ;
282+ let right_mtime = right. map_or_else ( String :: new, node_mtime) ;
270283 [
271284 name,
272285 left_mtime,
273- left_size,
274- left_only,
286+ left_size. map_or_else ( String :: new , bytes_size_to_string ) ,
287+ left_only. map_or_else ( String :: new , bytes_size_to_string ) ,
275288 right_mtime,
276- right_size,
277- right_only,
289+ right_size. map_or_else ( String :: new , bytes_size_to_string ) ,
290+ right_only. map_or_else ( String :: new , bytes_size_to_string ) ,
278291 ]
279292 . into_iter ( )
280293 . map ( Text :: from)
@@ -381,7 +394,7 @@ impl<'a, P: ProgressBars, S: IndexedFull> Diff<'a, P, S> {
381394 Ok ( ( ) )
382395 }
383396
384- pub fn compute_summary ( & mut self ) -> Result < ( ) > {
397+ pub fn compute_summary ( & mut self ) -> Result < PopUpTable > {
385398 let pb = self . repo . progress_bars ( ) ;
386399 let p = pb. progress_counter ( "computing (sub)-dir information" ) ;
387400
@@ -399,7 +412,58 @@ impl<'a, P: ProgressBars, S: IndexedFull> Diff<'a, P, S> {
399412
400413 p. finish ( ) ;
401414 self . update_table ( ) ;
402- Ok ( ( ) )
415+
416+ // Compute total sizes diff
417+ let ( left_size, left_only, right_size, right_only, both) = self . sizes ( & self . node ) ;
418+ let left_repo_size = if let ( Some ( only) , Some ( both) ) = ( left_only, both) {
419+ Some ( only + both)
420+ } else {
421+ None
422+ } ;
423+ let right_repo_size = if let ( Some ( only) , Some ( both) ) = ( right_only, both) {
424+ Some ( only + both)
425+ } else {
426+ None
427+ } ;
428+ let mut rows = Vec :: new ( ) ;
429+ let title_left = if self . node . 0 . has_left ( ) {
430+ format ! ( "{}:{}" , self . snapshot_left. id, self . path_left. display( ) )
431+ } else {
432+ format ! ( "({})" , self . snapshot_left. id)
433+ } ;
434+ let title_right = if self . node . 0 . has_right ( ) {
435+ format ! ( "{}:{}" , self . snapshot_right. id, self . path_right. display( ) )
436+ } else {
437+ format ! ( "({})" , self . snapshot_right. id)
438+ } ;
439+ rows. push ( vec ! [
440+ Text :: from( "" ) ,
441+ Text :: from( title_right) ,
442+ Text :: from( title_left) ,
443+ ] ) ;
444+ rows. push ( vec ! [
445+ Text :: from( "total Size" ) ,
446+ Text :: from( left_size. map_or_else( String :: new, bytes_size_to_string) ) ,
447+ Text :: from( right_size. map_or_else( String :: new, bytes_size_to_string) ) ,
448+ ] ) ;
449+ rows. push ( vec ! [
450+ Text :: from( "total RepoSize" ) ,
451+ Text :: from( left_repo_size. map_or_else( String :: new, bytes_size_to_string) ) ,
452+ Text :: from( right_repo_size. map_or_else( String :: new, bytes_size_to_string) ) ,
453+ ] ) ;
454+ rows. push ( vec ! [
455+ Text :: from( "exclusive RepoSize" ) ,
456+ Text :: from( left_only. map_or_else( String :: new, bytes_size_to_string) ) ,
457+ Text :: from( right_only. map_or_else( String :: new, bytes_size_to_string) ) ,
458+ ] ) ;
459+ let both = both. map_or_else ( String :: new, bytes_size_to_string) ;
460+ rows. push ( vec ! [
461+ Text :: from( "shared RepoSize" ) ,
462+ Text :: from( both. clone( ) ) ,
463+ Text :: from( both) ,
464+ ] ) ;
465+
466+ Ok ( popup_table ( "diff total" , rows) )
403467 }
404468
405469 pub fn snapshot_details ( & self ) -> PopUpTable {
@@ -448,7 +512,10 @@ impl<'a, P: ProgressBars, S: IndexedFull> ProcessEvent for Diff<'a, P, S> {
448512 }
449513 Char ( 'm' ) => self . toggle_ignore_metadata ( ) ,
450514 Char ( 'd' ) => self . toggle_ignore_identical ( ) ?,
451- Char ( 's' ) => self . compute_summary ( ) ?,
515+ Char ( 's' ) => {
516+ self . current_screen =
517+ CurrentScreen :: SnapshotDetails ( self . compute_summary ( ) ?) ;
518+ }
452519 Char ( 'I' ) => {
453520 self . current_screen =
454521 CurrentScreen :: SnapshotDetails ( self . snapshot_details ( ) ) ;
0 commit comments