mirror of
https://github.com/martinvonz/jj.git
synced 2025-02-07 13:00:08 +00:00
Merging is currently done with line-level granularity, so it makes sense to have newlines after the markers. That makes them easier to edit out when resolving conflicts.
118 lines
4.5 KiB
Rust
118 lines
4.5 KiB
Rust
// Copyright 2020 Google LLC
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// https://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
use std::io::{Cursor, Write};
|
|
|
|
use crate::files;
|
|
use crate::repo_path::RepoPath;
|
|
use crate::store::{Conflict, TreeValue};
|
|
use crate::store_wrapper::StoreWrapper;
|
|
|
|
pub fn materialize_conflict(
|
|
store: &StoreWrapper,
|
|
path: &RepoPath,
|
|
conflict: &Conflict,
|
|
file: &mut dyn Write,
|
|
) {
|
|
match conflict.to_three_way() {
|
|
None => {
|
|
file.write_all(b"Unresolved complex conflict.\n").unwrap();
|
|
}
|
|
Some((Some(left), Some(base), Some(right))) => {
|
|
match (left.value, base.value, right.value) {
|
|
(
|
|
TreeValue::Normal {
|
|
id: left_id,
|
|
executable: false,
|
|
},
|
|
TreeValue::Normal {
|
|
id: base_id,
|
|
executable: false,
|
|
},
|
|
TreeValue::Normal {
|
|
id: right_id,
|
|
executable: false,
|
|
},
|
|
) => {
|
|
let mut left_contents: Vec<u8> = vec![];
|
|
let mut base_contents: Vec<u8> = vec![];
|
|
let mut right_contents: Vec<u8> = vec![];
|
|
let file_path = path.to_file_repo_path();
|
|
store
|
|
.read_file(&file_path, &left_id)
|
|
.unwrap()
|
|
.read_to_end(&mut left_contents)
|
|
.unwrap();
|
|
store
|
|
.read_file(&file_path, &base_id)
|
|
.unwrap()
|
|
.read_to_end(&mut base_contents)
|
|
.unwrap();
|
|
store
|
|
.read_file(&file_path, &right_id)
|
|
.unwrap()
|
|
.read_to_end(&mut right_contents)
|
|
.unwrap();
|
|
let merge_result =
|
|
files::merge(&base_contents, &left_contents, &right_contents);
|
|
match merge_result {
|
|
files::MergeResult::Resolved(contents) => {
|
|
file.write_all(&contents).unwrap();
|
|
}
|
|
files::MergeResult::Conflict(hunks) => {
|
|
for hunk in hunks {
|
|
match hunk {
|
|
files::MergeHunk::Resolved(contents) => {
|
|
file.write_all(&contents).unwrap();
|
|
}
|
|
files::MergeHunk::Conflict { base, left, right } => {
|
|
file.write_all(b"<<<<<<<\n").unwrap();
|
|
file.write_all(&left).unwrap();
|
|
file.write_all(b"|||||||\n").unwrap();
|
|
file.write_all(&base).unwrap();
|
|
file.write_all(b"=======\n").unwrap();
|
|
file.write_all(&right).unwrap();
|
|
file.write_all(b">>>>>>>\n").unwrap();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
_ => {
|
|
file.write_all(b"Unresolved 3-way conflict.\n").unwrap();
|
|
}
|
|
}
|
|
}
|
|
Some(_) => {
|
|
file.write_all(b"Unresolved complex conflict.\n").unwrap();
|
|
}
|
|
}
|
|
}
|
|
|
|
pub fn conflict_to_materialized_value(
|
|
store: &StoreWrapper,
|
|
path: &RepoPath,
|
|
conflict: &Conflict,
|
|
) -> TreeValue {
|
|
let mut buf = vec![];
|
|
materialize_conflict(store, &path, &conflict, &mut buf);
|
|
let file_id = store
|
|
.write_file(&path.to_file_repo_path(), &mut Cursor::new(&buf))
|
|
.unwrap();
|
|
TreeValue::Normal {
|
|
id: file_id,
|
|
executable: false,
|
|
}
|
|
}
|