mirror of
https://github.com/gitbutlerapp/gitbutler.git
synced 2024-11-28 13:26:16 +03:00
add failing test
This commit is contained in:
parent
4dec1fef4d
commit
cc7102b18c
@ -114,6 +114,69 @@ impl TestProject {
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
pub fn rebase_and_merge(&self, branch_name: &git::Refname) {
|
||||
let branch_name: git::Refname = match branch_name {
|
||||
git::Refname::Local(local) => format!("refs/heads/{}", local.branch()).parse().unwrap(),
|
||||
git::Refname::Remote(remote) => {
|
||||
format!("refs/heads/{}", remote.branch()).parse().unwrap()
|
||||
}
|
||||
_ => "INVALID".parse().unwrap(), // todo
|
||||
};
|
||||
let branch = self.remote_repository.find_branch(&branch_name).unwrap();
|
||||
let branch_commit = branch.peel_to_commit().unwrap();
|
||||
|
||||
let master_branch = {
|
||||
let name: git::Refname = "refs/heads/master".parse().unwrap();
|
||||
self.remote_repository.find_branch(&name).unwrap()
|
||||
};
|
||||
let master_branch_commit = master_branch.peel_to_commit().unwrap();
|
||||
|
||||
let mut rebase_options = git2::RebaseOptions::new();
|
||||
rebase_options.quiet(true);
|
||||
rebase_options.inmemory(true);
|
||||
|
||||
let mut rebase = self
|
||||
.remote_repository
|
||||
.rebase(
|
||||
Some(branch_commit.id()),
|
||||
Some(master_branch_commit.id()),
|
||||
None,
|
||||
Some(&mut rebase_options),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let mut rebase_success = true;
|
||||
let mut last_rebase_head = branch_commit.id();
|
||||
while let Some(Ok(op)) = rebase.next() {
|
||||
let commit = self.remote_repository.find_commit(op.id().into()).unwrap();
|
||||
let index = rebase.inmemory_index().unwrap();
|
||||
if index.has_conflicts() {
|
||||
rebase_success = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if let Ok(commit_id) = rebase.commit(None, &commit.committer().into(), None) {
|
||||
last_rebase_head = commit_id.into();
|
||||
} else {
|
||||
rebase_success = false;
|
||||
break;
|
||||
};
|
||||
}
|
||||
|
||||
if rebase_success {
|
||||
self.remote_repository
|
||||
.reference(
|
||||
&"refs/heads/master".parse().unwrap(),
|
||||
last_rebase_head,
|
||||
true,
|
||||
&format!("rebase: {}", branch_name),
|
||||
)
|
||||
.unwrap();
|
||||
} else {
|
||||
rebase.abort().unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
/// works like if we'd open and merge a PR on github. does not update local.
|
||||
pub fn merge(&self, branch_name: &git::Refname) {
|
||||
let branch_name: git::Refname = match branch_name {
|
||||
|
@ -5301,6 +5301,127 @@ mod update_commit_message {
|
||||
mod create_virtual_branch_from_branch {
|
||||
use super::*;
|
||||
|
||||
#[tokio::test]
|
||||
async fn integration() {
|
||||
let Test {
|
||||
repository,
|
||||
project_id,
|
||||
controller,
|
||||
..
|
||||
} = Test::default();
|
||||
|
||||
controller
|
||||
.set_base_branch(&project_id, &"refs/remotes/origin/master".parse().unwrap())
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let branch_name = {
|
||||
// make a remote branch
|
||||
|
||||
let branch_id = controller
|
||||
.create_virtual_branch(&project_id, &super::branch::BranchCreateRequest::default())
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
std::fs::write(repository.path().join("file.txt"), "first\n").unwrap();
|
||||
controller
|
||||
.create_commit(&project_id, &branch_id, "first", None, false)
|
||||
.await
|
||||
.unwrap();
|
||||
controller
|
||||
.push_virtual_branch(&project_id, &branch_id, false)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let branch = controller
|
||||
.list_virtual_branches(&project_id)
|
||||
.await
|
||||
.unwrap()
|
||||
.into_iter()
|
||||
.find(|branch| branch.id == branch_id)
|
||||
.unwrap();
|
||||
|
||||
let name = branch.upstream.unwrap().name;
|
||||
|
||||
controller
|
||||
.delete_virtual_branch(&project_id, &branch_id)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
name
|
||||
};
|
||||
|
||||
// checkout a existing remote branch
|
||||
let branch_id = controller
|
||||
.create_virtual_branch_from_branch(&project_id, &branch_name)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
{
|
||||
// add a commit
|
||||
std::fs::write(repository.path().join("file.txt"), "first\nsecond").unwrap();
|
||||
|
||||
controller
|
||||
.create_commit(&project_id, &branch_id, "second", None, false)
|
||||
.await
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
{
|
||||
// meanwhile, there is a new commit on master
|
||||
repository.checkout(&"refs/heads/master".parse().unwrap());
|
||||
std::fs::write(repository.path().join("another.txt"), "").unwrap();
|
||||
repository.commit_all("another");
|
||||
repository.push_branch(&"refs/heads/master".parse().unwrap());
|
||||
repository.checkout(&"refs/heads/gitbutler/integration".parse().unwrap());
|
||||
}
|
||||
|
||||
{
|
||||
// merge branch into master
|
||||
controller
|
||||
.push_virtual_branch(&project_id, &branch_id, false)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let branch = controller
|
||||
.list_virtual_branches(&project_id)
|
||||
.await
|
||||
.unwrap()
|
||||
.into_iter()
|
||||
.find(|branch| branch.id == branch_id)
|
||||
.unwrap();
|
||||
|
||||
assert!(branch.commits[0].is_remote);
|
||||
assert!(!branch.commits[0].is_integrated);
|
||||
assert!(branch.commits[1].is_remote);
|
||||
assert!(!branch.commits[1].is_integrated);
|
||||
|
||||
repository.rebase_and_merge(&branch_name);
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
// should mark commits as integrated
|
||||
controller.fetch_from_target(&project_id).await.unwrap();
|
||||
|
||||
let base = controller.get_base_branch_data(&project_id).await.unwrap();
|
||||
|
||||
let branch = controller
|
||||
.list_virtual_branches(&project_id)
|
||||
.await
|
||||
.unwrap()
|
||||
.into_iter()
|
||||
.find(|branch| branch.id == branch_id)
|
||||
.unwrap();
|
||||
|
||||
|
||||
assert!(branch.commits[0].is_remote);
|
||||
assert!(branch.commits[0].is_integrated);
|
||||
assert!(branch.commits[1].is_remote);
|
||||
assert!(branch.commits[1].is_integrated);
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn no_conflicts() {
|
||||
let Test {
|
||||
|
Loading…
Reference in New Issue
Block a user