add failing test

This commit is contained in:
Nikita Galaiko 2024-01-17 14:03:24 +01:00 committed by GitButler
parent 4dec1fef4d
commit cc7102b18c
2 changed files with 184 additions and 0 deletions

View File

@ -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 {

View File

@ -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 {