diff --git a/README.md b/README.md index 74c17b7d..4d58b38d 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ - Fast and intuitive **keyboard only** control - Context based help (**no need to memorize** tons of hot-keys) - Inspect, commit, and amend changes (incl. hooks: _commit-msg_/_post-commit_) -- Stage, unstage, revert and reset files and hunks +- Stage, unstage, revert and reset files, hunks and lines - Stashing (save, apply, drop, and inspect) - Push/Fetch to/from remote - Branch List (create, rename, delete) diff --git a/asyncgit/src/sync/branch/merge_commit.rs b/asyncgit/src/sync/branch/merge_commit.rs index d8b1b9df..139ea7b7 100644 --- a/asyncgit/src/sync/branch/merge_commit.rs +++ b/asyncgit/src/sync/branch/merge_commit.rs @@ -162,9 +162,10 @@ mod test { merge_upstream_commit(clone2_dir, "master").unwrap(); let state = crate::sync::repo_state(clone2_dir).unwrap(); - assert_eq!(state, RepoState::Clean); + assert!(!clone2.head_detached().unwrap()); + let commits = get_commit_ids(&clone2, 10); assert_eq!(commits.len(), 3); assert_eq!(commits[0], merge_commit); diff --git a/asyncgit/src/sync/branch/merge_rebase.rs b/asyncgit/src/sync/branch/merge_rebase.rs index 0b1c56f7..9200f3bc 100644 --- a/asyncgit/src/sync/branch/merge_rebase.rs +++ b/asyncgit/src/sync/branch/merge_rebase.rs @@ -15,6 +15,12 @@ pub fn merge_upstream_rebase( 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()?; @@ -24,36 +30,34 @@ pub fn merge_upstream_rebase( let branch_commit = branch.get().peel_to_commit()?; let annotated_branch = repo.find_annotated_commit(branch_commit.id())?; + dbg!(annotated_branch.id()); - let rebase = repo.rebase( - Some(&annotated_branch), - Some(&annotated_upstream), - None, - None, - )?; + let mut rebase = + repo.rebase(None, Some(&annotated_upstream), None, None)?; let signature = crate::sync::commit::signature_allow_undefined_name(&repo)?; - for e in rebase { - let _op = e?; - // dbg!(op.id()); - // dbg!(op.kind()); + 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", + ))); + } + + let commit = rebase.commit(None, &signature, None)?; + dbg!(commit); } - let mut rebase = repo.open_rebase(None)?; + rebase.finish(Some(&signature))?; - if repo.index()?.has_conflicts() { - rebase.abort()?; + repo.index()?.read(true)?; - Err(Error::Generic(String::from("conflicts while merging"))) - } else { - rebase.commit(None, &signature, None)?; - - rebase.finish(Some(&signature))?; - - Ok(()) - } + Ok(()) } #[cfg(test)] @@ -97,9 +101,13 @@ mod test { let _commit1 = write_commit_file(&clone1, "test.txt", "test", "commit1"); + assert_eq!(clone1.head_detached().unwrap(), false); + push(clone1_dir, "origin", "master", false, None, None) .unwrap(); + assert_eq!(clone1.head_detached().unwrap(), false); + // clone2 let (clone2_dir, clone2) = @@ -114,9 +122,13 @@ mod test { "commit2", ); + assert_eq!(clone2.head_detached().unwrap(), false); + push(clone2_dir, "origin", "master", false, None, None) .unwrap(); + assert_eq!(clone2.head_detached().unwrap(), false); + // clone1 let _commit3 = write_commit_file( @@ -126,6 +138,8 @@ mod test { "commit3", ); + assert_eq!(clone1.head_detached().unwrap(), false); + //lets fetch from origin let bytes = fetch_origin(clone1_dir, "master", None, None).unwrap(); @@ -141,12 +155,13 @@ mod test { // debug_cmd_print(clone1_dir, "git log"); + 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); @@ -158,6 +173,8 @@ mod test { String::from("commit1") ] ); + + assert_eq!(clone1.head_detached().unwrap(), false); } #[test] diff --git a/asyncgit/src/sync/branch/mod.rs b/asyncgit/src/sync/branch/mod.rs index 73b8f411..19664d16 100644 --- a/asyncgit/src/sync/branch/mod.rs +++ b/asyncgit/src/sync/branch/mod.rs @@ -19,10 +19,17 @@ use utils::get_head_repo; /// returns the branch-name head is currently pointing to /// this might be expensive, see `cached::BranchName` pub(crate) fn get_branch_name(repo_path: &str) -> Result { - scope_time!("get_branch_name"); - let repo = utils::repo(repo_path)?; + Ok(get_branch_name_repo(&repo)?) +} + +/// ditto +pub(crate) fn get_branch_name_repo( + repo: &Repository, +) -> Result { + scope_time!("get_branch_name_repo"); + let iter = repo.branches(None)?; for b in iter {