diff --git a/src/base.rs b/src/base.rs index 0240042..ce2d7ca 100644 --- a/src/base.rs +++ b/src/base.rs @@ -301,6 +301,24 @@ pub fn merge(oid: String) { println!("Please commit"); } +pub fn get_merge_base(commit1: String, commit2: String) -> String { + let mut commit1_deq = VecDeque::new(); + commit1_deq.push_front(commit1); + + let mut commit2_deq = VecDeque::new(); + commit2_deq.push_front(commit2); + + let parents1 = iter_commits_and_parents(commit1_deq); + + for oid in iter_commits_and_parents(commit2_deq) { + if parents1.contains(&oid) { + return oid; + } + } + + return "".to_owned(); +} + fn is_ignored(path: &String) -> bool { if path.contains(".rgit") { true diff --git a/src/main.rs b/src/main.rs index e0d09b8..6b2ffb6 100644 --- a/src/main.rs +++ b/src/main.rs @@ -86,6 +86,12 @@ fn main() { .about("Merge changes of a different commit/branch") .arg(Arg::with_name("commit").index(1).required(true)), ) + .subcommand( + SubCommand::with_name("merge-base") + .about("Find the common ancestor between two commits") + .arg(Arg::with_name("commit1").index(1).required(true)) + .arg(Arg::with_name("commit2").index(2).required(true)), + ) .get_matches(); match matches.subcommand_name() { @@ -105,6 +111,7 @@ fn main() { Some("show") => show(matches), Some("diff") => difference(matches), Some("merge") => merge(matches), + Some("merge-base") => merge_base(matches), _ => println!("unknown sub command"), } } @@ -326,6 +333,14 @@ fn merge(matches: ArgMatches) { } } +fn merge_base(matches: ArgMatches) { + if let Some(cmd_matches) = matches.subcommand_matches("merge-base") { + let commit1 = base::get_oid(cmd_matches.value_of("commit1").unwrap().to_owned()); + let commit2 = base::get_oid(cmd_matches.value_of("commit2").unwrap().to_owned()); + println!("{}", base::get_merge_base(commit1, commit2)); + } +} + fn print_commit(oid: String, commit: &base::Commit, mut refs: HashMap>) { let ref_str = if refs.contains_key(&oid) { refs.get_mut(&oid).unwrap().join(", ")