conflicts: extract function for materializing hunk

This will make it easier to add a second code path for Git-style
conflicts in a later commit.
This commit is contained in:
Scott Taylor 2024-11-17 07:41:38 -06:00 committed by Scott Taylor
parent d2b06b9cf9
commit 54c453ba8d

View file

@ -278,6 +278,30 @@ fn materialize_conflict_hunks(
hunks: &[Merge<BString>], hunks: &[Merge<BString>],
conflict_marker_style: ConflictMarkerStyle, conflict_marker_style: ConflictMarkerStyle,
output: &mut dyn Write, output: &mut dyn Write,
) -> io::Result<()> {
let num_conflicts = hunks
.iter()
.filter(|hunk| hunk.as_resolved().is_none())
.count();
let mut conflict_index = 0;
for hunk in hunks {
if let Some(content) = hunk.as_resolved() {
output.write_all(content)?;
} else {
conflict_index += 1;
let conflict_info = format!("Conflict {conflict_index} of {num_conflicts}");
materialize_jj_style_conflict(hunk, &conflict_info, conflict_marker_style, output)?;
}
}
Ok(())
}
fn materialize_jj_style_conflict(
hunk: &Merge<BString>,
conflict_info: &str,
conflict_marker_style: ConflictMarkerStyle,
output: &mut dyn Write,
) -> io::Result<()> { ) -> io::Result<()> {
// Write a positive snapshot (side) of a conflict // Write a positive snapshot (side) of a conflict
fn write_side(add_index: usize, data: &[u8], output: &mut dyn Write) -> io::Result<()> { fn write_side(add_index: usize, data: &[u8], output: &mut dyn Write) -> io::Result<()> {
@ -310,24 +334,11 @@ fn materialize_conflict_hunks(
write_diff_hunks(diff, output) write_diff_hunks(diff, output)
} }
let num_conflicts = hunks writeln!(output, "{CONFLICT_START_LINE} {conflict_info}")?;
.iter()
.filter(|hunk| hunk.as_resolved().is_none())
.count();
let mut conflict_index = 0;
for hunk in hunks {
if let Some(content) = hunk.as_resolved() {
output.write_all(content)?;
} else {
conflict_index += 1;
writeln!(
output,
"{CONFLICT_START_LINE} Conflict {conflict_index} of {num_conflicts}"
)?;
let mut add_index = 0; let mut add_index = 0;
for (base_index, left) in hunk.removes().enumerate() { for (base_index, left) in hunk.removes().enumerate() {
// The vast majority of conflicts one actually tries to // The vast majority of conflicts one actually tries to resolve manually have 1
// resolve manually have 1 base. // base.
let base_str = if hunk.removes().len() == 1 { let base_str = if hunk.removes().len() == 1 {
"base".to_string() "base".to_string()
} else { } else {
@ -335,8 +346,8 @@ fn materialize_conflict_hunks(
}; };
let Some(right1) = hunk.get_add(add_index) else { let Some(right1) = hunk.get_add(add_index) else {
// If we have no more positive terms, emit the remaining negative // If we have no more positive terms, emit the remaining negative terms as
// terms as snapshots. // snapshots.
write_base(&base_str, left, output)?; write_base(&base_str, left, output)?;
continue; continue;
}; };
@ -350,15 +361,14 @@ fn materialize_conflict_hunks(
} }
let diff1 = Diff::by_line([&left, &right1]).hunks().collect_vec(); let diff1 = Diff::by_line([&left, &right1]).hunks().collect_vec();
// Check if the diff against the next positive term is better. Since // Check if the diff against the next positive term is better. Since we want to
// we want to preserve the order of the terms, we don't match against // preserve the order of the terms, we don't match against any later positive
// any later positive terms. // terms.
if let Some(right2) = hunk.get_add(add_index + 1) { if let Some(right2) = hunk.get_add(add_index + 1) {
let diff2 = Diff::by_line([&left, &right2]).hunks().collect_vec(); let diff2 = Diff::by_line([&left, &right2]).hunks().collect_vec();
if diff_size(&diff2) < diff_size(&diff1) { if diff_size(&diff2) < diff_size(&diff1) {
// If the next positive term is a better match, emit // If the next positive term is a better match, emit the current positive term
// the current positive term as a snapshot and the next // as a snapshot and the next positive term as a diff.
// positive term as a diff.
write_side(add_index, right1, output)?; write_side(add_index, right1, output)?;
write_diff(&base_str, add_index + 1, &diff2, output)?; write_diff(&base_str, add_index + 1, &diff2, output)?;
add_index += 2; add_index += 2;
@ -374,12 +384,7 @@ fn materialize_conflict_hunks(
for (add_index, slice) in hunk.adds().enumerate().skip(add_index) { for (add_index, slice) in hunk.adds().enumerate().skip(add_index) {
write_side(add_index, slice, output)?; write_side(add_index, slice, output)?;
} }
writeln!( writeln!(output, "{CONFLICT_END_LINE} {conflict_info} ends")?;
output,
"{CONFLICT_END_LINE} Conflict {conflict_index} of {num_conflicts} ends"
)?;
}
}
Ok(()) Ok(())
} }