fix detached head after rebase merge

This commit is contained in:
Stephan Dilly 2021-03-12 12:04:37 +01:00
parent 15a6565908
commit 6430484a97
4 changed files with 51 additions and 26 deletions

View File

@ -28,7 +28,7 @@
- Fast and intuitive **keyboard only** control - Fast and intuitive **keyboard only** control
- Context based help (**no need to memorize** tons of hot-keys) - Context based help (**no need to memorize** tons of hot-keys)
- Inspect, commit, and amend changes (incl. hooks: _commit-msg_/_post-commit_) - 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) - Stashing (save, apply, drop, and inspect)
- Push/Fetch to/from remote - Push/Fetch to/from remote
- Branch List (create, rename, delete) - Branch List (create, rename, delete)

View File

@ -162,9 +162,10 @@ mod test {
merge_upstream_commit(clone2_dir, "master").unwrap(); merge_upstream_commit(clone2_dir, "master").unwrap();
let state = crate::sync::repo_state(clone2_dir).unwrap(); let state = crate::sync::repo_state(clone2_dir).unwrap();
assert_eq!(state, RepoState::Clean); assert_eq!(state, RepoState::Clean);
assert!(!clone2.head_detached().unwrap());
let commits = get_commit_ids(&clone2, 10); let commits = get_commit_ids(&clone2, 10);
assert_eq!(commits.len(), 3); assert_eq!(commits.len(), 3);
assert_eq!(commits[0], merge_commit); assert_eq!(commits[0], merge_commit);

View File

@ -15,6 +15,12 @@ pub fn merge_upstream_rebase(
scope_time!("merge_upstream_rebase"); scope_time!("merge_upstream_rebase");
let repo = utils::repo(repo_path)?; 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 branch = repo.find_branch(branch_name, BranchType::Local)?;
let upstream = branch.upstream()?; let upstream = branch.upstream()?;
let upstream_commit = upstream.get().peel_to_commit()?; let upstream_commit = upstream.get().peel_to_commit()?;
@ -24,37 +30,35 @@ pub fn merge_upstream_rebase(
let branch_commit = branch.get().peel_to_commit()?; let branch_commit = branch.get().peel_to_commit()?;
let annotated_branch = let annotated_branch =
repo.find_annotated_commit(branch_commit.id())?; repo.find_annotated_commit(branch_commit.id())?;
dbg!(annotated_branch.id());
let rebase = repo.rebase( let mut rebase =
Some(&annotated_branch), repo.rebase(None, Some(&annotated_upstream), None, None)?;
Some(&annotated_upstream),
None,
None,
)?;
let signature = let signature =
crate::sync::commit::signature_allow_undefined_name(&repo)?; crate::sync::commit::signature_allow_undefined_name(&repo)?;
for e in rebase { while let Some(op) = rebase.next() {
let _op = e?; let op = op?;
// dbg!(op.id()); dbg!(op.id());
// dbg!(op.kind());
}
let mut rebase = repo.open_rebase(None)?;
if repo.index()?.has_conflicts() { if repo.index()?.has_conflicts() {
rebase.abort()?; rebase.abort()?;
return Err(Error::Generic(String::from(
"conflicts while merging",
)));
}
Err(Error::Generic(String::from("conflicts while merging"))) let commit = rebase.commit(None, &signature, None)?;
} else { dbg!(commit);
rebase.commit(None, &signature, None)?; }
rebase.finish(Some(&signature))?; rebase.finish(Some(&signature))?;
repo.index()?.read(true)?;
Ok(()) Ok(())
} }
}
#[cfg(test)] #[cfg(test)]
mod test { mod test {
@ -97,9 +101,13 @@ mod test {
let _commit1 = let _commit1 =
write_commit_file(&clone1, "test.txt", "test", "commit1"); write_commit_file(&clone1, "test.txt", "test", "commit1");
assert_eq!(clone1.head_detached().unwrap(), false);
push(clone1_dir, "origin", "master", false, None, None) push(clone1_dir, "origin", "master", false, None, None)
.unwrap(); .unwrap();
assert_eq!(clone1.head_detached().unwrap(), false);
// clone2 // clone2
let (clone2_dir, clone2) = let (clone2_dir, clone2) =
@ -114,9 +122,13 @@ mod test {
"commit2", "commit2",
); );
assert_eq!(clone2.head_detached().unwrap(), false);
push(clone2_dir, "origin", "master", false, None, None) push(clone2_dir, "origin", "master", false, None, None)
.unwrap(); .unwrap();
assert_eq!(clone2.head_detached().unwrap(), false);
// clone1 // clone1
let _commit3 = write_commit_file( let _commit3 = write_commit_file(
@ -126,6 +138,8 @@ mod test {
"commit3", "commit3",
); );
assert_eq!(clone1.head_detached().unwrap(), false);
//lets fetch from origin //lets fetch from origin
let bytes = let bytes =
fetch_origin(clone1_dir, "master", None, None).unwrap(); fetch_origin(clone1_dir, "master", None, None).unwrap();
@ -141,12 +155,13 @@ mod test {
// debug_cmd_print(clone1_dir, "git log"); // debug_cmd_print(clone1_dir, "git log");
assert_eq!(clone1.head_detached().unwrap(), false);
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(); 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); let commits = get_commit_msgs(&clone1);
@ -158,6 +173,8 @@ mod test {
String::from("commit1") String::from("commit1")
] ]
); );
assert_eq!(clone1.head_detached().unwrap(), false);
} }
#[test] #[test]

View File

@ -19,10 +19,17 @@ use utils::get_head_repo;
/// returns the branch-name head is currently pointing to /// returns the branch-name head is currently pointing to
/// this might be expensive, see `cached::BranchName` /// this might be expensive, see `cached::BranchName`
pub(crate) fn get_branch_name(repo_path: &str) -> Result<String> { pub(crate) fn get_branch_name(repo_path: &str) -> Result<String> {
scope_time!("get_branch_name");
let repo = utils::repo(repo_path)?; let repo = utils::repo(repo_path)?;
Ok(get_branch_name_repo(&repo)?)
}
/// ditto
pub(crate) fn get_branch_name_repo(
repo: &Repository,
) -> Result<String> {
scope_time!("get_branch_name_repo");
let iter = repo.branches(None)?; let iter = repo.branches(None)?;
for b in iter { for b in iter {