start moving virtual_branches to separate crate

We want to move towards having each functional domain in a separate crate. 
The main benefit of that for our project is that this will enforce a unidirectional dependency graph (i.e. no cycles).
Starting off with virutal_branches - a lot of the implementation is still in core (i.e. virtual.rs), that will be moved in a separate PR. 

Furthermore, the virtual branches controller (as well as virtual.rs) contain functions not directly related to branches (e.g. commit reordering etc). That will be furthe separate in a crate.
This commit is contained in:
Kiril Videlov 2024-07-07 13:32:35 +02:00
parent ef3e6afdc9
commit 7d078de52f
No known key found for this signature in database
GPG Key ID: A4C733025427C471
40 changed files with 135 additions and 64 deletions

21
Cargo.lock generated
View File

@ -2102,6 +2102,25 @@ dependencies = [
"thiserror", "thiserror",
] ]
[[package]]
name = "gitbutler-branch"
version = "0.0.0"
dependencies = [
"anyhow",
"git2",
"gitbutler-core",
"gitbutler-git",
"gitbutler-testsupport",
"glob",
"itertools 0.13.0",
"once_cell",
"pretty_assertions",
"serial_test",
"tempfile",
"tokio",
"tracing",
]
[[package]] [[package]]
name = "gitbutler-cli" name = "gitbutler-cli"
version = "0.0.0" version = "0.0.0"
@ -2209,6 +2228,7 @@ dependencies = [
"dirs 5.0.1", "dirs 5.0.1",
"futures", "futures",
"git2", "git2",
"gitbutler-branch",
"gitbutler-core", "gitbutler-core",
"gitbutler-testsupport", "gitbutler-testsupport",
"gitbutler-watcher", "gitbutler-watcher",
@ -2256,6 +2276,7 @@ dependencies = [
"anyhow", "anyhow",
"backoff", "backoff",
"futures", "futures",
"gitbutler-branch",
"gitbutler-core", "gitbutler-core",
"gitbutler-notify-debouncer", "gitbutler-notify-debouncer",
"gix", "gix",

View File

@ -6,7 +6,8 @@ members = [
"crates/gitbutler-watcher", "crates/gitbutler-watcher",
"crates/gitbutler-watcher/vendor/debouncer", "crates/gitbutler-watcher/vendor/debouncer",
"crates/gitbutler-testsupport", "crates/gitbutler-testsupport",
"crates/gitbutler-cli", "crates/gitbutler-cli",
"crates/gitbutler-branch",
] ]
resolver = "2" resolver = "2"
@ -25,6 +26,7 @@ gitbutler-core = { path = "crates/gitbutler-core" }
gitbutler-watcher = { path = "crates/gitbutler-watcher" } gitbutler-watcher = { path = "crates/gitbutler-watcher" }
gitbutler-testsupport = { path = "crates/gitbutler-testsupport" } gitbutler-testsupport = { path = "crates/gitbutler-testsupport" }
gitbutler-cli ={ path = "crates/gitbutler-cli" } gitbutler-cli ={ path = "crates/gitbutler-cli" }
gitbutler-branch = { path = "crates/gitbutler-branch" }
[profile.release] [profile.release]
codegen-units = 1 # Compile crates one after another so the compiler can optimize better codegen-units = 1 # Compile crates one after another so the compiler can optimize better

View File

@ -0,0 +1,27 @@
[package]
name = "gitbutler-branch"
version = "0.0.0"
edition = "2021"
authors = ["GitButler <gitbutler@gitbutler.com>"]
publish = false
[dependencies]
tracing = "0.1.40"
anyhow = "1.0.86"
git2.workspace = true
tokio.workspace = true
gitbutler-core.workspace = true
[[test]]
name="branches"
path = "tests/virtual_branches/mod.rs"
[dev-dependencies]
once_cell = "1.19"
pretty_assertions = "1.4"
gitbutler-testsupport.workspace = true
gitbutler-git = { workspace = true, features = ["test-askpass-path"] }
glob = "0.3.1"
serial_test = "3.1.1"
tempfile = "3.10"
itertools = "0.13"

View File

@ -1,20 +1,22 @@
use crate::{ use anyhow::Result;
use gitbutler_core::{
git::{credentials::Helper, BranchExt}, git::{credentials::Helper, BranchExt},
ops::entry::{OperationKind, SnapshotDetails}, ops::entry::{OperationKind, SnapshotDetails},
project_repository::Repository, project_repository::Repository,
projects::FetchResult, projects::FetchResult,
types::ReferenceName, types::ReferenceName,
}; };
use anyhow::Result;
use std::{path::Path, sync::Arc}; use std::{path::Path, sync::Arc};
use tokio::sync::Semaphore; use tokio::sync::Semaphore;
use super::{ use gitbutler_core::virtual_branches;
use gitbutler_core::virtual_branches::{
branch::{BranchId, BranchOwnershipClaims}, branch::{BranchId, BranchOwnershipClaims},
target, BaseBranch, NameConflitResolution, RemoteBranchFile, VirtualBranchesHandle, target, BaseBranch, NameConflitResolution, RemoteBranchFile, VirtualBranchesHandle,
}; };
use crate::{ use gitbutler_core::{
git, git,
projects::{self, Project}, projects::{self, Project},
}; };
@ -44,7 +46,7 @@ impl Controller {
self.permit(project.ignore_project_semaphore).await; self.permit(project.ignore_project_semaphore).await;
let project_repository = open_with_verify(project)?; let project_repository = open_with_verify(project)?;
let snapshot_tree = project_repository.project().prepare_snapshot(); let snapshot_tree = project_repository.project().prepare_snapshot();
let result = super::commit( let result = virtual_branches::commit(
&project_repository, &project_repository,
branch_id, branch_id,
message, message,
@ -69,28 +71,32 @@ impl Controller {
branch_name: &git::RemoteRefname, branch_name: &git::RemoteRefname,
) -> Result<bool> { ) -> Result<bool> {
let project_repository = Repository::open(project)?; let project_repository = Repository::open(project)?;
super::is_remote_branch_mergeable(&project_repository, branch_name).map_err(Into::into) virtual_branches::is_remote_branch_mergeable(&project_repository, branch_name)
.map_err(Into::into)
} }
pub async fn list_virtual_branches( pub async fn list_virtual_branches(
&self, &self,
project: &Project, project: &Project,
) -> Result<(Vec<super::VirtualBranch>, Vec<git::diff::FileDiff>)> { ) -> Result<(
Vec<virtual_branches::VirtualBranch>,
Vec<git::diff::FileDiff>,
)> {
self.permit(project.ignore_project_semaphore).await; self.permit(project.ignore_project_semaphore).await;
let project_repository = open_with_verify(project)?; let project_repository = open_with_verify(project)?;
super::list_virtual_branches(&project_repository).map_err(Into::into) virtual_branches::list_virtual_branches(&project_repository).map_err(Into::into)
} }
pub async fn create_virtual_branch( pub async fn create_virtual_branch(
&self, &self,
project: &Project, project: &Project,
create: &super::branch::BranchCreateRequest, create: &virtual_branches::branch::BranchCreateRequest,
) -> Result<BranchId> { ) -> Result<BranchId> {
self.permit(project.ignore_project_semaphore).await; self.permit(project.ignore_project_semaphore).await;
let project_repository = open_with_verify(project)?; let project_repository = open_with_verify(project)?;
let branch_id = super::create_virtual_branch(&project_repository, create)?.id; let branch_id = virtual_branches::create_virtual_branch(&project_repository, create)?.id;
Ok(branch_id) Ok(branch_id)
} }
@ -102,12 +108,13 @@ impl Controller {
self.permit(project.ignore_project_semaphore).await; self.permit(project.ignore_project_semaphore).await;
let project_repository = open_with_verify(project)?; let project_repository = open_with_verify(project)?;
super::create_virtual_branch_from_branch(&project_repository, branch).map_err(Into::into) virtual_branches::create_virtual_branch_from_branch(&project_repository, branch)
.map_err(Into::into)
} }
pub async fn get_base_branch_data(&self, project: &Project) -> Result<BaseBranch> { pub async fn get_base_branch_data(&self, project: &Project) -> Result<BaseBranch> {
let project_repository = Repository::open(project)?; let project_repository = Repository::open(project)?;
super::get_base_branch_data(&project_repository) virtual_branches::get_base_branch_data(&project_repository)
} }
pub async fn list_remote_commit_files( pub async fn list_remote_commit_files(
@ -116,7 +123,8 @@ impl Controller {
commit_oid: git2::Oid, commit_oid: git2::Oid,
) -> Result<Vec<RemoteBranchFile>> { ) -> Result<Vec<RemoteBranchFile>> {
let project_repository = Repository::open(project)?; let project_repository = Repository::open(project)?;
super::list_remote_commit_files(project_repository.repo(), commit_oid).map_err(Into::into) virtual_branches::list_remote_commit_files(project_repository.repo(), commit_oid)
.map_err(Into::into)
} }
pub async fn set_base_branch( pub async fn set_base_branch(
@ -128,12 +136,12 @@ impl Controller {
let _ = project_repository let _ = project_repository
.project() .project()
.create_snapshot(SnapshotDetails::new(OperationKind::SetBaseBranch)); .create_snapshot(SnapshotDetails::new(OperationKind::SetBaseBranch));
super::set_base_branch(&project_repository, target_branch) virtual_branches::set_base_branch(&project_repository, target_branch)
} }
pub async fn set_target_push_remote(&self, project: &Project, push_remote: &str) -> Result<()> { pub async fn set_target_push_remote(&self, project: &Project, push_remote: &str) -> Result<()> {
let project_repository = Repository::open(project)?; let project_repository = Repository::open(project)?;
super::set_target_push_remote(&project_repository, push_remote) virtual_branches::set_target_push_remote(&project_repository, push_remote)
} }
pub async fn integrate_upstream_commits( pub async fn integrate_upstream_commits(
@ -147,7 +155,8 @@ impl Controller {
let _ = project_repository let _ = project_repository
.project() .project()
.create_snapshot(SnapshotDetails::new(OperationKind::MergeUpstream)); .create_snapshot(SnapshotDetails::new(OperationKind::MergeUpstream));
super::integrate_upstream_commits(&project_repository, branch_id).map_err(Into::into) virtual_branches::integrate_upstream_commits(&project_repository, branch_id)
.map_err(Into::into)
} }
pub async fn update_base_branch(&self, project: &Project) -> Result<Vec<ReferenceName>> { pub async fn update_base_branch(&self, project: &Project) -> Result<Vec<ReferenceName>> {
@ -157,7 +166,7 @@ impl Controller {
let _ = project_repository let _ = project_repository
.project() .project()
.create_snapshot(SnapshotDetails::new(OperationKind::UpdateWorkspaceBase)); .create_snapshot(SnapshotDetails::new(OperationKind::UpdateWorkspaceBase));
super::update_base_branch(&project_repository) virtual_branches::update_base_branch(&project_repository)
.map(|unapplied_branches| { .map(|unapplied_branches| {
unapplied_branches unapplied_branches
.iter() .iter()
@ -170,7 +179,7 @@ impl Controller {
pub async fn update_virtual_branch( pub async fn update_virtual_branch(
&self, &self,
project: &Project, project: &Project,
branch_update: super::branch::BranchUpdateRequest, branch_update: virtual_branches::branch::BranchUpdateRequest,
) -> Result<()> { ) -> Result<()> {
self.permit(project.ignore_project_semaphore).await; self.permit(project.ignore_project_semaphore).await;
@ -180,7 +189,7 @@ impl Controller {
.project() .project()
.virtual_branches() .virtual_branches()
.get_branch(branch_update.id)?; .get_branch(branch_update.id)?;
let result = super::update_branch(&project_repository, &branch_update); let result = virtual_branches::update_branch(&project_repository, &branch_update);
let _ = snapshot_tree.and_then(|snapshot_tree| { let _ = snapshot_tree.and_then(|snapshot_tree| {
project_repository.project().snapshot_branch_update( project_repository.project().snapshot_branch_update(
snapshot_tree, snapshot_tree,
@ -200,7 +209,7 @@ impl Controller {
self.permit(project.ignore_project_semaphore).await; self.permit(project.ignore_project_semaphore).await;
let project_repository = open_with_verify(project)?; let project_repository = open_with_verify(project)?;
super::delete_branch(&project_repository, branch_id) virtual_branches::delete_branch(&project_repository, branch_id)
} }
pub async fn unapply_ownership( pub async fn unapply_ownership(
@ -214,7 +223,7 @@ impl Controller {
let _ = project_repository let _ = project_repository
.project() .project()
.create_snapshot(SnapshotDetails::new(OperationKind::DiscardHunk)); .create_snapshot(SnapshotDetails::new(OperationKind::DiscardHunk));
super::unapply_ownership(&project_repository, ownership).map_err(Into::into) virtual_branches::unapply_ownership(&project_repository, ownership).map_err(Into::into)
} }
pub async fn reset_files(&self, project: &Project, files: &Vec<String>) -> Result<()> { pub async fn reset_files(&self, project: &Project, files: &Vec<String>) -> Result<()> {
@ -224,7 +233,7 @@ impl Controller {
let _ = project_repository let _ = project_repository
.project() .project()
.create_snapshot(SnapshotDetails::new(OperationKind::DiscardFile)); .create_snapshot(SnapshotDetails::new(OperationKind::DiscardFile));
super::reset_files(&project_repository, files).map_err(Into::into) virtual_branches::reset_files(&project_repository, files).map_err(Into::into)
} }
pub async fn amend( pub async fn amend(
@ -240,7 +249,7 @@ impl Controller {
let _ = project_repository let _ = project_repository
.project() .project()
.create_snapshot(SnapshotDetails::new(OperationKind::AmendCommit)); .create_snapshot(SnapshotDetails::new(OperationKind::AmendCommit));
super::amend(&project_repository, branch_id, commit_oid, ownership) virtual_branches::amend(&project_repository, branch_id, commit_oid, ownership)
} }
pub async fn move_commit_file( pub async fn move_commit_file(
@ -257,7 +266,7 @@ impl Controller {
let _ = project_repository let _ = project_repository
.project() .project()
.create_snapshot(SnapshotDetails::new(OperationKind::MoveCommitFile)); .create_snapshot(SnapshotDetails::new(OperationKind::MoveCommitFile));
super::move_commit_file( virtual_branches::move_commit_file(
&project_repository, &project_repository,
branch_id, branch_id,
from_commit_oid, from_commit_oid,
@ -278,7 +287,8 @@ impl Controller {
let project_repository = open_with_verify(project)?; let project_repository = open_with_verify(project)?;
let snapshot_tree = project_repository.project().prepare_snapshot(); let snapshot_tree = project_repository.project().prepare_snapshot();
let result: Result<()> = let result: Result<()> =
super::undo_commit(&project_repository, branch_id, commit_oid).map_err(Into::into); virtual_branches::undo_commit(&project_repository, branch_id, commit_oid)
.map_err(Into::into);
let _ = snapshot_tree.and_then(|snapshot_tree| { let _ = snapshot_tree.and_then(|snapshot_tree| {
project_repository.project().snapshot_commit_undo( project_repository.project().snapshot_commit_undo(
snapshot_tree, snapshot_tree,
@ -302,7 +312,7 @@ impl Controller {
let _ = project_repository let _ = project_repository
.project() .project()
.create_snapshot(SnapshotDetails::new(OperationKind::InsertBlankCommit)); .create_snapshot(SnapshotDetails::new(OperationKind::InsertBlankCommit));
super::insert_blank_commit(&project_repository, branch_id, commit_oid, offset) virtual_branches::insert_blank_commit(&project_repository, branch_id, commit_oid, offset)
.map_err(Into::into) .map_err(Into::into)
} }
@ -319,7 +329,7 @@ impl Controller {
let _ = project_repository let _ = project_repository
.project() .project()
.create_snapshot(SnapshotDetails::new(OperationKind::ReorderCommit)); .create_snapshot(SnapshotDetails::new(OperationKind::ReorderCommit));
super::reorder_commit(&project_repository, branch_id, commit_oid, offset) virtual_branches::reorder_commit(&project_repository, branch_id, commit_oid, offset)
.map_err(Into::into) .map_err(Into::into)
} }
@ -335,7 +345,8 @@ impl Controller {
let _ = project_repository let _ = project_repository
.project() .project()
.create_snapshot(SnapshotDetails::new(OperationKind::UndoCommit)); .create_snapshot(SnapshotDetails::new(OperationKind::UndoCommit));
super::reset_branch(&project_repository, branch_id, target_commit_oid).map_err(Into::into) virtual_branches::reset_branch(&project_repository, branch_id, target_commit_oid)
.map_err(Into::into)
} }
pub async fn convert_to_real_branch( pub async fn convert_to_real_branch(
@ -348,9 +359,12 @@ impl Controller {
let project_repository = open_with_verify(project)?; let project_repository = open_with_verify(project)?;
let snapshot_tree = project_repository.project().prepare_snapshot(); let snapshot_tree = project_repository.project().prepare_snapshot();
let result = let result = virtual_branches::convert_to_real_branch(
super::convert_to_real_branch(&project_repository, branch_id, name_conflict_resolution) &project_repository,
.map_err(Into::into); branch_id,
name_conflict_resolution,
)
.map_err(Into::into);
let _ = snapshot_tree.and_then(|snapshot_tree| { let _ = snapshot_tree.and_then(|snapshot_tree| {
project_repository project_repository
.project() .project()
@ -369,21 +383,24 @@ impl Controller {
self.permit(project.ignore_project_semaphore).await; self.permit(project.ignore_project_semaphore).await;
let helper = Helper::default(); let helper = Helper::default();
let project_repository = open_with_verify(project)?; let project_repository = open_with_verify(project)?;
super::push(&project_repository, branch_id, with_force, &helper, askpass) virtual_branches::push(&project_repository, branch_id, with_force, &helper, askpass)
} }
pub async fn list_remote_branches(&self, project: Project) -> Result<Vec<super::RemoteBranch>> { pub async fn list_remote_branches(
&self,
project: Project,
) -> Result<Vec<virtual_branches::RemoteBranch>> {
let project_repository = Repository::open(&project)?; let project_repository = Repository::open(&project)?;
super::list_remote_branches(&project_repository) virtual_branches::list_remote_branches(&project_repository)
} }
pub async fn get_remote_branch_data( pub async fn get_remote_branch_data(
&self, &self,
project: &Project, project: &Project,
refname: &git::Refname, refname: &git::Refname,
) -> Result<super::RemoteBranchData> { ) -> Result<virtual_branches::RemoteBranchData> {
let project_repository = Repository::open(project)?; let project_repository = Repository::open(project)?;
super::get_branch_data(&project_repository, refname) virtual_branches::get_branch_data(&project_repository, refname)
} }
pub async fn squash( pub async fn squash(
@ -398,7 +415,7 @@ impl Controller {
let _ = project_repository let _ = project_repository
.project() .project()
.create_snapshot(SnapshotDetails::new(OperationKind::SquashCommit)); .create_snapshot(SnapshotDetails::new(OperationKind::SquashCommit));
super::squash(&project_repository, branch_id, commit_oid).map_err(Into::into) virtual_branches::squash(&project_repository, branch_id, commit_oid).map_err(Into::into)
} }
pub async fn update_commit_message( pub async fn update_commit_message(
@ -413,7 +430,7 @@ impl Controller {
let _ = project_repository let _ = project_repository
.project() .project()
.create_snapshot(SnapshotDetails::new(OperationKind::UpdateCommitMessage)); .create_snapshot(SnapshotDetails::new(OperationKind::UpdateCommitMessage));
super::update_commit_message(&project_repository, branch_id, commit_oid, message) virtual_branches::update_commit_message(&project_repository, branch_id, commit_oid, message)
.map_err(Into::into) .map_err(Into::into)
} }
@ -472,7 +489,8 @@ impl Controller {
let _ = project_repository let _ = project_repository
.project() .project()
.create_snapshot(SnapshotDetails::new(OperationKind::MoveCommit)); .create_snapshot(SnapshotDetails::new(OperationKind::MoveCommit));
super::move_commit(&project_repository, target_branch_id, commit_oid).map_err(Into::into) virtual_branches::move_commit(&project_repository, target_branch_id, commit_oid)
.map_err(Into::into)
} }
async fn permit(&self, ignore: bool) { async fn permit(&self, ignore: bool) {
@ -484,7 +502,7 @@ impl Controller {
fn open_with_verify(project: &Project) -> Result<Repository> { fn open_with_verify(project: &Project) -> Result<Repository> {
let project_repository = Repository::open(project)?; let project_repository = Repository::open(project)?;
super::integration::verify_branch(&project_repository)?; virtual_branches::integration::verify_branch(&project_repository)?;
Ok(project_repository) Ok(project_repository)
} }

View File

@ -0,0 +1,3 @@
//! GitButler internal library containing functionaliry related to branches, i.e. the virtual branches implementation
pub mod controller;
pub use controller::Controller;

View File

@ -0,0 +1 @@
mod virtual_branches;

View File

@ -1,11 +1,12 @@
use std::path::PathBuf; use std::path::PathBuf;
use std::{fs, path, str::FromStr}; use std::{fs, path, str::FromStr};
use gitbutler_branch::Controller;
use gitbutler_core::error::Marker; use gitbutler_core::error::Marker;
use gitbutler_core::{ use gitbutler_core::{
git, git,
projects::{self, Project, ProjectId}, projects::{self, Project, ProjectId},
virtual_branches::{branch, Controller}, virtual_branches::branch,
}; };
use tempfile::TempDir; use tempfile::TempDir;

View File

@ -1,6 +1,6 @@
use gitbutler_core::virtual_branches::{branch, BranchId}; use gitbutler_core::virtual_branches::{branch, BranchId};
use crate::suite::virtual_branches::Test; use super::Test;
#[tokio::test] #[tokio::test]
async fn no_diffs() { async fn no_diffs() {

View File

@ -2,7 +2,7 @@ use std::fs;
use gitbutler_core::virtual_branches::branch; use gitbutler_core::virtual_branches::branch;
use crate::suite::virtual_branches::Test; use super::Test;
#[tokio::test] #[tokio::test]
async fn to_head() { async fn to_head() {

View File

@ -2,7 +2,7 @@ use std::fs;
use gitbutler_core::virtual_branches::{branch, branch::BranchOwnershipClaims}; use gitbutler_core::virtual_branches::{branch, branch::BranchOwnershipClaims};
use crate::suite::virtual_branches::Test; use super::Test;
#[tokio::test] #[tokio::test]
async fn should_unapply_with_commits() { async fn should_unapply_with_commits() {

View File

@ -46,7 +46,7 @@ impl Project {
/// Prepares a snapshot of the current state of the working directory as well as GitButler data. /// Prepares a snapshot of the current state of the working directory as well as GitButler data.
/// Returns a tree hash of the snapshot. The snapshot is not discoverable until it is committed with [`commit_snapshot`](Self::commit_snapshot()) /// Returns a tree hash of the snapshot. The snapshot is not discoverable until it is committed with [`commit_snapshot`](Self::commit_snapshot())
/// If there are files that are untracked and larger than `SNAPSHOT_FILE_LIMIT_BYTES`, they are excluded from snapshot creation and restoring. /// If there are files that are untracked and larger than `SNAPSHOT_FILE_LIMIT_BYTES`, they are excluded from snapshot creation and restoring.
pub(crate) fn prepare_snapshot(&self) -> Result<git2::Oid> { pub fn prepare_snapshot(&self) -> Result<git2::Oid> {
let worktree_dir = self.path.as_path(); let worktree_dir = self.path.as_path();
let repo = git2::Repository::open(worktree_dir)?; let repo = git2::Repository::open(worktree_dir)?;
@ -172,7 +172,7 @@ impl Project {
/// ///
/// Returns `Some(snapshot_commit_id)` if it was created or `None` if nothing changed between the previous oplog /// Returns `Some(snapshot_commit_id)` if it was created or `None` if nothing changed between the previous oplog
/// commit and the current one (after comparing trees). /// commit and the current one (after comparing trees).
pub(crate) fn commit_snapshot( pub fn commit_snapshot(
&self, &self,
snapshot_tree_id: git2::Oid, snapshot_tree_id: git2::Oid,
details: SnapshotDetails, details: SnapshotDetails,

View File

@ -11,7 +11,7 @@ use super::entry::Trailer;
/// Snapshot functionality /// Snapshot functionality
impl Project { impl Project {
pub(crate) fn snapshot_branch_unapplied( pub fn snapshot_branch_unapplied(
&self, &self,
snapshot_tree: git2::Oid, snapshot_tree: git2::Oid,
result: Result<&git2::Branch, &anyhow::Error>, result: Result<&git2::Branch, &anyhow::Error>,
@ -22,7 +22,7 @@ impl Project {
self.commit_snapshot(snapshot_tree, details)?; self.commit_snapshot(snapshot_tree, details)?;
Ok(()) Ok(())
} }
pub(crate) fn snapshot_commit_undo( pub fn snapshot_commit_undo(
&self, &self,
snapshot_tree: git2::Oid, snapshot_tree: git2::Oid,
result: Result<&(), &anyhow::Error>, result: Result<&(), &anyhow::Error>,
@ -34,7 +34,7 @@ impl Project {
self.commit_snapshot(snapshot_tree, details)?; self.commit_snapshot(snapshot_tree, details)?;
Ok(()) Ok(())
} }
pub(crate) fn snapshot_commit_creation( pub fn snapshot_commit_creation(
&self, &self,
snapshot_tree: git2::Oid, snapshot_tree: git2::Oid,
error: Option<&anyhow::Error>, error: Option<&anyhow::Error>,
@ -60,7 +60,7 @@ impl Project {
self.commit_snapshot(snapshot_tree, details)?; self.commit_snapshot(snapshot_tree, details)?;
Ok(()) Ok(())
} }
pub(crate) fn snapshot_branch_creation(&self, branch_name: String) -> anyhow::Result<()> { pub fn snapshot_branch_creation(&self, branch_name: String) -> anyhow::Result<()> {
let details = let details =
SnapshotDetails::new(OperationKind::CreateBranch).with_trailers(vec![Trailer { SnapshotDetails::new(OperationKind::CreateBranch).with_trailers(vec![Trailer {
key: "name".to_string(), key: "name".to_string(),
@ -69,7 +69,7 @@ impl Project {
self.create_snapshot(details)?; self.create_snapshot(details)?;
Ok(()) Ok(())
} }
pub(crate) fn snapshot_branch_deletion(&self, branch_name: String) -> anyhow::Result<()> { pub fn snapshot_branch_deletion(&self, branch_name: String) -> anyhow::Result<()> {
let details = let details =
SnapshotDetails::new(OperationKind::DeleteBranch).with_trailers(vec![Trailer { SnapshotDetails::new(OperationKind::DeleteBranch).with_trailers(vec![Trailer {
key: "name".to_string(), key: "name".to_string(),
@ -79,7 +79,7 @@ impl Project {
self.create_snapshot(details)?; self.create_snapshot(details)?;
Ok(()) Ok(())
} }
pub(crate) fn snapshot_branch_update( pub fn snapshot_branch_update(
&self, &self,
snapshot_tree: git2::Oid, snapshot_tree: git2::Oid,
old_branch: &Branch, old_branch: &Branch,

View File

@ -11,9 +11,6 @@ pub use integration::GITBUTLER_INTEGRATION_REFERENCE;
mod base; mod base;
pub use base::*; pub use base::*;
pub mod controller;
pub use controller::Controller;
mod r#virtual; mod r#virtual;
pub use r#virtual::*; pub use r#virtual::*;

View File

@ -1,6 +1,5 @@
mod suite { mod suite {
mod projects; mod projects;
mod virtual_branches;
} }
mod git; mod git;

View File

@ -48,6 +48,7 @@ tracing-appender = "0.2.3"
tracing-subscriber = "0.3.17" tracing-subscriber = "0.3.17"
gitbutler-core.workspace = true gitbutler-core.workspace = true
gitbutler-watcher.workspace = true gitbutler-watcher.workspace = true
gitbutler-branch.workspace = true
open = "5" open = "5"
[dependencies.tauri] [dependencies.tauri]

View File

@ -135,7 +135,7 @@ fn main() {
let git_credentials_controller = git::credentials::Helper::default(); let git_credentials_controller = git::credentials::Helper::default();
app_handle.manage(git_credentials_controller.clone()); app_handle.manage(git_credentials_controller.clone());
app_handle.manage(gitbutler_core::virtual_branches::controller::Controller::default()); app_handle.manage(gitbutler_branch::controller::Controller::default());
let remotes_controller = gitbutler_core::remotes::controller::Controller::new( let remotes_controller = gitbutler_core::remotes::controller::Controller::new(
projects_controller.clone(), projects_controller.clone(),

View File

@ -1,6 +1,7 @@
pub mod commands { pub mod commands {
use crate::error::Error; use crate::error::Error;
use anyhow::{anyhow, Context}; use anyhow::{anyhow, Context};
use gitbutler_branch::Controller;
use gitbutler_core::{ use gitbutler_core::{
assets, assets,
error::Code, error::Code,
@ -9,7 +10,6 @@ pub mod commands {
types::ReferenceName, types::ReferenceName,
virtual_branches::{ virtual_branches::{
branch::{self, BranchId, BranchOwnershipClaims}, branch::{self, BranchId, BranchOwnershipClaims},
controller::Controller,
BaseBranch, NameConflitResolution, RemoteBranch, RemoteBranchData, RemoteBranchFile, BaseBranch, NameConflitResolution, RemoteBranch, RemoteBranchData, RemoteBranchFile,
VirtualBranches, VirtualBranches,
}, },

View File

@ -3,7 +3,7 @@ use std::sync::Arc;
use anyhow::{Context, Result}; use anyhow::{Context, Result};
use futures::executor::block_on; use futures::executor::block_on;
use gitbutler_core::projects::{self, Project, ProjectId}; use gitbutler_core::projects::{self, Project, ProjectId};
use gitbutler_core::{assets, users, virtual_branches}; use gitbutler_core::{assets, users};
use tauri::{AppHandle, Manager}; use tauri::{AppHandle, Manager};
use tracing::instrument; use tracing::instrument;
@ -76,7 +76,7 @@ pub struct Watchers {
fn handler_from_app(app: &AppHandle) -> anyhow::Result<gitbutler_watcher::Handler> { fn handler_from_app(app: &AppHandle) -> anyhow::Result<gitbutler_watcher::Handler> {
let projects = app.state::<projects::Controller>().inner().clone(); let projects = app.state::<projects::Controller>().inner().clone();
let users = app.state::<users::Controller>().inner().clone(); let users = app.state::<users::Controller>().inner().clone();
let vbranches = app.state::<virtual_branches::Controller>().inner().clone(); let vbranches = app.state::<gitbutler_branch::Controller>().inner().clone();
let assets_proxy = app.state::<assets::Proxy>().inner().clone(); let assets_proxy = app.state::<assets::Proxy>().inner().clone();
Ok(gitbutler_watcher::Handler::new( Ok(gitbutler_watcher::Handler::new(

View File

@ -10,6 +10,7 @@ doctest = false
[dependencies] [dependencies]
gitbutler-core.workspace = true gitbutler-core.workspace = true
gitbutler-branch.workspace = true
thiserror.workspace = true thiserror.workspace = true
anyhow = "1.0.86" anyhow = "1.0.86"
futures = "0.3.30" futures = "0.3.30"

View File

@ -7,7 +7,7 @@ use gitbutler_core::ops::entry::{OperationKind, SnapshotDetails};
use gitbutler_core::projects::ProjectId; use gitbutler_core::projects::ProjectId;
use gitbutler_core::synchronize::sync_with_gitbutler; use gitbutler_core::synchronize::sync_with_gitbutler;
use gitbutler_core::virtual_branches::VirtualBranches; use gitbutler_core::virtual_branches::VirtualBranches;
use gitbutler_core::{assets, git, project_repository, projects, users, virtual_branches}; use gitbutler_core::{assets, git, project_repository, projects, users};
use tracing::instrument; use tracing::instrument;
use super::{events, Change}; use super::{events, Change};
@ -24,7 +24,7 @@ pub struct Handler {
// need extra protection. // need extra protection.
projects: projects::Controller, projects: projects::Controller,
users: users::Controller, users: users::Controller,
vbranch_controller: virtual_branches::Controller, vbranch_controller: gitbutler_branch::Controller,
assets_proxy: assets::Proxy, assets_proxy: assets::Proxy,
/// A function to send events - decoupled from app-handle for testing purposes. /// A function to send events - decoupled from app-handle for testing purposes.
@ -38,7 +38,7 @@ impl Handler {
pub fn new( pub fn new(
projects: projects::Controller, projects: projects::Controller,
users: users::Controller, users: users::Controller,
vbranch_controller: virtual_branches::Controller, vbranch_controller: gitbutler_branch::Controller,
assets_proxy: assets::Proxy, assets_proxy: assets::Proxy,
send_event: impl Fn(Change) -> Result<()> + Send + Sync + 'static, send_event: impl Fn(Change) -> Result<()> + Send + Sync + 'static,
) -> Self { ) -> Self {