Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
conflicts: insert trailing newline when materializing conflicts
Browse files Browse the repository at this point in the history
This happens for non-empty files only; the materialization code can
handle files and hunks with 0 or more lines, but each line should
terminate in a newline.

This is an imperfect fix to jj-vcs#3968, a better fix is TODO; see jj-vcs#3975.
ilyagr committed Jun 26, 2024
1 parent d1dc97f commit 8c941fd
Showing 2 changed files with 38 additions and 4 deletions.
18 changes: 18 additions & 0 deletions lib/src/conflicts.rs
Original file line number Diff line number Diff line change
@@ -53,6 +53,8 @@ static CONFLICT_MARKER_REGEX: once_cell::sync::Lazy<Regex> = once_cell::sync::La
.unwrap()
});

/// This function assumes that each hunk consists of 0 or more lines, each
/// ending with a newline.
fn write_diff_hunks(hunks: &[DiffHunk], file: &mut dyn Write) -> std::io::Result<()> {
for hunk in hunks {
match hunk {
@@ -218,6 +220,21 @@ pub fn materialize_merge_result(
single_hunk: Merge<ContentHunk>,
output: &mut dyn Write,
) -> std::io::Result<()> {
// The following code assumes that the file contains 0 or more lines, each
// ending with `\n`. For now, we force this to be true.
// TODO(#3795): A better solution for this.
let single_hunk: Merge<ContentHunk> = Merge::from_vec(
single_hunk
.into_iter()
.map(|ContentHunk(mut side)| {
if !side.is_empty() && !side.ends_with(b"\n") {
side.push(b'\n');
};
ContentHunk(side)
})
.collect::<smallvec::SmallVec<_>>(),
);

let slices = single_hunk.map(|content| content.0.as_slice());
let merge_result = files::merge(&slices);
match merge_result {
@@ -239,6 +256,7 @@ pub fn materialize_merge_result(
output.write_all(
format!(" Conflict {conflict_index} of {num_conflicts}\n").as_bytes(),
)?;

let mut add_index = 0;
for (base_index, left) in hunk.removes().enumerate() {
// The vast majority of conflicts one actually tries to
24 changes: 20 additions & 4 deletions lib/tests/test_conflicts.rs
Original file line number Diff line number Diff line change
@@ -357,15 +357,31 @@ fn test_materialize_conflict_no_newlines_at_eof() {
@r###"
<<<<<<< Conflict 1 of 1
%%%%%%% Changes from base to side #1
-base+++++++ Contents of side #2
right>>>>>>> Conflict 1 of 1 ends
-base
+++++++ Contents of side #2
right
>>>>>>> Conflict 1 of 1 ends
"###
);
// BUG(#3968): These conflict markers cannot be parsed
// These conflict markers can be parsed (#3968)
// TODO(#3975): BUG: The result of the parsing has newlines where original files
// didn't.
insta::assert_debug_snapshot!(parse_conflict(
materialized.as_bytes(),
conflict.num_sides()
),@"None");
),@r###"
Some(
[
Conflicted(
[
"",
"base\n",
"right\n",
],
),
],
)
"###);
}

#[test]

0 comments on commit 8c941fd

Please sign in to comment.