conflicts: allow CRLF line endings on conflict markers

Currently, conflict markers ending in CRLF line endings aren't allowed.
I don't see any reason why we should reject them, since some
editors/tools might produce CRLF automatically on Windows when saving
files, which would break the conflicts otherwise.
This commit is contained in:
Scott Taylor 2024-11-20 18:04:25 -06:00 committed by Scott Taylor
parent ee7f829d4c
commit 9674852dc7
2 changed files with 31 additions and 5 deletions

View file

@ -20,6 +20,7 @@ use std::io::Write;
use std::iter::zip;
use bstr::BString;
use bstr::ByteSlice;
use futures::stream::BoxStream;
use futures::try_join;
use futures::Stream;
@ -394,7 +395,7 @@ pub fn parse_conflict(input: &[u8], num_sides: usize) -> Option<Vec<Merge<BStrin
let mut conflict_start = None;
let mut conflict_start_len = 0;
for line in input.split_inclusive(|b| *b == b'\n') {
if CONFLICT_MARKER_REGEX.is_match_at(line, 0) {
if is_conflict_marker_line(line) {
if line[0] == CONFLICT_START_LINE_CHAR {
conflict_start = Some(pos);
conflict_start_len = line.len();
@ -436,7 +437,7 @@ fn parse_conflict_hunk(input: &[u8]) -> Merge<BString> {
let mut removes = vec![];
let mut adds = vec![];
for line in input.split_inclusive(|b| *b == b'\n') {
if CONFLICT_MARKER_REGEX.is_match_at(line, 0) {
if is_conflict_marker_line(line) {
match line[0] {
CONFLICT_DIFF_LINE_CHAR => {
state = State::Diff;
@ -492,6 +493,13 @@ fn parse_conflict_hunk(input: &[u8]) -> Merge<BString> {
}
}
/// Check whether a line is a conflict marker. Removes trailing whitespace
/// before checking against regex to ensure it parses CRLF endings correctly.
fn is_conflict_marker_line(line: &[u8]) -> bool {
let line = line.trim_end_with(|ch| ch.is_ascii_whitespace());
CONFLICT_MARKER_REGEX.is_match_at(line, 0)
}
/// Parses conflict markers in `content` and returns an updated version of
/// `file_ids` with the new contents. If no (valid) conflict markers remain, a
/// single resolves `FileId` will be returned.

View file

@ -727,8 +727,8 @@ fn test_parse_conflict_multi_way() {
#[test]
fn test_parse_conflict_crlf_markers() {
// Conflict markers aren't recognized due to CRLF
assert_eq!(
// Conflict markers should be recognized even with CRLF
insta::assert_debug_snapshot!(
parse_conflict(
indoc! {b"
line 1\r
@ -744,7 +744,25 @@ fn test_parse_conflict_crlf_markers() {
"},
2
),
None
@r#"
Some(
[
Resolved(
"line 1\r\n",
),
Conflicted(
[
"left\r\n",
"base\r\n",
"right\r\n",
],
),
Resolved(
"line 5\r\n",
),
],
)
"#
);
}