From c0a26f76426e4aa457f5c84080893bc926f4e844 Mon Sep 17 00:00:00 2001 From: Martin von Zweigbergk Date: Wed, 13 Oct 2021 11:08:01 -0700 Subject: [PATCH] conflicts: work around rust-lang/rust#89716 --- lib/src/conflicts.rs | 30 +++++++++++----- lib/src/files.rs | 72 +++++++++++++++++++++---------------- lib/tests/test_conflicts.rs | 3 +- 3 files changed, 64 insertions(+), 41 deletions(-) diff --git a/lib/src/conflicts.rs b/lib/src/conflicts.rs index 06bb67fea4..aa2524a226 100644 --- a/lib/src/conflicts.rs +++ b/lib/src/conflicts.rs @@ -102,19 +102,31 @@ fn write_diff_hunks(left: &[u8], right: &[u8], file: &mut dyn Write) -> std::io: for hunk in diff.hunks() { match hunk { DiffHunk::Matching(content) => { - for line in content.split_inclusive(|b| *b == b'\n') { - file.write_all(b" ")?; - file.write_all(line)?; + // TODO: Remove this check once https://github.com/rust-lang/rust/issues/89716 + // has been fixed and released for long enough. + if !content.is_empty() { + for line in content.split_inclusive(|b| *b == b'\n') { + file.write_all(b" ")?; + file.write_all(line)?; + } } } DiffHunk::Different(content) => { - for line in content[0].split_inclusive(|b| *b == b'\n') { - file.write_all(b"-")?; - file.write_all(line)?; + // TODO: Remove this check once https://github.com/rust-lang/rust/issues/89716 + // has been fixed and released for long enough. + if !content[0].is_empty() { + for line in content[0].split_inclusive(|b| *b == b'\n') { + file.write_all(b"-")?; + file.write_all(line)?; + } } - for line in content[1].split_inclusive(|b| *b == b'\n') { - file.write_all(b"+")?; - file.write_all(line)?; + // TODO: Remove this check once https://github.com/rust-lang/rust/issues/89716 + // has been fixed and released for long enough. + if !content[1].is_empty() { + for line in content[1].split_inclusive(|b| *b == b'\n') { + file.write_all(b"+")?; + file.write_all(line)?; + } } } } diff --git a/lib/src/files.rs b/lib/src/files.rs index 7e83f6555c..5a6bb55513 100644 --- a/lib/src/files.rs +++ b/lib/src/files.rs @@ -85,44 +85,56 @@ impl<'a> Iterator for DiffLineIterator<'a> { self.current_pos += 1; match hunk { diff::DiffHunk::Matching(text) => { - let lines = text.split_inclusive(|b| *b == b'\n'); - for line in lines { - self.current_line.has_left_content = true; - self.current_line.has_right_content = true; - self.current_line.hunks.push(DiffHunk::Matching(line)); - if line.ends_with(b"\n") { - self.queued_lines.push_back(self.current_line.clone()); - self.current_line.left_line_number += 1; - self.current_line.right_line_number += 1; - self.current_line.reset_line(); + // TODO: Remove this check once https://github.com/rust-lang/rust/issues/89716 + // has been fixed and released for long enough. + if !text.is_empty() { + let lines = text.split_inclusive(|b| *b == b'\n'); + for line in lines { + self.current_line.has_left_content = true; + self.current_line.has_right_content = true; + self.current_line.hunks.push(DiffHunk::Matching(line)); + if line.ends_with(b"\n") { + self.queued_lines.push_back(self.current_line.clone()); + self.current_line.left_line_number += 1; + self.current_line.right_line_number += 1; + self.current_line.reset_line(); + } } } } diff::DiffHunk::Different(contents) => { let left = contents[0]; let right = contents[1]; - let left_lines = left.split_inclusive(|b| *b == b'\n'); - for left_line in left_lines { - self.current_line.has_left_content = true; - self.current_line - .hunks - .push(DiffHunk::Different(vec![left_line, b""])); - if left_line.ends_with(b"\n") { - self.queued_lines.push_back(self.current_line.clone()); - self.current_line.left_line_number += 1; - self.current_line.reset_line(); + // TODO: Remove this check once https://github.com/rust-lang/rust/issues/89716 + // has been fixed and released for long enough. + if !left.is_empty() { + let left_lines = left.split_inclusive(|b| *b == b'\n'); + for left_line in left_lines { + self.current_line.has_left_content = true; + self.current_line + .hunks + .push(DiffHunk::Different(vec![left_line, b""])); + if left_line.ends_with(b"\n") { + self.queued_lines.push_back(self.current_line.clone()); + self.current_line.left_line_number += 1; + self.current_line.reset_line(); + } } } - let right_lines = right.split_inclusive(|b| *b == b'\n'); - for right_line in right_lines { - self.current_line.has_right_content = true; - self.current_line - .hunks - .push(DiffHunk::Different(vec![b"", right_line])); - if right_line.ends_with(b"\n") { - self.queued_lines.push_back(self.current_line.clone()); - self.current_line.right_line_number += 1; - self.current_line.reset_line(); + // TODO: Remove this check once https://github.com/rust-lang/rust/issues/89716 + // has been fixed and released for long enough. + if !right.is_empty() { + let right_lines = right.split_inclusive(|b| *b == b'\n'); + for right_line in right_lines { + self.current_line.has_right_content = true; + self.current_line + .hunks + .push(DiffHunk::Different(vec![b"", right_line])); + if right_line.ends_with(b"\n") { + self.queued_lines.push_back(self.current_line.clone()); + self.current_line.right_line_number += 1; + self.current_line.reset_line(); + } } } } diff --git a/lib/tests/test_conflicts.rs b/lib/tests/test_conflicts.rs index 68cceae1b8..5a7edcd0a2 100644 --- a/lib/tests/test_conflicts.rs +++ b/lib/tests/test_conflicts.rs @@ -234,7 +234,6 @@ line 5 let mut result: Vec = vec![]; materialize_conflict(repo.store(), &path, &conflict, &mut result); - // TODO: There's an extra "+" after "-line 3". assert_eq!( String::from_utf8(result).unwrap().as_str(), "line 1 @@ -243,7 +242,7 @@ line 2 ------- +++++++ -line 3 -++++++++ ++++++++ right >>>>>>> line 4