Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 75 additions & 0 deletions src/diff/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -642,6 +642,81 @@ void Chunk_copy(Chunk *src, size_t src_start, Chunk *dst, size_t dst_start, size
assert_patch!(original, a, expected_diffy);
}

#[test]
fn suppress_blank_empty() {
let original = "\
1
2
3

4
";

let modified = "\
1
2
3

5
";

// Note that there is a space " " on the line after 3
let expected = "\
--- original
+++ modified
@@ -2,4 +2,4 @@
2
3

-4
+5
";

let f = PatchFormatter::new().suppress_blank_empty(false);
let patch = create_patch(original, modified);
let bpatch = create_patch_bytes(original.as_bytes(), modified.as_bytes());
let patch_str = format!("{}", f.fmt_patch(&patch));
let mut patch_bytes = Vec::new();
f.write_patch_into(&bpatch, &mut patch_bytes).unwrap();

assert_eq!(patch_str, expected);
assert_eq!(patch_bytes, patch_str.as_bytes());
assert_eq!(patch_bytes, expected.as_bytes());
assert_eq!(apply(original, &patch).unwrap(), modified);
assert_eq!(
crate::apply_bytes(original.as_bytes(), &bpatch).unwrap(),
modified.as_bytes()
);

// Note that there is no space " " on the line after 3
let expected_suppressed = "\
--- original
+++ modified
@@ -2,4 +2,4 @@
2
3

-4
+5
";

let f = PatchFormatter::new().suppress_blank_empty(true);
let patch = create_patch(original, modified);
let bpatch = create_patch_bytes(original.as_bytes(), modified.as_bytes());
let patch_str = format!("{}", f.fmt_patch(&patch));
let mut patch_bytes = Vec::new();
f.write_patch_into(&bpatch, &mut patch_bytes).unwrap();

assert_eq!(patch_str, expected_suppressed);
assert_eq!(patch_bytes, patch_str.as_bytes());
assert_eq!(patch_bytes, expected_suppressed.as_bytes());
assert_eq!(apply(original, &patch).unwrap(), modified);
assert_eq!(
crate::apply_bytes(original.as_bytes(), &bpatch).unwrap(),
modified.as_bytes()
);
}

// In the event that a patch has an invalid hunk range we want to ensure that when apply is
// attempting to search for a matching position to apply a hunk that the search algorithm runs in
// time bounded by the length of the original image being patched. Before clamping the search space
Expand Down
23 changes: 21 additions & 2 deletions src/patch/format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use std::{
pub struct PatchFormatter {
with_color: bool,
with_missing_newline_message: bool,
suppress_blank_empty: bool,

context: Style,
delete: Style,
Expand All @@ -26,6 +27,10 @@ impl PatchFormatter {
with_color: false,
with_missing_newline_message: true,

// TODO the default in git-diff and GNU diff is to have this set to false, on the next
// semver breaking release we should contemplate switching this to be false by default
suppress_blank_empty: true,

context: Style::new(),
delete: Color::Red.normal(),
insert: Color::Green.normal(),
Expand Down Expand Up @@ -54,6 +59,20 @@ impl PatchFormatter {
self
}

/// Sets whether to suppress printing of a space before empty lines.
///
/// Defaults to `true`.
///
/// For more information you can refer to the [Omitting trailing blanks] manual page of GNU
/// diff or the [diff.suppressBlankEmpty] config for `git-diff`.
///
/// [Omitting trailing blanks]: https://www.gnu.org/software/diffutils/manual/html_node/Trailing-Blanks.html
/// [diff.suppressBlankEmpty]: https://git-scm.com/docs/git-diff#Documentation/git-diff.txt-codediffsuppressBlankEmptycode
pub fn suppress_blank_empty(mut self, enable: bool) -> Self {
self.suppress_blank_empty = enable;
self
}

/// Returns a `Display` impl which can be used to print a Patch
pub fn fmt_patch<'a>(&'a self, patch: &'a Patch<'a, str>) -> impl Display + 'a {
PatchDisplay { f: self, patch }
Expand Down Expand Up @@ -240,7 +259,7 @@ impl<T: AsRef<[u8]> + ?Sized> LineDisplay<'_, T> {
write!(w, "{}", style.prefix())?;
}

if sign == ' ' && line == b"\n" {
if self.f.suppress_blank_empty && sign == ' ' && line == b"\n" {
w.write_all(line)?;
} else {
write!(w, "{}", sign)?;
Expand Down Expand Up @@ -274,7 +293,7 @@ impl Display for LineDisplay<'_, str> {
write!(f, "{}", style.prefix())?;
}

if sign == ' ' && *line == "\n" {
if self.f.suppress_blank_empty && sign == ' ' && *line == "\n" {
write!(f, "{}", line)?;
} else {
write!(f, "{}{}", sign, line)?;
Expand Down
Loading