diff --git a/src/base.rs b/src/base.rs index ce2d7ca..1fc32a6 100644 --- a/src/base.rs +++ b/src/base.rs @@ -284,6 +284,8 @@ pub fn merge(oid: String) { let head = data::get_ref("HEAD".to_owned(), true); 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_other = get_commit(oid.clone()); @@ -296,7 +298,7 @@ pub fn merge(oid: String) { 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!("Please commit"); } @@ -410,11 +412,12 @@ fn is_branch(name: String) -> bool { 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(); + let base_tree = get_tree(base_tree, "".to_owned()); let head_tree = get_tree(head_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(); dirs.next(); diff --git a/src/diff.rs b/src/diff.rs index 80d70b9..26396ba 100644 --- a/src/diff.rs +++ b/src/diff.rs @@ -91,19 +91,32 @@ pub fn changed_files( return result; } -pub fn merge_trees(t_head: HashMap, t_other: HashMap) -> HashMap { +pub fn merge_trees( + t_base: HashMap, + t_head: HashMap, + t_other: HashMap, +) -> HashMap { 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() { - 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; } -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_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 != "" { let content = data::get_object(o_head, "blob".to_owned()); 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(); } - let output = Command::new("diff") - .arg("-DHEAD") + let output = Command::new("diff3") + .arg("-m") + .arg("-L") + .arg("HEAD") .arg(f_head.path()) + .arg("-L") + .arg("BASE") + .arg(f_base.path()) + .arg("-L") + .arg("MERGE_HEAD") .arg(f_other.path()) .stdout(Stdio::piped()) .output()