mirror of
https://github.com/gitbutlerapp/gitbutler.git
synced 2024-11-27 09:47:34 +03:00
use the new testsupport
crate
This commit is contained in:
parent
3a148a556f
commit
906bfa3cf4
2
Cargo.lock
generated
2
Cargo.lock
generated
@ -2038,6 +2038,7 @@ dependencies = [
|
||||
"git2",
|
||||
"git2-hooks",
|
||||
"gitbutler-git",
|
||||
"gitbutler-testsupport",
|
||||
"itertools 0.12.1",
|
||||
"lazy_static",
|
||||
"log",
|
||||
@ -2099,6 +2100,7 @@ dependencies = [
|
||||
"futures",
|
||||
"git2",
|
||||
"gitbutler-core",
|
||||
"gitbutler-testsupport",
|
||||
"governor",
|
||||
"itertools 0.12.1",
|
||||
"log",
|
||||
|
@ -8,6 +8,7 @@ publish = false
|
||||
[dev-dependencies]
|
||||
once_cell = "1.19"
|
||||
pretty_assertions = "1.4"
|
||||
gitbutler-testsupport = { path = "../gitbutler-testsupport" }
|
||||
|
||||
[dependencies]
|
||||
toml = "0.8.12"
|
||||
|
@ -1,5 +1,3 @@
|
||||
pub mod shared;
|
||||
|
||||
mod suite {
|
||||
mod gb_repository;
|
||||
mod projects;
|
||||
|
@ -1,6 +1,6 @@
|
||||
use gitbutler_core::database::Database;
|
||||
|
||||
use crate::shared::temp_dir;
|
||||
use gitbutler_testsupport::temp_dir;
|
||||
|
||||
#[test]
|
||||
fn smoke() {
|
||||
|
@ -7,7 +7,7 @@ mod database {
|
||||
sessions::SessionId,
|
||||
};
|
||||
|
||||
use crate::shared::test_database;
|
||||
use gitbutler_testsupport::test_database;
|
||||
|
||||
#[test]
|
||||
fn insert_query() -> anyhow::Result<()> {
|
||||
@ -115,7 +115,7 @@ mod writer {
|
||||
|
||||
use gitbutler_core::{deltas, deltas::operations::Operation, sessions};
|
||||
|
||||
use crate::shared::{Case, Suite};
|
||||
use gitbutler_testsupport::{Case, Suite};
|
||||
|
||||
#[test]
|
||||
fn write_no_vbranches() -> anyhow::Result<()> {
|
||||
|
@ -10,7 +10,7 @@ use gitbutler_core::{
|
||||
use pretty_assertions::assert_eq;
|
||||
use tempfile::TempDir;
|
||||
|
||||
use crate::shared::{init_opts_bare, Case, Suite};
|
||||
use gitbutler_testsupport::{init_opts_bare, Case, Suite};
|
||||
|
||||
mod repository {
|
||||
use std::path::PathBuf;
|
||||
@ -18,7 +18,7 @@ mod repository {
|
||||
use anyhow::Result;
|
||||
use pretty_assertions::assert_eq;
|
||||
|
||||
use crate::shared::{Case, Suite};
|
||||
use gitbutler_testsupport::{Case, Suite};
|
||||
|
||||
#[test]
|
||||
fn alternates_file_being_set() -> Result<()> {
|
||||
|
@ -1,4 +1,4 @@
|
||||
use crate::shared::test_repository;
|
||||
use gitbutler_testsupport::test_repository;
|
||||
|
||||
#[test]
|
||||
pub fn set_str() {
|
||||
|
@ -5,7 +5,7 @@ use gitbutler_core::{
|
||||
keys, project_repository, projects, users,
|
||||
};
|
||||
|
||||
use crate::shared::{temp_dir, test_repository};
|
||||
use gitbutler_testsupport::{temp_dir, test_repository};
|
||||
|
||||
#[derive(Default)]
|
||||
struct TestCase<'a> {
|
||||
|
@ -10,7 +10,7 @@ use gitbutler_core::{
|
||||
use pretty_assertions::assert_eq;
|
||||
use tempfile::TempDir;
|
||||
|
||||
use crate::shared::{init_opts_bare, Case, Suite};
|
||||
use gitbutler_testsupport::{init_opts_bare, Case, Suite};
|
||||
|
||||
fn new_test_remote_repository() -> Result<(git2::Repository, TempDir)> {
|
||||
let tmp = tempfile::tempdir()?;
|
||||
|
@ -9,7 +9,7 @@ mod controller {
|
||||
|
||||
use gitbutler_core::keys::{storage::Storage, Controller};
|
||||
|
||||
use crate::shared::Suite;
|
||||
use gitbutler_testsupport::Suite;
|
||||
|
||||
#[test]
|
||||
fn get_or_create() {
|
||||
|
@ -1,6 +1,6 @@
|
||||
use gitbutler_core::lock::Dir;
|
||||
|
||||
use crate::shared::temp_dir;
|
||||
use gitbutler_testsupport::temp_dir;
|
||||
|
||||
#[tokio::test]
|
||||
async fn lock_same_instance() {
|
||||
|
@ -3,7 +3,7 @@ use std::{fs, path::Path};
|
||||
use anyhow::Result;
|
||||
use gitbutler_core::reader::{CommitReader, Content, Reader};
|
||||
|
||||
use crate::shared::{commit_all, temp_dir, test_repository};
|
||||
use gitbutler_testsupport::{commit_all, temp_dir, test_repository};
|
||||
|
||||
#[test]
|
||||
fn directory_reader_read_file() -> Result<()> {
|
||||
|
@ -3,7 +3,7 @@ use gitbutler_core::{
|
||||
sessions::{session, Database, Session, SessionId},
|
||||
};
|
||||
|
||||
use crate::shared::test_database;
|
||||
use gitbutler_testsupport::test_database;
|
||||
|
||||
#[test]
|
||||
fn insert_query() -> anyhow::Result<()> {
|
||||
|
@ -3,7 +3,7 @@ mod database;
|
||||
use anyhow::Result;
|
||||
use gitbutler_core::sessions::{self, session::SessionId};
|
||||
|
||||
use crate::shared::{Case, Suite};
|
||||
use gitbutler_testsupport::{Case, Suite};
|
||||
|
||||
#[test]
|
||||
fn should_not_write_session_with_hash() {
|
||||
|
@ -1,69 +0,0 @@
|
||||
pub const VAR_NO_CLEANUP: &str = "GITBUTLER_TESTS_NO_CLEANUP";
|
||||
|
||||
mod test_project;
|
||||
pub use test_project::TestProject;
|
||||
|
||||
mod suite;
|
||||
pub use suite::*;
|
||||
|
||||
pub mod paths {
|
||||
use tempfile::TempDir;
|
||||
|
||||
use super::temp_dir;
|
||||
|
||||
pub fn data_dir() -> TempDir {
|
||||
temp_dir()
|
||||
}
|
||||
}
|
||||
|
||||
pub mod virtual_branches {
|
||||
use gitbutler_core::{
|
||||
gb_repository, project_repository,
|
||||
virtual_branches::{self, VirtualBranchesHandle},
|
||||
};
|
||||
|
||||
use crate::shared::empty_bare_repository;
|
||||
|
||||
pub fn set_test_target(
|
||||
gb_repo: &gb_repository::Repository,
|
||||
project_repository: &project_repository::Repository,
|
||||
) -> anyhow::Result<()> {
|
||||
let (remote_repo, _tmp) = empty_bare_repository();
|
||||
let mut remote = project_repository
|
||||
.git_repository
|
||||
.remote(
|
||||
"origin",
|
||||
&remote_repo.path().to_str().unwrap().parse().unwrap(),
|
||||
)
|
||||
.expect("failed to add remote");
|
||||
remote.push(&["refs/heads/master:refs/heads/master"], None)?;
|
||||
|
||||
virtual_branches::target::Writer::new(
|
||||
gb_repo,
|
||||
VirtualBranchesHandle::new(&project_repository.project().gb_dir()),
|
||||
)?
|
||||
.write_default(&virtual_branches::target::Target {
|
||||
branch: "refs/remotes/origin/master".parse().unwrap(),
|
||||
remote_url: remote_repo.path().to_str().unwrap().parse().unwrap(),
|
||||
sha: remote_repo.head().unwrap().target().unwrap(),
|
||||
})
|
||||
.expect("failed to write target");
|
||||
|
||||
virtual_branches::integration::update_gitbutler_integration(gb_repo, project_repository)
|
||||
.expect("failed to update integration");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn init_opts() -> git2::RepositoryInitOptions {
|
||||
let mut opts = git2::RepositoryInitOptions::new();
|
||||
opts.initial_head("master");
|
||||
opts
|
||||
}
|
||||
|
||||
pub fn init_opts_bare() -> git2::RepositoryInitOptions {
|
||||
let mut opts = init_opts();
|
||||
opts.bare(true);
|
||||
opts
|
||||
}
|
@ -1,232 +0,0 @@
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
fs,
|
||||
path::{Path, PathBuf},
|
||||
};
|
||||
|
||||
use tempfile::{tempdir, TempDir};
|
||||
|
||||
use crate::shared::{init_opts, init_opts_bare, VAR_NO_CLEANUP};
|
||||
|
||||
pub struct Suite {
|
||||
pub local_app_data: Option<TempDir>,
|
||||
pub storage: gitbutler_core::storage::Storage,
|
||||
pub users: gitbutler_core::users::Controller,
|
||||
pub projects: gitbutler_core::projects::Controller,
|
||||
pub keys: gitbutler_core::keys::Controller,
|
||||
}
|
||||
|
||||
impl Drop for Suite {
|
||||
fn drop(&mut self) {
|
||||
if std::env::var_os(VAR_NO_CLEANUP).is_some() {
|
||||
let _ = self.local_app_data.take().unwrap().into_path();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Suite {
|
||||
fn default() -> Self {
|
||||
let local_app_data = temp_dir();
|
||||
let storage = gitbutler_core::storage::Storage::new(&local_app_data);
|
||||
let users = gitbutler_core::users::Controller::from_path(&local_app_data);
|
||||
let projects = gitbutler_core::projects::Controller::from_path(&local_app_data);
|
||||
let keys = gitbutler_core::keys::Controller::from_path(&local_app_data);
|
||||
Self {
|
||||
storage,
|
||||
local_app_data: Some(local_app_data),
|
||||
users,
|
||||
projects,
|
||||
keys,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Suite {
|
||||
pub fn local_app_data(&self) -> &Path {
|
||||
self.local_app_data.as_ref().unwrap().path()
|
||||
}
|
||||
pub fn sign_in(&self) -> gitbutler_core::users::User {
|
||||
let user = gitbutler_core::users::User {
|
||||
name: Some("test".to_string()),
|
||||
email: "test@email.com".to_string(),
|
||||
access_token: "token".to_string(),
|
||||
..Default::default()
|
||||
};
|
||||
self.users.set_user(&user).expect("failed to add user");
|
||||
user
|
||||
}
|
||||
|
||||
fn project(&self, fs: HashMap<PathBuf, &str>) -> (gitbutler_core::projects::Project, TempDir) {
|
||||
let (repository, tmp) = test_repository();
|
||||
for (path, contents) in fs {
|
||||
if let Some(parent) = path.parent() {
|
||||
fs::create_dir_all(repository.path().parent().unwrap().join(parent))
|
||||
.expect("failed to create dir");
|
||||
}
|
||||
fs::write(
|
||||
repository.path().parent().unwrap().join(&path),
|
||||
contents.as_bytes(),
|
||||
)
|
||||
.expect("failed to write file");
|
||||
}
|
||||
commit_all(&repository);
|
||||
|
||||
(
|
||||
self.projects
|
||||
.add(repository.path().parent().unwrap())
|
||||
.expect("failed to add project"),
|
||||
tmp,
|
||||
)
|
||||
}
|
||||
|
||||
pub fn new_case_with_files(&self, fs: HashMap<PathBuf, &str>) -> Case {
|
||||
let (project, project_tmp) = self.project(fs);
|
||||
Case::new(self, project, project_tmp)
|
||||
}
|
||||
|
||||
pub fn new_case(&self) -> Case {
|
||||
self.new_case_with_files(HashMap::new())
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Case<'a> {
|
||||
suite: &'a Suite,
|
||||
pub project: gitbutler_core::projects::Project,
|
||||
pub project_repository: gitbutler_core::project_repository::Repository,
|
||||
pub gb_repository: gitbutler_core::gb_repository::Repository,
|
||||
pub credentials: gitbutler_core::git::credentials::Helper,
|
||||
/// The directory containing the `project_repository`
|
||||
project_tmp: Option<TempDir>,
|
||||
}
|
||||
|
||||
impl Drop for Case<'_> {
|
||||
fn drop(&mut self) {
|
||||
if let Some(tmp) = self
|
||||
.project_tmp
|
||||
.take()
|
||||
.filter(|_| std::env::var_os(VAR_NO_CLEANUP).is_some())
|
||||
{
|
||||
let _ = tmp.into_path();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Case<'a> {
|
||||
fn new(
|
||||
suite: &'a Suite,
|
||||
project: gitbutler_core::projects::Project,
|
||||
project_tmp: TempDir,
|
||||
) -> Case<'a> {
|
||||
let project_repository = gitbutler_core::project_repository::Repository::open(&project)
|
||||
.expect("failed to create project repository");
|
||||
let gb_repository = gitbutler_core::gb_repository::Repository::open(
|
||||
suite.local_app_data(),
|
||||
&project_repository,
|
||||
None,
|
||||
)
|
||||
.expect("failed to open gb repository");
|
||||
let credentials =
|
||||
gitbutler_core::git::credentials::Helper::from_path(suite.local_app_data());
|
||||
Case {
|
||||
suite,
|
||||
project,
|
||||
gb_repository,
|
||||
project_repository,
|
||||
project_tmp: Some(project_tmp),
|
||||
credentials,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn refresh(mut self) -> Self {
|
||||
let project = self
|
||||
.suite
|
||||
.projects
|
||||
.get(&self.project.id)
|
||||
.expect("failed to get project");
|
||||
let project_repository = gitbutler_core::project_repository::Repository::open(&project)
|
||||
.expect("failed to create project repository");
|
||||
let user = self.suite.users.get_user().expect("failed to get user");
|
||||
let credentials =
|
||||
gitbutler_core::git::credentials::Helper::from_path(self.suite.local_app_data());
|
||||
Self {
|
||||
suite: self.suite,
|
||||
gb_repository: gitbutler_core::gb_repository::Repository::open(
|
||||
self.suite.local_app_data(),
|
||||
&project_repository,
|
||||
user.as_ref(),
|
||||
)
|
||||
.expect("failed to open gb repository"),
|
||||
credentials,
|
||||
project_repository,
|
||||
project,
|
||||
project_tmp: self.project_tmp.take(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn test_database() -> (gitbutler_core::database::Database, TempDir) {
|
||||
let tmp = temp_dir();
|
||||
let db = gitbutler_core::database::Database::open_in_directory(&tmp).unwrap();
|
||||
(db, tmp)
|
||||
}
|
||||
|
||||
pub fn temp_dir() -> TempDir {
|
||||
tempdir().unwrap()
|
||||
}
|
||||
|
||||
pub fn empty_bare_repository() -> (gitbutler_core::git::Repository, TempDir) {
|
||||
let tmp = temp_dir();
|
||||
(
|
||||
gitbutler_core::git::Repository::init_opts(&tmp, &init_opts_bare())
|
||||
.expect("failed to init repository"),
|
||||
tmp,
|
||||
)
|
||||
}
|
||||
|
||||
pub fn test_repository() -> (gitbutler_core::git::Repository, TempDir) {
|
||||
let tmp = temp_dir();
|
||||
let repository = gitbutler_core::git::Repository::init_opts(&tmp, &init_opts())
|
||||
.expect("failed to init repository");
|
||||
let mut index = repository.index().expect("failed to get index");
|
||||
let oid = index.write_tree().expect("failed to write tree");
|
||||
let signature = gitbutler_core::git::Signature::now("test", "test@email.com").unwrap();
|
||||
repository
|
||||
.commit(
|
||||
Some(&"refs/heads/master".parse().unwrap()),
|
||||
&signature,
|
||||
&signature,
|
||||
"Initial commit",
|
||||
&repository.find_tree(oid).expect("failed to find tree"),
|
||||
&[],
|
||||
)
|
||||
.expect("failed to commit");
|
||||
(repository, tmp)
|
||||
}
|
||||
|
||||
pub fn commit_all(repository: &gitbutler_core::git::Repository) -> gitbutler_core::git::Oid {
|
||||
let mut index = repository.index().expect("failed to get index");
|
||||
index
|
||||
.add_all(["."], git2::IndexAddOption::DEFAULT, None)
|
||||
.expect("failed to add all");
|
||||
index.write().expect("failed to write index");
|
||||
let oid = index.write_tree().expect("failed to write tree");
|
||||
let signature = gitbutler_core::git::Signature::now("test", "test@email.com").unwrap();
|
||||
let head = repository.head().expect("failed to get head");
|
||||
let commit_oid = repository
|
||||
.commit(
|
||||
Some(&head.name().unwrap()),
|
||||
&signature,
|
||||
&signature,
|
||||
"some commit",
|
||||
&repository.find_tree(oid).expect("failed to find tree"),
|
||||
&[&repository
|
||||
.find_commit(
|
||||
repository
|
||||
.refname_to_id("HEAD")
|
||||
.expect("failed to get head"),
|
||||
)
|
||||
.expect("failed to find commit")],
|
||||
)
|
||||
.expect("failed to commit");
|
||||
commit_oid
|
||||
}
|
@ -1,348 +0,0 @@
|
||||
#![allow(unused)]
|
||||
|
||||
use std::{path, str::from_utf8};
|
||||
|
||||
use gitbutler_core::git;
|
||||
use tempfile::TempDir;
|
||||
|
||||
use crate::shared::{init_opts, VAR_NO_CLEANUP};
|
||||
|
||||
pub fn temp_dir() -> TempDir {
|
||||
tempfile::tempdir().unwrap()
|
||||
}
|
||||
|
||||
pub struct TestProject {
|
||||
local_repository: git::Repository,
|
||||
local_tmp: Option<TempDir>,
|
||||
remote_repository: git::Repository,
|
||||
remote_tmp: Option<TempDir>,
|
||||
}
|
||||
|
||||
impl Drop for TestProject {
|
||||
fn drop(&mut self) {
|
||||
if std::env::var_os(VAR_NO_CLEANUP).is_some() {
|
||||
let _ = self.local_tmp.take().unwrap().into_path();
|
||||
let _ = self.remote_tmp.take().unwrap().into_path();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for TestProject {
|
||||
fn default() -> Self {
|
||||
let local_tmp = temp_dir();
|
||||
let local_repository = git::Repository::init_opts(local_tmp.path(), &init_opts())
|
||||
.expect("failed to init repository");
|
||||
let mut index = local_repository.index().expect("failed to get index");
|
||||
let oid = index.write_tree().expect("failed to write tree");
|
||||
let signature = git::Signature::now("test", "test@email.com").unwrap();
|
||||
local_repository
|
||||
.commit(
|
||||
Some(&"refs/heads/master".parse().unwrap()),
|
||||
&signature,
|
||||
&signature,
|
||||
"Initial commit",
|
||||
&local_repository
|
||||
.find_tree(oid)
|
||||
.expect("failed to find tree"),
|
||||
&[],
|
||||
)
|
||||
.expect("failed to commit");
|
||||
|
||||
let remote_tmp = temp_dir();
|
||||
let remote_repository = git::Repository::init_opts(
|
||||
remote_tmp.path(),
|
||||
git2::RepositoryInitOptions::new()
|
||||
.bare(true)
|
||||
.external_template(false),
|
||||
)
|
||||
.expect("failed to init repository");
|
||||
|
||||
{
|
||||
let mut remote = local_repository
|
||||
.remote(
|
||||
"origin",
|
||||
&remote_repository
|
||||
.path()
|
||||
.to_str()
|
||||
.expect("failed to convert path to str")
|
||||
.parse()
|
||||
.unwrap(),
|
||||
)
|
||||
.expect("failed to add remote");
|
||||
remote
|
||||
.push(&["refs/heads/master:refs/heads/master"], None)
|
||||
.expect("failed to push");
|
||||
}
|
||||
|
||||
Self {
|
||||
local_repository,
|
||||
local_tmp: Some(local_tmp),
|
||||
remote_repository,
|
||||
remote_tmp: Some(remote_tmp),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl TestProject {
|
||||
pub fn path(&self) -> &std::path::Path {
|
||||
self.local_repository.workdir().unwrap()
|
||||
}
|
||||
|
||||
pub fn push_branch(&self, branch: &git::LocalRefname) {
|
||||
let mut origin = self.local_repository.find_remote("origin").unwrap();
|
||||
origin.push(&[&format!("{branch}:{branch}")], None).unwrap();
|
||||
}
|
||||
|
||||
pub fn push(&self) {
|
||||
let mut origin = self.local_repository.find_remote("origin").unwrap();
|
||||
origin
|
||||
.push(&["refs/heads/master:refs/heads/master"], None)
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
/// git add -A
|
||||
/// git reset --hard <oid>
|
||||
pub fn reset_hard(&self, oid: Option<git::Oid>) {
|
||||
let mut index = self.local_repository.index().expect("failed to get index");
|
||||
index
|
||||
.add_all(["."], git2::IndexAddOption::DEFAULT, None)
|
||||
.expect("failed to add all");
|
||||
index.write().expect("failed to write index");
|
||||
|
||||
let head = self.local_repository.head().unwrap();
|
||||
let commit = oid.map_or(head.peel_to_commit().unwrap(), |oid| {
|
||||
self.local_repository.find_commit(oid).unwrap()
|
||||
});
|
||||
|
||||
let head_ref = head.name().unwrap();
|
||||
let head_ref = self.local_repository.find_reference(&head_ref).unwrap();
|
||||
|
||||
self.local_repository
|
||||
.reset(&commit, git2::ResetType::Hard, None)
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
/// fetch remote into local
|
||||
pub fn fetch(&self) {
|
||||
let mut remote = self.local_repository.find_remote("origin").unwrap();
|
||||
remote
|
||||
.fetch(&["+refs/heads/*:refs/remotes/origin/*"], None)
|
||||
.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 {
|
||||
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 merge_base = {
|
||||
let oid = self
|
||||
.remote_repository
|
||||
.merge_base(branch_commit.id(), master_branch_commit.id())
|
||||
.unwrap();
|
||||
self.remote_repository.find_commit(oid).unwrap()
|
||||
};
|
||||
let merge_tree = {
|
||||
let mut merge_index = self
|
||||
.remote_repository
|
||||
.merge_trees(
|
||||
&merge_base.tree().unwrap(),
|
||||
&master_branch.peel_to_tree().unwrap(),
|
||||
&branch.peel_to_tree().unwrap(),
|
||||
)
|
||||
.unwrap();
|
||||
let oid = merge_index.write_tree_to(&self.remote_repository).unwrap();
|
||||
self.remote_repository.find_tree(oid).unwrap()
|
||||
};
|
||||
|
||||
self.remote_repository
|
||||
.commit(
|
||||
Some(&"refs/heads/master".parse().unwrap()),
|
||||
&branch_commit.author(),
|
||||
&branch_commit.committer(),
|
||||
&format!("Merge pull request from {}", branch_name),
|
||||
&merge_tree,
|
||||
&[&master_branch_commit, &branch_commit],
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
pub fn find_commit(&self, oid: git::Oid) -> Result<git::Commit, git::Error> {
|
||||
self.local_repository.find_commit(oid)
|
||||
}
|
||||
|
||||
pub fn checkout_commit(&self, commit_oid: git::Oid) {
|
||||
let commit = self.local_repository.find_commit(commit_oid).unwrap();
|
||||
let commit_tree = commit.tree().unwrap();
|
||||
|
||||
self.local_repository.set_head_detached(commit_oid).unwrap();
|
||||
self.local_repository
|
||||
.checkout_tree(&commit_tree)
|
||||
.force()
|
||||
.checkout()
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
pub fn checkout(&self, branch: &git::LocalRefname) {
|
||||
let branch: git::Refname = branch.into();
|
||||
let tree = match self.local_repository.find_branch(&branch) {
|
||||
Ok(branch) => branch.peel_to_tree(),
|
||||
Err(git::Error::NotFound(_)) => {
|
||||
let head_commit = self
|
||||
.local_repository
|
||||
.head()
|
||||
.unwrap()
|
||||
.peel_to_commit()
|
||||
.unwrap();
|
||||
self.local_repository
|
||||
.reference(&branch, head_commit.id(), false, "new branch")
|
||||
.unwrap();
|
||||
head_commit.tree()
|
||||
}
|
||||
Err(error) => Err(error),
|
||||
}
|
||||
.unwrap();
|
||||
self.local_repository.set_head(&branch).unwrap();
|
||||
self.local_repository
|
||||
.checkout_tree(&tree)
|
||||
.force()
|
||||
.checkout()
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
/// takes all changes in the working directory and commits them into local
|
||||
pub fn commit_all(&self, message: &str) -> git::Oid {
|
||||
let head = self.local_repository.head().unwrap();
|
||||
let mut index = self.local_repository.index().expect("failed to get index");
|
||||
index
|
||||
.add_all(["."], git2::IndexAddOption::DEFAULT, None)
|
||||
.expect("failed to add all");
|
||||
index.write().expect("failed to write index");
|
||||
let oid = index.write_tree().expect("failed to write tree");
|
||||
let signature = git::Signature::now("test", "test@email.com").unwrap();
|
||||
self.local_repository
|
||||
.commit(
|
||||
head.name().as_ref(),
|
||||
&signature,
|
||||
&signature,
|
||||
message,
|
||||
&self
|
||||
.local_repository
|
||||
.find_tree(oid)
|
||||
.expect("failed to find tree"),
|
||||
&[&self
|
||||
.local_repository
|
||||
.find_commit(
|
||||
self.local_repository
|
||||
.refname_to_id("HEAD")
|
||||
.expect("failed to get head"),
|
||||
)
|
||||
.expect("failed to find commit")],
|
||||
)
|
||||
.expect("failed to commit")
|
||||
}
|
||||
|
||||
pub fn references(&self) -> Vec<git::Reference> {
|
||||
self.local_repository
|
||||
.references()
|
||||
.expect("failed to get references")
|
||||
.collect::<Result<Vec<_>, _>>()
|
||||
.expect("failed to read references")
|
||||
}
|
||||
|
||||
pub fn add_submodule(&self, url: &git::Url, path: &path::Path) {
|
||||
let mut submodule = self.local_repository.add_submodule(url, path).unwrap();
|
||||
let repo = submodule.open().unwrap();
|
||||
|
||||
// checkout submodule's master head
|
||||
repo.find_remote("origin")
|
||||
.unwrap()
|
||||
.fetch(&["+refs/heads/*:refs/heads/*"], None, None)
|
||||
.unwrap();
|
||||
let reference = repo.find_reference("refs/heads/master").unwrap();
|
||||
let reference_head = repo.find_commit(reference.target().unwrap()).unwrap();
|
||||
repo.checkout_tree(reference_head.tree().unwrap().as_object(), None)
|
||||
.unwrap();
|
||||
|
||||
// be sure that `HEAD` points to the actual head - `git2` seems to initialize it
|
||||
// with `init.defaultBranch`, causing failure otherwise.
|
||||
repo.set_head("refs/heads/master");
|
||||
submodule.add_finalize().unwrap();
|
||||
}
|
||||
}
|
@ -2,7 +2,7 @@ use std::path;
|
||||
|
||||
use gitbutler_core::{gb_repository, git, project_repository, projects};
|
||||
|
||||
use crate::shared::{paths, TestProject};
|
||||
use gitbutler_testsupport::{paths, TestProject};
|
||||
|
||||
mod init {
|
||||
use super::*;
|
||||
|
@ -1,7 +1,7 @@
|
||||
use gitbutler_core::projects::Controller;
|
||||
use tempfile::TempDir;
|
||||
|
||||
use crate::shared::{self, paths};
|
||||
use gitbutler_testsupport::{self, paths};
|
||||
|
||||
pub fn new() -> (Controller, TempDir) {
|
||||
let data_dir = paths::data_dir();
|
||||
@ -15,7 +15,7 @@ mod add {
|
||||
#[test]
|
||||
fn success() {
|
||||
let (controller, _tmp) = new();
|
||||
let repository = shared::TestProject::default();
|
||||
let repository = gitbutler_testsupport::TestProject::default();
|
||||
let path = repository.path();
|
||||
let project = controller.add(path).unwrap();
|
||||
assert_eq!(project.path, path);
|
||||
@ -62,7 +62,7 @@ mod add {
|
||||
#[test]
|
||||
fn twice() {
|
||||
let (controller, _tmp) = new();
|
||||
let repository = shared::TestProject::default();
|
||||
let repository = gitbutler_testsupport::TestProject::default();
|
||||
let path = repository.path();
|
||||
controller.add(path).unwrap();
|
||||
assert!(matches!(controller.add(path), Err(AddError::AlreadyExists)));
|
||||
|
@ -8,7 +8,7 @@ use gitbutler_core::{
|
||||
};
|
||||
use tempfile::TempDir;
|
||||
|
||||
use crate::shared::{paths, TestProject, VAR_NO_CLEANUP};
|
||||
use gitbutler_testsupport::{paths, TestProject, VAR_NO_CLEANUP};
|
||||
|
||||
struct Test {
|
||||
repository: TestProject,
|
||||
|
@ -7,7 +7,7 @@ use gitbutler_core::virtual_branches::{
|
||||
};
|
||||
use once_cell::sync::Lazy;
|
||||
|
||||
use crate::shared::{Case, Suite};
|
||||
use gitbutler_testsupport::{Case, Suite};
|
||||
|
||||
static TEST_INDEX: Lazy<AtomicUsize> = Lazy::new(|| AtomicUsize::new(0));
|
||||
|
||||
|
@ -9,7 +9,7 @@ use once_cell::sync::Lazy;
|
||||
|
||||
use self::branch::BranchId;
|
||||
use super::*;
|
||||
use crate::shared::{Case, Suite};
|
||||
use gitbutler_testsupport::{Case, Suite};
|
||||
|
||||
static TEST_INDEX: Lazy<AtomicUsize> = Lazy::new(|| AtomicUsize::new(0));
|
||||
|
||||
|
@ -4,7 +4,7 @@ use anyhow::Result;
|
||||
use gitbutler_core::virtual_branches::{self, VirtualBranchesHandle};
|
||||
use once_cell::sync::Lazy;
|
||||
|
||||
use crate::shared::{Case, Suite};
|
||||
use gitbutler_testsupport::{Case, Suite};
|
||||
|
||||
static TEST_INDEX: Lazy<AtomicUsize> = Lazy::new(|| AtomicUsize::new(0));
|
||||
|
||||
|
@ -28,7 +28,7 @@ use gitbutler_core::{
|
||||
};
|
||||
use pretty_assertions::assert_eq;
|
||||
|
||||
use crate::shared::{commit_all, virtual_branches::set_test_target, Case, Suite};
|
||||
use gitbutler_testsupport::{commit_all, virtual_branches::set_test_target, Case, Suite};
|
||||
|
||||
#[test]
|
||||
fn commit_on_branch_then_change_file_then_get_status() -> Result<()> {
|
||||
|
@ -7,7 +7,7 @@ use gitbutler_core::virtual_branches::{
|
||||
};
|
||||
use once_cell::sync::Lazy;
|
||||
|
||||
use crate::shared::{Case, Suite};
|
||||
use gitbutler_testsupport::{Case, Suite};
|
||||
|
||||
static TEST_INDEX: Lazy<AtomicUsize> = Lazy::new(|| AtomicUsize::new(0));
|
||||
|
||||
|
@ -11,7 +11,7 @@ use gitbutler_core::virtual_branches::{
|
||||
};
|
||||
use once_cell::sync::Lazy;
|
||||
|
||||
use crate::shared::{Case, Suite};
|
||||
use gitbutler_testsupport::{Case, Suite};
|
||||
|
||||
static TEST_INDEX: Lazy<AtomicUsize> = Lazy::new(|| AtomicUsize::new(0));
|
||||
|
||||
|
@ -20,6 +20,7 @@ tauri-build = { version = "1.5", features = [] }
|
||||
#once_cell = "1.19"
|
||||
pretty_assertions = "1.4"
|
||||
tempfile = "3.10"
|
||||
gitbutler-testsupport = { path = "../gitbutler-testsupport" }
|
||||
|
||||
[dependencies]
|
||||
anyhow = "1.0.81"
|
||||
|
@ -1,4 +1 @@
|
||||
// TODO(ST): move test code into crate and use that, but wait for `crates/`
|
||||
#[path = "../../gitbutler-core/tests/shared/mod.rs"]
|
||||
pub mod shared;
|
||||
mod watcher;
|
||||
|
@ -14,7 +14,7 @@ use gitbutler_tauri::watcher::handlers::calculate_deltas_handler::Handler;
|
||||
use once_cell::sync::Lazy;
|
||||
|
||||
use self::branch::BranchId;
|
||||
use crate::shared::{commit_all, Case, Suite};
|
||||
use gitbutler_testsupport::{commit_all, Case, Suite};
|
||||
|
||||
static TEST_TARGET_INDEX: Lazy<AtomicUsize> = Lazy::new(|| AtomicUsize::new(0));
|
||||
|
||||
|
@ -4,10 +4,8 @@ use gitbutler_core::projects;
|
||||
use gitbutler_tauri::watcher::handlers::fetch_gitbutler_data::Handler;
|
||||
use pretty_assertions::assert_eq;
|
||||
|
||||
use crate::{
|
||||
shared::{Case, Suite},
|
||||
watcher::handler::test_remote_repository,
|
||||
};
|
||||
use crate::watcher::handler::test_remote_repository;
|
||||
use gitbutler_testsupport::{Case, Suite};
|
||||
|
||||
#[tokio::test]
|
||||
async fn fetch_success() -> anyhow::Result<()> {
|
||||
|
@ -5,7 +5,7 @@ use gitbutler_core::projects;
|
||||
use gitbutler_tauri::watcher::{handlers, handlers::git_file_change::Handler, Event};
|
||||
use pretty_assertions::assert_eq;
|
||||
|
||||
use crate::shared::{Case, Suite};
|
||||
use gitbutler_testsupport::{Case, Suite};
|
||||
|
||||
#[test]
|
||||
fn flush_session() -> Result<()> {
|
||||
|
@ -1,6 +1,6 @@
|
||||
use tempfile::TempDir;
|
||||
|
||||
use crate::shared::init_opts_bare;
|
||||
use gitbutler_testsupport::init_opts_bare;
|
||||
|
||||
fn test_remote_repository() -> anyhow::Result<(git2::Repository, TempDir)> {
|
||||
let tmp = tempfile::tempdir()?;
|
||||
|
@ -4,10 +4,8 @@ use anyhow::Result;
|
||||
use gitbutler_core::{git, project_repository::LogUntil, projects};
|
||||
use gitbutler_tauri::watcher::handlers::push_project_to_gitbutler::Handler;
|
||||
|
||||
use crate::{
|
||||
shared::{virtual_branches::set_test_target, Case, Suite},
|
||||
watcher::handler::test_remote_repository,
|
||||
};
|
||||
use crate::watcher::handler::test_remote_repository;
|
||||
use gitbutler_testsupport::{virtual_branches::set_test_target, Case, Suite};
|
||||
|
||||
fn log_walk(repo: &git2::Repository, head: git::Oid) -> Vec<git::Oid> {
|
||||
let mut walker = repo.revwalk().unwrap();
|
||||
|
Loading…
Reference in New Issue
Block a user