Rename FileConflictData to ConflictHunk, use it in files.rs.

There's no point in having two identical types used for the same
purpose in two different places.
This commit is contained in:
Ilya Grigoriev 2022-10-30 14:26:07 -07:00
parent 85b472b507
commit 55762e3681
3 changed files with 44 additions and 47 deletions

View file

@ -19,7 +19,7 @@ use itertools::Itertools;
use crate::backend::{BackendResult, Conflict, ConflictId, ConflictPart, TreeValue};
use crate::diff::{find_line_ranges, Diff, DiffHunk};
use crate::files;
use crate::files::{MergeHunk, MergeResult};
use crate::files::{ConflictHunk, MergeHunk, MergeResult};
use crate::repo_path::RepoPath;
use crate::store::Store;
@ -133,7 +133,7 @@ pub fn materialize_conflict(
conflict: &Conflict,
output: &mut dyn Write,
) -> std::io::Result<()> {
match extract_file_conflict_data(store, path, conflict) {
match extract_file_conflict_as_single_hunk(store, path, conflict) {
None => {
// Unless all parts are regular files, we can't do much better than to try to
// describe the conflict.
@ -143,18 +143,12 @@ pub fn materialize_conflict(
}
}
/// The contents of every version of the file that participates in a conflict.
pub struct FileConflictData {
removes: Vec<Vec<u8>>,
adds: Vec<Vec<u8>>,
}
/// Only works if all parts of the conflict are regular, non-executable files
pub fn extract_file_conflict_data(
pub fn extract_file_conflict_as_single_hunk(
store: &Store,
path: &RepoPath,
conflict: &Conflict,
) -> Option<FileConflictData> {
) -> Option<ConflictHunk> {
let file_adds = file_parts(&conflict.adds);
let file_removes = file_parts(&conflict.removes);
if file_adds.len() != conflict.adds.len() || file_removes.len() != conflict.removes.len() {
@ -169,14 +163,14 @@ pub fn extract_file_conflict_data(
.map(|part| get_file_contents(store, path, part))
.collect_vec();
Some(FileConflictData {
Some(ConflictHunk {
removes: removed_content,
adds: added_content,
})
}
pub fn materialize_merge_result(
single_hunk: &FileConflictData,
single_hunk: &ConflictHunk,
output: &mut dyn Write,
) -> std::io::Result<()> {
let removed_slices = single_hunk.removes.iter().map(Vec::as_slice).collect_vec();
@ -192,10 +186,10 @@ pub fn materialize_merge_result(
MergeHunk::Resolved(content) => {
output.write_all(&content)?;
}
MergeHunk::Conflict {
MergeHunk::Conflict(ConflictHunk {
mut removes,
mut adds,
} => {
}) => {
output.write_all(CONFLICT_START_LINE)?;
while !removes.is_empty() && !adds.is_empty() {
let left = &removes[0];
@ -279,7 +273,7 @@ pub fn parse_conflict(input: &[u8], num_removes: usize, num_adds: usize) -> Opti
let conflict_body = &input[conflict_start.unwrap() + CONFLICT_START_LINE.len()..pos];
let hunk = parse_conflict_hunk(conflict_body);
match &hunk {
MergeHunk::Conflict { removes, adds }
MergeHunk::Conflict(ConflictHunk { removes, adds })
if removes.len() == num_removes && adds.len() == num_adds =>
{
let resolved_slice = &input[resolved_start..conflict_start.unwrap()];
@ -363,7 +357,7 @@ fn parse_conflict_hunk(input: &[u8]) -> MergeHunk {
}
}
MergeHunk::Conflict { removes, adds }
MergeHunk::Conflict(ConflictHunk { removes, adds })
}
/// Returns `None` if there are no conflict markers in `content`.
@ -399,7 +393,7 @@ pub fn update_conflict_from_content(
buf.extend_from_slice(&slice);
}
}
MergeHunk::Conflict { removes, adds } => {
MergeHunk::Conflict(ConflictHunk { removes, adds }) => {
for (i, buf) in removes.iter().enumerate() {
removed_content[i].extend_from_slice(buf);
}

View file

@ -141,13 +141,16 @@ impl<'a> Iterator for DiffLineIterator<'a> {
}
}
#[derive(PartialEq, Eq, Clone)]
pub struct ConflictHunk {
pub removes: Vec<Vec<u8>>,
pub adds: Vec<Vec<u8>>,
}
#[derive(PartialEq, Eq, Clone)]
pub enum MergeHunk {
Resolved(Vec<u8>),
Conflict {
removes: Vec<Vec<u8>>,
adds: Vec<Vec<u8>>,
},
Conflict(ConflictHunk),
}
impl Debug for MergeHunk {
@ -157,7 +160,7 @@ impl Debug for MergeHunk {
.debug_tuple("Resolved")
.field(&String::from_utf8_lossy(data))
.finish(),
MergeHunk::Conflict { removes, adds } => f
MergeHunk::Conflict(ConflictHunk { removes, adds }) => f
.debug_struct("Conflict")
.field(
"removes",
@ -267,7 +270,7 @@ pub fn merge(removes: &[&[u8]], adds: &[&[u8]]) -> MergeResult {
}
// Include the unfiltered lists of removed and added here, so the caller
// knows which part corresponds to which input.
merge_hunks.push(MergeHunk::Conflict {
merge_hunks.push(MergeHunk::Conflict(ConflictHunk {
removes: parts[..num_removes]
.iter()
.map(|part| part.to_vec())
@ -276,7 +279,7 @@ pub fn merge(removes: &[&[u8]], adds: &[&[u8]]) -> MergeResult {
.iter()
.map(|part| part.to_vec())
.collect_vec(),
});
}));
}
}
}
@ -341,10 +344,10 @@ mod tests {
// One side modified, two sides added
assert_eq!(
merge(&[b"a"], &[b"b", b"b", b"b"]),
MergeResult::Conflict(vec![MergeHunk::Conflict {
MergeResult::Conflict(vec![MergeHunk::Conflict(ConflictHunk {
removes: vec![b"a".to_vec()],
adds: vec![b"b".to_vec(), b"b".to_vec(), b"b".to_vec()]
}])
})])
);
// All sides removed same content
assert_eq!(
@ -354,10 +357,10 @@ mod tests {
// One side modified, two sides removed
assert_eq!(
merge(&[b"a\n", b"a\n", b"a\n"], &[b""]),
MergeResult::Conflict(vec![MergeHunk::Conflict {
MergeResult::Conflict(vec![MergeHunk::Conflict(ConflictHunk {
removes: vec![b"a\n".to_vec(), b"a\n".to_vec(), b"a\n".to_vec()],
adds: vec![b"".to_vec()]
}])
})])
);
// Three sides made the same change
assert_eq!(
@ -367,45 +370,45 @@ mod tests {
// One side unchanged, one side added
assert_eq!(
merge(&[b"a\n"], &[b"a\nb\n"]),
MergeResult::Conflict(vec![MergeHunk::Conflict {
MergeResult::Conflict(vec![MergeHunk::Conflict(ConflictHunk {
removes: vec![b"".to_vec()],
adds: vec![b"b\n".to_vec()]
}])
})])
);
// Two sides left one line unchanged, and added conflicting additional lines
assert_eq!(
merge(&[b"a\n"], &[b"a\nb\n", b"a\nc\n"]),
MergeResult::Conflict(vec![
MergeHunk::Resolved(b"a\n".to_vec()),
MergeHunk::Conflict {
MergeHunk::Conflict(ConflictHunk {
removes: vec![b"".to_vec()],
adds: vec![b"b\n".to_vec(), b"c\n".to_vec()]
}
})
])
);
// One side removed, one side modified
assert_eq!(
merge(&[b"a\n"], &[b"", b"b\n"]),
MergeResult::Conflict(vec![MergeHunk::Conflict {
MergeResult::Conflict(vec![MergeHunk::Conflict(ConflictHunk {
removes: vec![b"a\n".to_vec()],
adds: vec![b"".to_vec(), b"b\n".to_vec()]
}])
})])
);
// One side modified, one side removed
assert_eq!(
merge(&[b"a\n"], &[b"b\n", b""]),
MergeResult::Conflict(vec![MergeHunk::Conflict {
MergeResult::Conflict(vec![MergeHunk::Conflict(ConflictHunk {
removes: vec![b"a\n".to_vec()],
adds: vec![b"b\n".to_vec(), b"".to_vec()]
}])
})])
);
// Two sides modified in different ways
assert_eq!(
merge(&[b"a"], &[b"b", b"c"]),
MergeResult::Conflict(vec![MergeHunk::Conflict {
MergeResult::Conflict(vec![MergeHunk::Conflict(ConflictHunk {
removes: vec![b"a".to_vec()],
adds: vec![b"b".to_vec(), b"c".to_vec()]
}])
})])
);
// Two of three sides don't change, third side changes
assert_eq!(
@ -420,10 +423,10 @@ mod tests {
// One side unchanged, two other sides make the different change
assert_eq!(
merge(&[b"a", b"a"], &[b"b", b"a", b"c"]),
MergeResult::Conflict(vec![MergeHunk::Conflict {
MergeResult::Conflict(vec![MergeHunk::Conflict(ConflictHunk {
removes: vec![b"a".to_vec(), b"a".to_vec()],
adds: vec![b"b".to_vec(), b"a".to_vec(), b"c".to_vec()]
}])
})])
);
// Merge of an unresolved conflict and another branch, where the other branch
// undid the change from one of the inputs to the unresolved conflict in the
@ -435,10 +438,10 @@ mod tests {
// Merge of an unresolved conflict and another branch.
assert_eq!(
merge(&[b"a", b"b"], &[b"c", b"d", b"e"]),
MergeResult::Conflict(vec![MergeHunk::Conflict {
MergeResult::Conflict(vec![MergeHunk::Conflict(ConflictHunk {
removes: vec![b"a".to_vec(), b"b".to_vec()],
adds: vec![b"c".to_vec(), b"d".to_vec(), b"e".to_vec()]
}])
})])
);
}
}

View file

@ -14,7 +14,7 @@
use jujutsu_lib::backend::{Conflict, ConflictPart, TreeValue};
use jujutsu_lib::conflicts::{materialize_conflict, parse_conflict, update_conflict_from_content};
use jujutsu_lib::files::MergeHunk;
use jujutsu_lib::files::{ConflictHunk, MergeHunk};
use jujutsu_lib::repo_path::RepoPath;
use jujutsu_lib::store::Store;
use testutils::TestRepo;
@ -307,10 +307,10 @@ line 5
),
Some(vec![
MergeHunk::Resolved(b"line 1\n".to_vec()),
MergeHunk::Conflict {
MergeHunk::Conflict(ConflictHunk {
removes: vec![b"line 2\nline 3\nline 4\n".to_vec()],
adds: vec![b"line 2\nleft\nline 4\n".to_vec(), b"right\n".to_vec()]
},
}),
MergeHunk::Resolved(b"line 5\n".to_vec())
])
)
@ -342,7 +342,7 @@ line 5
),
Some(vec![
MergeHunk::Resolved(b"line 1\n".to_vec()),
MergeHunk::Conflict {
MergeHunk::Conflict(ConflictHunk {
removes: vec![
b"line 2\nline 3\nline 4\n".to_vec(),
b"line 2\nline 3\nline 4\n".to_vec()
@ -352,7 +352,7 @@ line 5
b"right\n".to_vec(),
b"line 2\nforward\nline 3\nline 4\n".to_vec()
]
},
}),
MergeHunk::Resolved(b"line 5\n".to_vec())
])
)