step fifty three: three way merge

This commit is contained in:
Gonçalo Valério 2020-11-30 23:22:00 +00:00
parent c51db4a8f1
commit 8060fab18e
2 changed files with 32 additions and 9 deletions

View File

@ -284,6 +284,8 @@ pub fn merge(oid: String) {
let head = data::get_ref("HEAD".to_owned(), true); let head = data::get_ref("HEAD".to_owned(), true);
assert!(head.value != ""); assert!(head.value != "");
let merge_base = get_merge_base(oid.clone(), head.value.clone());
let c_base = get_commit(merge_base);
let c_head = get_commit(head.value); let c_head = get_commit(head.value);
let c_other = get_commit(oid.clone()); let c_other = get_commit(oid.clone());
@ -296,7 +298,7 @@ pub fn merge(oid: String) {
true, true,
); );
read_tree_merged(c_head.tree, c_other.tree); read_tree_merged(c_base.tree, c_head.tree, c_other.tree);
println!("Merged in working tree"); println!("Merged in working tree");
println!("Please commit"); println!("Please commit");
} }
@ -410,11 +412,12 @@ fn is_branch(name: String) -> bool {
return data::get_ref(name, true).value != ""; return data::get_ref(name, true).value != "";
} }
fn read_tree_merged(head_tree: String, commit_tree: String) { fn read_tree_merged(base_tree: String, head_tree: String, commit_tree: String) {
empty_current_directory(".").unwrap(); empty_current_directory(".").unwrap();
let base_tree = get_tree(base_tree, "".to_owned());
let head_tree = get_tree(head_tree, "".to_owned()); let head_tree = get_tree(head_tree, "".to_owned());
let commit_tree = get_tree(commit_tree, "".to_owned()); let commit_tree = get_tree(commit_tree, "".to_owned());
for (path, blob) in diff::merge_trees(head_tree, commit_tree) { for (path, blob) in diff::merge_trees(base_tree, head_tree, commit_tree) {
let mut dirs = Path::new(&path).ancestors(); let mut dirs = Path::new(&path).ancestors();
dirs.next(); dirs.next();

View File

@ -91,19 +91,32 @@ pub fn changed_files(
return result; return result;
} }
pub fn merge_trees(t_head: HashMap<String, String>, t_other: HashMap<String, String>) -> HashMap<String, String> { pub fn merge_trees(
t_base: HashMap<String, String>,
t_head: HashMap<String, String>,
t_other: HashMap<String, String>,
) -> HashMap<String, String> {
let mut tree = HashMap::new(); let mut tree = HashMap::new();
let trees = vec![t_head, t_other]; let trees = vec![t_base, t_head, t_other];
for (path, oids) in compare_trees(trees).iter() { for (path, oids) in compare_trees(trees).iter() {
tree.insert(path.clone(), merge_blobs(oids[0].clone(), oids[1].clone())); tree.insert(
path.clone(),
merge_blobs(oids[0].clone(), oids[1].clone(), oids[2].clone()),
);
} }
return tree; return tree;
} }
fn merge_blobs(o_head: String, o_other: String) -> String { fn merge_blobs(o_base: String, o_head: String, o_other: String) -> String {
let f_base = NamedTempFile::new().unwrap();
let f_head = NamedTempFile::new().unwrap(); let f_head = NamedTempFile::new().unwrap();
let f_other = NamedTempFile::new().unwrap(); let f_other = NamedTempFile::new().unwrap();
if o_base != "" {
let content = data::get_object(o_base, "blob".to_owned());
fs::write(f_base.path(), content).unwrap();
}
if o_head != "" { if o_head != "" {
let content = data::get_object(o_head, "blob".to_owned()); let content = data::get_object(o_head, "blob".to_owned());
fs::write(f_head.path(), content).unwrap(); fs::write(f_head.path(), content).unwrap();
@ -114,9 +127,16 @@ fn merge_blobs(o_head: String, o_other: String) -> String {
fs::write(f_other.path(), content).unwrap(); fs::write(f_other.path(), content).unwrap();
} }
let output = Command::new("diff") let output = Command::new("diff3")
.arg("-DHEAD") .arg("-m")
.arg("-L")
.arg("HEAD")
.arg(f_head.path()) .arg(f_head.path())
.arg("-L")
.arg("BASE")
.arg(f_base.path())
.arg("-L")
.arg("MERGE_HEAD")
.arg(f_other.path()) .arg(f_other.path())
.stdout(Stdio::piped()) .stdout(Stdio::piped())
.output() .output()