summaryrefslogtreecommitdiffstats
path: root/asyncgit/src/sync/branch/merge_rebase.rs
diff options
context:
space:
mode:
Diffstat (limited to 'asyncgit/src/sync/branch/merge_rebase.rs')
-rw-r--r--asyncgit/src/sync/branch/merge_rebase.rs576
1 files changed, 288 insertions, 288 deletions
diff --git a/asyncgit/src/sync/branch/merge_rebase.rs b/asyncgit/src/sync/branch/merge_rebase.rs
index e3d3a3dc..eb920094 100644
--- a/asyncgit/src/sync/branch/merge_rebase.rs
+++ b/asyncgit/src/sync/branch/merge_rebase.rs
@@ -1,341 +1,341 @@
//! merging from upstream (rebase)
use crate::{
- error::{Error, Result},
- sync::utils,
+ error::{Error, Result},
+ sync::utils,
};
use git2::BranchType;
use scopetime::scope_time;
/// trys merging current branch with its upstrema using rebase
pub fn merge_upstream_rebase(
- repo_path: &str,
- branch_name: &str,
+ repo_path: &str,
+ branch_name: &str,
) -> Result<()> {
- scope_time!("merge_upstream_rebase");
-
- let repo = utils::repo(repo_path)?;
- if super::get_branch_name_repo(&repo)? != branch_name {
- return Err(Error::Generic(String::from(
- "can only rebase in head branch",
- )));
- }
-
- let branch = repo.find_branch(branch_name, BranchType::Local)?;
- let upstream = branch.upstream()?;
- let upstream_commit = upstream.get().peel_to_commit()?;
- let annotated_upstream =
- repo.find_annotated_commit(upstream_commit.id())?;
-
- let mut rebase =
- repo.rebase(None, Some(&annotated_upstream), None, None)?;
-
- let signature =
- crate::sync::commit::signature_allow_undefined_name(&repo)?;
-
- while let Some(op) = rebase.next() {
- let _op = op?;
- // dbg!(op.id());
-
- if repo.index()?.has_conflicts() {
- rebase.abort()?;
- return Err(Error::Generic(String::from(
- "conflicts while merging",
- )));
- }
-
- rebase.commit(None, &signature, None)?;
- }
-
- if repo.index()?.has_conflicts() {
- rebase.abort()?;
- return Err(Error::Generic(String::from(
- "conflicts while merging",
- )));
- }
-
- rebase.finish(Some(&signature))?;
-
- Ok(())
+ scope_time!("merge_upstream_rebase");
+
+ let repo = utils::repo(repo_path)?;
+ if super::get_branch_name_repo(&repo)? != branch_name {
+ return Err(Error::Generic(String::from(
+ "can only rebase in head branch",
+ )));
+ }
+
+ let branch = repo.find_branch(branch_name, BranchType::Local)?;
+ let upstream = branch.upstream()?;
+ let upstream_commit = upstream.get().peel_to_commit()?;
+ let annotated_upstream =
+ repo.find_annotated_commit(upstream_commit.id())?;
+
+ let mut rebase =
+ repo.rebase(None, Some(&annotated_upstream), None, None)?;
+
+ let signature =
+ crate::sync::commit::signature_allow_undefined_name(&repo)?;
+
+ while let Some(op) = rebase.next() {
+ let _op = op?;
+ // dbg!(op.id());
+
+ if repo.index()?.has_conflicts() {
+ rebase.abort()?;
+ return Err(Error::Generic(String::from(
+ "conflicts while merging",
+ )));
+ }
+
+ rebase.commit(None, &signature, None)?;
+ }
+
+ if repo.index()?.has_conflicts() {
+ rebase.abort()?;
+ return Err(Error::Generic(String::from(
+ "conflicts while merging",
+ )));
+ }
+
+ rebase.finish(Some(&signature))?;
+
+ Ok(())
}
#[cfg(test)]
mod test {
- use super::*;
- use crate::sync::{
- branch_compare_upstream, get_commits_info,
- remotes::{fetch, push::push},
- tests::{
- debug_cmd_print, get_commit_ids, repo_clone,
- repo_init_bare, write_commit_file, write_commit_file_at,
- },
- RepoState,
- };
- use git2::{Repository, Time};
-
- fn get_commit_msgs(r: &Repository) -> Vec<String> {
- let commits = get_commit_ids(r, 10);
- get_commits_info(
- r.workdir().unwrap().to_str().unwrap(),
- &commits,
- 10,
- )
- .unwrap()
- .into_iter()
- .map(|c| c.message)
- .collect()
- }
-
- #[test]
- fn test_merge_normal() {
- let (r1_dir, _repo) = repo_init_bare().unwrap();
-
- let (clone1_dir, clone1) =
- repo_clone(r1_dir.path().to_str().unwrap()).unwrap();
-
- let clone1_dir = clone1_dir.path().to_str().unwrap();
-
- // clone1
-
- let _commit1 = write_commit_file_at(
- &clone1,
- "test.txt",
- "test",
- "commit1",
- git2::Time::new(0, 0),
- );
-
- assert_eq!(clone1.head_detached().unwrap(), false);
-
- push(
- clone1_dir, "origin", "master", false, false, None, None,
- )
- .unwrap();
-
- assert_eq!(clone1.head_detached().unwrap(), false);
-
- // clone2
-
- let (clone2_dir, clone2) =
- repo_clone(r1_dir.path().to_str().unwrap()).unwrap();
-
- let clone2_dir = clone2_dir.path().to_str().unwrap();
-
- let _commit2 = write_commit_file_at(
- &clone2,
- "test2.txt",
- "test",
- "commit2",
- git2::Time::new(1, 0),
- );
-
- assert_eq!(clone2.head_detached().unwrap(), false);
-
- push(
- clone2_dir, "origin", "master", false, false, None, None,
- )
- .unwrap();
-
- assert_eq!(clone2.head_detached().unwrap(), false);
-
- // clone1
-
- let _commit3 = write_commit_file_at(
- &clone1,
- "test3.txt",
- "test",
- "commit3",
- git2::Time::new(2, 0),
- );
-
- assert_eq!(clone1.head_detached().unwrap(), false);
-
- //lets fetch from origin
- let bytes = fetch(clone1_dir, "master", None, None).unwrap();
- assert!(bytes > 0);
-
- //we should be one commit behind
- assert_eq!(
- branch_compare_upstream(clone1_dir, "master")
- .unwrap()
- .behind,
- 1
- );
-
- // debug_cmd_print(clone1_dir, "git status");
-
- assert_eq!(clone1.head_detached().unwrap(), false);
-
- merge_upstream_rebase(clone1_dir, "master").unwrap();
-
- debug_cmd_print(clone1_dir, "git log");
-
- let state = crate::sync::repo_state(clone1_dir).unwrap();
- assert_eq!(state, RepoState::Clean);
-
- let commits = get_commit_msgs(&clone1);
- assert_eq!(
- commits,
- vec![
- String::from("commit3"),
- String::from("commit2"),
- String::from("commit1")
- ]
- );
+ use super::*;
+ use crate::sync::{
+ branch_compare_upstream, get_commits_info,
+ remotes::{fetch, push::push},
+ tests::{
+ debug_cmd_print, get_commit_ids, repo_clone,
+ repo_init_bare, write_commit_file, write_commit_file_at,
+ },
+ RepoState,
+ };
+ use git2::{Repository, Time};
+
+ fn get_commit_msgs(r: &Repository) -> Vec<String> {
+ let commits = get_commit_ids(r, 10);
+ get_commits_info(
+ r.workdir().unwrap().to_str().unwrap(),
+ &commits,
+ 10,
+ )
+ .unwrap()
+ .into_iter()
+ .map(|c| c.message)
+ .collect()
+ }
+
+ #[test]
+ fn test_merge_normal() {
+ let (r1_dir, _repo) = repo_init_bare().unwrap();
+
+ let (clone1_dir, clone1) =
+ repo_clone(r1_dir.path().to_str().unwrap()).unwrap();
+
+ let clone1_dir = clone1_dir.path().to_str().unwrap();
+
+ // clone1
+
+ let _commit1 = write_commit_file_at(
+ &clone1,
+ "test.txt",
+ "test",
+ "commit1",
+ git2::Time::new(0, 0),
+ );
+
+ assert_eq!(clone1.head_detached().unwrap(), false);
+
+ push(
+ clone1_dir, "origin", "master", false, false, None, None,
+ )
+ .unwrap();
+
+ assert_eq!(clone1.head_detached().unwrap(), false);
+
+ // clone2
+
+ let (clone2_dir, clone2) =
+ repo_clone(r1_dir.path().to_str().unwrap()).unwrap();
+
+ let clone2_dir = clone2_dir.path().to_str().unwrap();
+
+ let _commit2 = write_commit_file_at(
+ &clone2,
+ "test2.txt",
+ "test",
+ "commit2",
+ git2::Time::new(1, 0),
+ );
+
+ assert_eq!(clone2.head_detached().unwrap(), false);
+
+ push(
+ clone2_dir, "origin", "master", false, false, None, None,
+ )
+ .unwrap();
+
+ assert_eq!(clone2.head_detached().unwrap(), false);
+
+ // clone1
+
+ let _commit3 = write_commit_file_at(
+ &clone1,
+ "test3.txt",
+ "test",
+ "commit3",
+ git2::Time::new(2, 0),
+ );
+
+ assert_eq!(clone1.head_detached().unwrap(), false);
+
+ //lets fetch from origin
+ let bytes = fetch(clone1_dir, "master", None, None).unwrap();
+ assert!(bytes > 0);
+
+ //we should be one commit behind
+ assert_eq!(
+ branch_compare_upstream(clone1_dir, "master")
+ .unwrap()
+ .behind,
+ 1
+ );
+
+ // debug_cmd_print(clone1_dir, "git status");
+
+ assert_eq!(clone1.head_detached().unwrap(), false);
+
+ merge_upstream_rebase(clone1_dir, "master").unwrap();
+
+ debug_cmd_print(clone1_dir, "git log");
+
+ let state = crate::sync::repo_state(clone1_dir).unwrap();
+ assert_eq!(state, RepoState::Clean);
+
+ let commits = get_commit_msgs(&clone1);
+ assert_eq!(
+ commits,
+ vec![
+ String::from("commit3"),
+ String::from("commit2"),
+ String::from("commit1")
+ ]
+ );
- assert_eq!(clone1.head_detached().unwrap(), false);
- }
+ assert_eq!(clone1.head_detached().unwrap(), false);
+ }
- #[test]
- fn test_merge_multiple() {
- let (r1_dir, _repo) = repo_init_bare().unwrap();
+ #[test]
+ fn test_merge_multiple() {
+ let (r1_dir, _repo) = repo_init_bare().unwrap();
- let (clone1_dir, clone1) =
- repo_clone(r1_dir.path().to_str().unwrap()).unwrap();
+ let (clone1_dir, clone1) =
+ repo_clone(r1_dir.path().to_str().unwrap()).unwrap();
- let clone1_dir = clone1_dir.path().to_str().unwrap();
+ let clone1_dir = clone1_dir.path().to_str().unwrap();
- // clone1
+ // clone1
- write_commit_file_at(
- &clone1,
- "test.txt",
- "test",
- "commit1",
- Time::new(0, 0),
- );
+ write_commit_file_at(
+ &clone1,
+ "test.txt",
+ "test",
+ "commit1",
+ Time::new(0, 0),
+ );
- push(
- clone1_dir, "origin", "master", false, false, None, None,
- )
- .unwrap();
+ push(
+ clone1_dir, "origin", "master", false, false, None, None,
+ )
+ .unwrap();
- // clone2
+ // clone2
- let (clone2_dir, clone2) =
- repo_clone(r1_dir.path().to_str().unwrap()).unwrap();
+ let (clone2_dir, clone2) =
+ repo_clone(r1_dir.path().to_str().unwrap()).unwrap();
- let clone2_dir = clone2_dir.path().to_str().unwrap();
+ let clone2_dir = clone2_dir.path().to_str().unwrap();
- write_commit_file_at(
- &clone2,
- "test2.txt",
- "test",
- "commit2",
- Time::new(1, 0),
- );
+ write_commit_file_at(
+ &clone2,
+ "test2.txt",
+ "test",
+ "commit2",
+ Time::new(1, 0),
+ );
- push(
- clone2_dir, "origin", "master", false, false, None, None,
- )
- .unwrap();
+ push(
+ clone2_dir, "origin", "master", false, false, None, None,
+ )
+ .unwrap();
- // clone1
+ // clone1
- write_commit_file_at(
- &clone1,
- "test3.txt",
- "test",
- "commit3",
- Time::new(2, 0),
- );
- write_commit_file_at(
- &clone1,
- "test4.txt",
- "test",
- "commit4",
- Time::new(3, 0),
- );
+ write_commit_file_at(
+ &clone1,
+ "test3.txt",
+ "test",
+ "commit3",
+ Time::new(2, 0),
+ );
+ write_commit_file_at(
+ &clone1,
+ "test4.txt",
+ "test",
+ "commit4",
+ Time::new(3, 0),
+ );
- //lets fetch from origin
+ //lets fetch from origin
- fetch(clone1_dir, "master", None, None).unwrap();
+ fetch(clone1_dir, "master", None, None).unwrap();
- merge_upstream_rebase(clone1_dir, "master").unwrap();
+ merge_upstream_rebase(clone1_dir, "master").unwrap();
- debug_cmd_print(clone1_dir, "git log");
+ debug_cmd_print(clone1_dir, "git log");
- let state = crate::sync::repo_state(clone1_dir).unwrap();
- assert_eq!(state, RepoState::Clean);
+ let state = crate::sync::repo_state(clone1_dir).unwrap();
+ assert_eq!(state, RepoState::Clean);
- let commits = get_commit_msgs(&clone1);
- assert_eq!(
- commits,
- vec![
- String::from("commit4"),
- String::from("commit3"),
- String::from("commit2"),
- String::from("commit1")
- ]
- );
+ let commits = get_commit_msgs(&clone1);
+ assert_eq!(
+ commits,
+ vec![
+ String::from("commit4"),
+ String::from("commit3"),
+ String::from("commit2"),
+ String::from("commit1")
+ ]
+ );
- assert_eq!(clone1.head_detached().unwrap(), false);
- }
+ assert_eq!(clone1.head_detached().unwrap(), false);
+ }
- #[test]
- fn test_merge_conflict() {
- let (r1_dir, _repo) = repo_init_bare().unwrap();
+ #[test]
+ fn test_merge_conflict() {
+ let (r1_dir, _repo) = repo_init_bare().unwrap();
- let (clone1_dir, clone1) =
- repo_clone(r1_dir.path().to_str().unwrap()).unwrap();
+ let (clone1_dir, clone1) =
+ repo_clone(r1_dir.path().to_str().unwrap()).unwrap();
- let clone1_dir = clone1_dir.path().to_str().unwrap();
+ let clone1_dir = clone1_dir.path().to_str().unwrap();
- // clone1
+ // clone1
- let _commit1 =
- write_commit_file(&clone1, "test.txt", "test", "commit1");
+ let _commit1 =
+ write_commit_file(&clone1, "test.txt", "test", "commit1");
- push(
- clone1_dir, "origin", "master", false, false, None, None,
- )
- .unwrap();
+ push(
+ clone1_dir, "origin", "master", false, false, None, None,
+ )
+ .unwrap();
- // clone2
+ // clone2
- let (clone2_dir, clone2) =
- repo_clone(r1_dir.path().to_str().unwrap()).unwrap();
+ let (clone2_dir, clone2) =
+ repo_clone(r1_dir.path().to_str().unwrap()).unwrap();
- let clone2_dir = clone2_dir.path().to_str().unwrap();
-
- let _commit2 = write_commit_file(
- &clone2,
- "test2.txt",
- "test",
- "commit2",
- );
+ let clone2_dir = clone2_dir.path().to_str().unwrap();
+
+ let _commit2 = write_commit_file(
+ &clone2,
+ "test2.txt",
+ "test",
+ "commit2",
+ );
- push(
- clone2_dir, "origin", "master", false, false, None, None,
- )
- .unwrap();
+ push(
+ clone2_dir, "origin", "master", false, false, None, None,
+ )
+ .unwrap();
- // clone1
+ // clone1
- let _commit3 =
- write_commit_file(&clone1, "test2.txt", "foo", "commit3");
+ let _commit3 =
+ write_commit_file(&clone1, "test2.txt", "foo", "commit3");
- let bytes = fetch(clone1_dir, "master", None, None).unwrap();
- assert!(bytes > 0);
-
- assert_eq!(
- branch_compare_upstream(clone1_dir, "master")
- .unwrap()
- .behind,
- 1
- );
+ let bytes = fetch(clone1_dir, "master", None, None).unwrap();
+ assert!(bytes > 0);
+
+ assert_eq!(
+ branch_compare_upstream(clone1_dir, "master")
+ .unwrap()
+ .behind,
+ 1
+ );
- let res = merge_upstream_rebase(clone1_dir, "master");
- assert!(res.is_err());
+ let res = merge_upstream_rebase(clone1_dir, "master");
+ assert!(res.is_err());
- let state = crate::sync::repo_state(clone1_dir).unwrap();
+ let state = crate::sync::repo_state(clone1_dir).unwrap();
- assert_eq!(state, RepoState::Clean);
+ assert_eq!(state, RepoState::Clean);
- let commits = get_commit_msgs(&clone1);
- assert_eq!(
- commits,
- vec![String::from("commit3"), String::from("commit1")]
- );
- }
+ let commits = get_commit_msgs(&clone1);
+ assert_eq!(
+ commits,
+ vec![String::from("commit3"), String::from("commit1")]
+ );
+ }
}