Show file size before/after on binary files

pull/864/head
Wilfred Hughes 2025-07-11 09:47:20 +07:00
parent fd6a9a365b
commit e596c52c53
4 changed files with 51 additions and 15 deletions

@ -11,6 +11,11 @@ binary files were treated as text.
Added the `--override-binary` option to force files to be treated as Added the `--override-binary` option to force files to be treated as
binary rather than text. binary rather than text.
### Display
When diffing binary files, the file sizes are now shown to help see
big changes.
## 0.64 (released 16th June 2025) ## 0.64 (released 16th June 2025)
### Parsing ### Parsing

@ -156,7 +156,7 @@ impl<'f> From<&'f DiffResult> for File<'f> {
File::with_sections(&summary.file_format, &summary.display_path, chunks) File::with_sections(&summary.file_format, &summary.display_path, chunks)
} }
(FileContent::Binary, FileContent::Binary) => { (FileContent::Binary, FileContent::Binary) => {
let status = if summary.has_byte_changes { let status = if summary.has_byte_changes.is_some() {
Status::Changed Status::Changed
} else { } else {
Status::Unchanged Status::Unchanged

@ -407,6 +407,11 @@ fn diff_file(
guess_content(&rhs_bytes, rhs_path, binary_overrides), guess_content(&rhs_bytes, rhs_path, binary_overrides),
) { ) {
(ProbableFileKind::Binary, _) | (_, ProbableFileKind::Binary) => { (ProbableFileKind::Binary, _) | (_, ProbableFileKind::Binary) => {
let has_byte_changes = if lhs_bytes == rhs_bytes {
None
} else {
Some((lhs_bytes.len(), rhs_bytes.len()))
};
return DiffResult { return DiffResult {
extra_info: renamed, extra_info: renamed,
display_path: display_path.to_owned(), display_path: display_path.to_owned(),
@ -416,7 +421,7 @@ fn diff_file(
lhs_positions: vec![], lhs_positions: vec![],
rhs_positions: vec![], rhs_positions: vec![],
hunks: vec![], hunks: vec![],
has_byte_changes: lhs_bytes != rhs_bytes, has_byte_changes,
has_syntactic_changes: false, has_syntactic_changes: false,
}; };
} }
@ -549,7 +554,11 @@ fn check_only_text(
lhs_src: &str, lhs_src: &str,
rhs_src: &str, rhs_src: &str,
) -> DiffResult { ) -> DiffResult {
let has_changes = lhs_src != rhs_src; let has_byte_changes = if lhs_src == rhs_src {
None
} else {
Some((lhs_src.as_bytes().len(), rhs_src.as_bytes().len()))
};
DiffResult { DiffResult {
display_path: display_path.to_owned(), display_path: display_path.to_owned(),
@ -560,8 +569,8 @@ fn check_only_text(
lhs_positions: vec![], lhs_positions: vec![],
rhs_positions: vec![], rhs_positions: vec![],
hunks: vec![], hunks: vec![],
has_byte_changes: has_changes, has_byte_changes,
has_syntactic_changes: has_changes, has_syntactic_changes: lhs_src != rhs_src,
} }
} }
@ -601,7 +610,7 @@ fn diff_file_content(
lhs_positions: vec![], lhs_positions: vec![],
rhs_positions: vec![], rhs_positions: vec![],
hunks: vec![], hunks: vec![],
has_byte_changes: false, has_byte_changes: None,
has_syntactic_changes: false, has_syntactic_changes: false,
}; };
} }
@ -633,6 +642,13 @@ fn diff_file_content(
Ok((lhs, rhs)) => { Ok((lhs, rhs)) => {
if diff_options.check_only { if diff_options.check_only {
let has_syntactic_changes = lhs != rhs; let has_syntactic_changes = lhs != rhs;
let has_byte_changes = if lhs_src == rhs_src {
None
} else {
Some((lhs_src.as_bytes().len(), rhs_src.as_bytes().len()))
};
return DiffResult { return DiffResult {
extra_info, extra_info,
display_path: display_path.to_owned(), display_path: display_path.to_owned(),
@ -642,7 +658,7 @@ fn diff_file_content(
lhs_positions: vec![], lhs_positions: vec![],
rhs_positions: vec![], rhs_positions: vec![],
hunks: vec![], hunks: vec![],
has_byte_changes: true, has_byte_changes,
has_syntactic_changes, has_syntactic_changes,
}; };
} }
@ -775,6 +791,12 @@ fn diff_file_content(
); );
let has_syntactic_changes = !hunks.is_empty(); let has_syntactic_changes = !hunks.is_empty();
let has_byte_changes = if lhs_src == rhs_src {
None
} else {
Some((lhs_src.as_bytes().len(), rhs_src.as_bytes().len()))
};
DiffResult { DiffResult {
extra_info, extra_info,
display_path: display_path.to_owned(), display_path: display_path.to_owned(),
@ -784,7 +806,7 @@ fn diff_file_content(
lhs_positions, lhs_positions,
rhs_positions, rhs_positions,
hunks, hunks,
has_byte_changes: true, has_byte_changes,
has_syntactic_changes, has_syntactic_changes,
} }
} }
@ -923,7 +945,7 @@ fn print_diff_result(display_options: &DisplayOptions, summary: &DiffResult) {
} }
} }
(FileContent::Binary, FileContent::Binary) => { (FileContent::Binary, FileContent::Binary) => {
if display_options.print_unchanged || summary.has_byte_changes { if display_options.print_unchanged || summary.has_byte_changes.is_some() {
println!( println!(
"{}", "{}",
display::style::header( display::style::header(
@ -935,10 +957,17 @@ fn print_diff_result(display_options: &DisplayOptions, summary: &DiffResult) {
display_options display_options
) )
); );
if summary.has_byte_changes {
println!("Binary contents changed.\n"); match summary.has_byte_changes {
} else { Some((lhs_len, rhs_len)) => {
println!("No changes.\n"); let format_options = FormatSizeOptions::from(BINARY).decimal_places(1);
println!(
"Binary contents changed (old: {}, new: {}).\n",
&format_size(lhs_len, format_options),
&format_size(rhs_len, format_options),
)
}
None => println!("No changes.\n"),
} }
} }
} }

@ -50,7 +50,9 @@ pub(crate) struct DiffResult {
pub(crate) lhs_positions: Vec<MatchedPos>, pub(crate) lhs_positions: Vec<MatchedPos>,
pub(crate) rhs_positions: Vec<MatchedPos>, pub(crate) rhs_positions: Vec<MatchedPos>,
pub(crate) has_byte_changes: bool, /// If the two files do not have exactly the same bytes, the
/// number of bytes in each file.
pub(crate) has_byte_changes: Option<(usize, usize)>,
pub(crate) has_syntactic_changes: bool, pub(crate) has_syntactic_changes: bool,
} }
@ -59,7 +61,7 @@ impl DiffResult {
if matches!(self.lhs_src, FileContent::Binary) if matches!(self.lhs_src, FileContent::Binary)
|| matches!(self.rhs_src, FileContent::Binary) || matches!(self.rhs_src, FileContent::Binary)
{ {
return self.has_byte_changes; return self.has_byte_changes.is_some();
} }
self.has_syntactic_changes self.has_syntactic_changes