diff --git a/Cargo.lock b/Cargo.lock index 8cb8bf308..03f89b87a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2113,6 +2113,7 @@ dependencies = [ "git2", "git2-hooks", "gitbutler-branchstate", + "gitbutler-command-context", "gitbutler-core", "gitbutler-git", "gitbutler-oplog", @@ -2156,6 +2157,16 @@ dependencies = [ "pager", ] +[[package]] +name = "gitbutler-command-context" +version = "0.0.0" +dependencies = [ + "anyhow", + "git2", + "gitbutler-core", + "tracing", +] + [[package]] name = "gitbutler-core" version = "0.0.0" @@ -2267,6 +2278,7 @@ dependencies = [ "anyhow", "bstr", "git2", + "gitbutler-command-context", "gitbutler-core", "gitbutler-git", "gitbutler-testsupport", @@ -2285,6 +2297,7 @@ dependencies = [ "anyhow", "git2", "gitbutler-branchstate", + "gitbutler-command-context", "gitbutler-core", "gitbutler-oplog", "itertools 0.13.0", @@ -2303,6 +2316,7 @@ dependencies = [ "futures", "git2", "gitbutler-branch", + "gitbutler-command-context", "gitbutler-core", "gitbutler-oplog", "gitbutler-repo", @@ -2339,6 +2353,7 @@ dependencies = [ "git2", "gitbutler-branch", "gitbutler-branchstate", + "gitbutler-command-context", "gitbutler-core", "gitbutler-repo", "keyring", @@ -2356,6 +2371,7 @@ dependencies = [ "backoff", "futures", "gitbutler-branch", + "gitbutler-command-context", "gitbutler-core", "gitbutler-notify-debouncer", "gitbutler-oplog", diff --git a/Cargo.toml b/Cargo.toml index 6ad0b96da..a1e5ed21b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,6 +12,7 @@ members = [ "crates/gitbutler-oplog", "crates/gitbutler-branchstate", "crates/gitbutler-repo", + "crates/gitbutler-command-context", ] resolver = "2" @@ -35,6 +36,7 @@ gitbutler-sync = { path = "crates/gitbutler-sync" } gitbutler-oplog = { path = "crates/gitbutler-oplog" } gitbutler-branchstate = { path = "crates/gitbutler-branchstate" } gitbutler-repo = { path = "crates/gitbutler-repo" } +gitbutler-command-context = { path = "crates/gitbutler-command-context" } [profile.release] codegen-units = 1 # Compile crates one after another so the compiler can optimize better diff --git a/crates/gitbutler-branch/Cargo.toml b/crates/gitbutler-branch/Cargo.toml index 9a3e74f84..5a70cfb61 100644 --- a/crates/gitbutler-branch/Cargo.toml +++ b/crates/gitbutler-branch/Cargo.toml @@ -24,6 +24,7 @@ url = { version = "2.5.2", features = ["serde"] } md5 = "0.7.0" futures = "0.3" itertools = "0.13" +gitbutler-command-context.workspace = true [[test]] name="branches" diff --git a/crates/gitbutler-branch/src/base.rs b/crates/gitbutler-branch/src/base.rs index 253649b2e..c94e2936e 100644 --- a/crates/gitbutler-branch/src/base.rs +++ b/crates/gitbutler-branch/src/base.rs @@ -3,6 +3,7 @@ use std::{path::Path, time}; use anyhow::{anyhow, Context, Result}; use git2::Index; use gitbutler_branchstate::{VirtualBranchesAccess, VirtualBranchesHandle}; +use gitbutler_command_context::ProjectRepo; use gitbutler_repo::{LogUntil, RepoActions, RepositoryExt}; use serde::Serialize; @@ -16,7 +17,6 @@ use gitbutler_core::error::Marker; use gitbutler_core::virtual_branches::{branch, target, BranchId, GITBUTLER_INTEGRATION_REFERENCE}; use gitbutler_core::{ git::{self, diff}, - project_repository, projects::FetchResult, virtual_branches::branch::BranchOwnershipClaims, }; @@ -40,16 +40,14 @@ pub struct BaseBranch { pub last_fetched_ms: Option, } -pub fn get_base_branch_data( - project_repository: &project_repository::ProjectRepo, -) -> Result { +pub fn get_base_branch_data(project_repository: &ProjectRepo) -> Result { let target = default_target(&project_repository.project().gb_dir())?; let base = target_to_base_branch(project_repository, &target)?; Ok(base) } fn go_back_to_integration( - project_repository: &project_repository::ProjectRepo, + project_repository: &ProjectRepo, default_target: &target::Target, ) -> Result { let statuses = project_repository @@ -120,7 +118,7 @@ fn go_back_to_integration( } pub fn set_base_branch( - project_repository: &project_repository::ProjectRepo, + project_repository: &ProjectRepo, target_branch_ref: &git::RemoteRefname, ) -> Result { let repo = project_repository.repo(); @@ -273,7 +271,7 @@ pub fn set_base_branch( } pub fn set_target_push_remote( - project_repository: &project_repository::ProjectRepo, + project_repository: &ProjectRepo, push_remote_name: &str, ) -> Result<()> { let remote = project_repository @@ -294,7 +292,7 @@ pub fn set_target_push_remote( Ok(()) } -fn set_exclude_decoration(project_repository: &project_repository::ProjectRepo) -> Result<()> { +fn set_exclude_decoration(project_repository: &ProjectRepo) -> Result<()> { let repo = project_repository.repo(); let mut config = repo.config()?; config @@ -330,7 +328,7 @@ fn _print_tree(repo: &git2::Repository, tree: &git2::Tree) -> Result<()> { // merge the target branch into our current working directory // update the target sha pub fn update_base_branch( - project_repository: &project_repository::ProjectRepo, + project_repository: &ProjectRepo, ) -> anyhow::Result>> { project_repository.assure_resolved()?; @@ -576,7 +574,7 @@ pub fn update_base_branch( } pub fn target_to_base_branch( - project_repository: &project_repository::ProjectRepo, + project_repository: &ProjectRepo, target: &target::Target, ) -> Result { let repo = project_repository.repo(); diff --git a/crates/gitbutler-branch/src/conflicts.rs b/crates/gitbutler-branch/src/conflicts.rs index 881b4b022..380dc3624 100644 --- a/crates/gitbutler-branch/src/conflicts.rs +++ b/crates/gitbutler-branch/src/conflicts.rs @@ -11,9 +11,10 @@ use std::{ }; use anyhow::{anyhow, Context, Result}; +use gitbutler_command_context::ProjectRepo; use itertools::Itertools; -use gitbutler_core::{error::Marker, project_repository::ProjectRepo}; +use gitbutler_core::error::Marker; pub fn mark, A: AsRef<[P]>>( repository: &ProjectRepo, diff --git a/crates/gitbutler-branch/src/controller.rs b/crates/gitbutler-branch/src/controller.rs index 3d9d805b8..48eadd395 100644 --- a/crates/gitbutler-branch/src/controller.rs +++ b/crates/gitbutler-branch/src/controller.rs @@ -1,8 +1,7 @@ use anyhow::Result; use gitbutler_branchstate::{VirtualBranchesAccess, VirtualBranchesHandle}; -use gitbutler_core::{ - git::BranchExt, project_repository::ProjectRepo, projects::FetchResult, types::ReferenceName, -}; +use gitbutler_command_context::ProjectRepo; +use gitbutler_core::{git::BranchExt, projects::FetchResult, types::ReferenceName}; use gitbutler_oplog::{ entry::{OperationKind, SnapshotDetails}, oplog::Oplog, diff --git a/crates/gitbutler-branch/src/integration.rs b/crates/gitbutler-branch/src/integration.rs index a5db512ce..0270d3b1d 100644 --- a/crates/gitbutler-branch/src/integration.rs +++ b/crates/gitbutler-branch/src/integration.rs @@ -4,14 +4,13 @@ use anyhow::{anyhow, bail, Context, Result}; use bstr::ByteSlice; use gitbutler_branchstate::{VirtualBranchesAccess, VirtualBranchesHandle}; +use gitbutler_command_context::ProjectRepo; use gitbutler_core::error::Marker; use gitbutler_core::virtual_branches::{ GITBUTLER_INTEGRATION_COMMIT_AUTHOR_EMAIL, GITBUTLER_INTEGRATION_COMMIT_AUTHOR_NAME, GITBUTLER_INTEGRATION_REFERENCE, }; -use gitbutler_core::{ - git::CommitExt, project_repository, virtual_branches::branch::BranchCreateRequest, -}; +use gitbutler_core::{git::CommitExt, virtual_branches::branch::BranchCreateRequest}; use gitbutler_repo::{LogUntil, RepoActions, RepositoryExt}; use crate::conflicts; @@ -31,7 +30,7 @@ pub fn get_integration_commiter<'a>() -> Result> { // what files have been modified. pub fn get_workspace_head( vb_state: &VirtualBranchesHandle, - project_repo: &project_repository::ProjectRepo, + project_repo: &ProjectRepo, ) -> Result { let target = vb_state .get_default_target() @@ -139,7 +138,7 @@ fn write_integration_file(head: &git2::Reference, path: PathBuf) -> Result<()> { } pub fn update_gitbutler_integration( vb_state: &VirtualBranchesHandle, - project_repository: &project_repository::ProjectRepo, + project_repository: &ProjectRepo, ) -> Result { let target = vb_state .get_default_target() @@ -289,7 +288,7 @@ pub fn update_gitbutler_integration( Ok(final_commit) } -pub fn verify_branch(project_repository: &project_repository::ProjectRepo) -> Result<()> { +pub fn verify_branch(project_repository: &ProjectRepo) -> Result<()> { project_repository .verify_current_branch_name() .and_then(|me| me.verify_head_is_set()) @@ -304,7 +303,7 @@ pub trait Verify { fn verify_head_is_clean(&self) -> Result<&Self>; } -impl Verify for project_repository::ProjectRepo { +impl Verify for ProjectRepo { fn verify_head_is_set(&self) -> Result<&Self> { match self.repo().head().context("failed to get head")?.name() { Some(refname) if *refname == GITBUTLER_INTEGRATION_REFERENCE.to_string() => Ok(self), diff --git a/crates/gitbutler-branch/src/remote.rs b/crates/gitbutler-branch/src/remote.rs index bcc2f95da..0c9ec5df4 100644 --- a/crates/gitbutler-branch/src/remote.rs +++ b/crates/gitbutler-branch/src/remote.rs @@ -3,14 +3,12 @@ use std::path::Path; use anyhow::{Context, Result}; use bstr::BString; use gitbutler_branchstate::VirtualBranchesHandle; +use gitbutler_command_context::ProjectRepo; use gitbutler_repo::{LogUntil, RepoActions, RepositoryExt}; use serde::Serialize; +use gitbutler_core::git::{self, CommitExt}; use gitbutler_core::virtual_branches::{target, Author}; -use gitbutler_core::{ - git::{self, CommitExt}, - project_repository, -}; // this struct is a mapping to the view `RemoteBranch` type in Typescript // found in src-tauri/src/routes/repo/[project_id]/types.ts @@ -60,9 +58,7 @@ pub struct RemoteCommit { // for legacy purposes, this is still named "remote" branches, but it's actually // a list of all the normal (non-gitbutler) git branches. -pub fn list_remote_branches( - project_repository: &project_repository::ProjectRepo, -) -> Result> { +pub fn list_remote_branches(project_repository: &ProjectRepo) -> Result> { let default_target = default_target(&project_repository.project().gb_dir())?; let mut remote_branches = vec![]; @@ -90,7 +86,7 @@ pub fn list_remote_branches( } pub fn get_branch_data( - project_repository: &project_repository::ProjectRepo, + project_repository: &ProjectRepo, refname: &git::Refname, ) -> Result { let default_target = default_target(&project_repository.project().gb_dir())?; @@ -148,7 +144,7 @@ pub fn branch_to_remote_branch(branch: &git2::Branch) -> Result Result> { diff --git a/crates/gitbutler-branch/src/virtual.rs b/crates/gitbutler-branch/src/virtual.rs index fe5653450..82d747134 100644 --- a/crates/gitbutler-branch/src/virtual.rs +++ b/crates/gitbutler-branch/src/virtual.rs @@ -1,4 +1,5 @@ use gitbutler_branchstate::{VirtualBranchesAccess, VirtualBranchesHandle}; +use gitbutler_command_context::ProjectRepo; use gitbutler_oplog::snapshot::Snapshot; use gitbutler_repo::credentials::Helper; use gitbutler_repo::{LogUntil, RepoActions, RepositoryExt}; @@ -41,7 +42,6 @@ use gitbutler_core::virtual_branches::{ use gitbutler_core::{ dedup::{dedup, dedup_fmt}, git::{self, diff, Refname, RemoteRefname}, - project_repository, }; use gitbutler_repo::rebase::{cherry_rebase, cherry_rebase_group}; @@ -205,7 +205,7 @@ pub enum NameConflitResolution { } pub fn unapply_ownership( - project_repository: &project_repository::ProjectRepo, + project_repository: &ProjectRepo, ownership: &BranchOwnershipClaims, ) -> Result<()> { project_repository.assure_resolved()?; @@ -305,10 +305,7 @@ pub fn unapply_ownership( } // reset a file in the project to the index state -pub fn reset_files( - project_repository: &project_repository::ProjectRepo, - files: &Vec, -) -> Result<()> { +pub fn reset_files(project_repository: &ProjectRepo, files: &Vec) -> Result<()> { project_repository.assure_resolved()?; // for each tree, we need to checkout the entry from the index at that path @@ -335,12 +332,12 @@ pub fn reset_files( // to unapply a branch, we need to write the current tree out, then remove those file changes from the wd pub fn convert_to_real_branch( - project_repository: &project_repository::ProjectRepo, + project_repository: &ProjectRepo, branch_id: BranchId, name_conflict_resolution: NameConflitResolution, ) -> Result> { fn build_real_branch<'l>( - project_repository: &'l project_repository::ProjectRepo, + project_repository: &'l ProjectRepo, vbranch: &branch::Branch, name_conflict_resolution: NameConflitResolution, ) -> Result> { @@ -391,7 +388,7 @@ pub fn convert_to_real_branch( Ok(branch) } fn build_metadata_commit<'l>( - project_repository: &'l project_repository::ProjectRepo, + project_repository: &'l ProjectRepo, vbranch: &branch::Branch, branch: &git2::Branch<'l>, ) -> Result { @@ -474,7 +471,7 @@ fn find_base_tree<'a>( } pub fn list_virtual_branches( - project_repository: &project_repository::ProjectRepo, + project_repository: &ProjectRepo, ) -> Result<(Vec, Vec)> { let mut branches: Vec = Vec::new(); @@ -655,10 +652,7 @@ fn joined(start_a: u32, end_a: u32, start_b: u32, end_b: u32) -> bool { || ((start_b >= start_a && start_b <= end_a) || (end_b >= start_a && end_b <= end_a)) } -fn is_requires_force( - project_repository: &project_repository::ProjectRepo, - branch: &branch::Branch, -) -> Result { +fn is_requires_force(project_repository: &ProjectRepo, branch: &branch::Branch) -> Result { let upstream = if let Some(upstream) = &branch.upstream { upstream } else { @@ -687,7 +681,7 @@ fn is_requires_force( } fn list_virtual_commit_files( - project_repository: &project_repository::ProjectRepo, + project_repository: &ProjectRepo, commit: &git2::Commit, ) -> Result> { if commit.parent_count() == 0 { @@ -705,7 +699,7 @@ fn list_virtual_commit_files( } fn commit_to_vbranch_commit( - repository: &project_repository::ProjectRepo, + repository: &ProjectRepo, branch: &branch::Branch, commit: &git2::Commit, is_integrated: bool, @@ -743,7 +737,7 @@ fn commit_to_vbranch_commit( } pub fn create_virtual_branch( - project_repository: &project_repository::ProjectRepo, + project_repository: &ProjectRepo, create: &BranchCreateRequest, ) -> Result { let vb_state = project_repository.project().virtual_branches(); @@ -867,7 +861,7 @@ pub fn create_virtual_branch( /// end since there will only be one parent commit. /// pub fn integrate_upstream_commits( - project_repository: &project_repository::ProjectRepo, + project_repository: &ProjectRepo, branch_id: BranchId, ) -> Result<()> { conflicts::is_conflicting(project_repository, None)?; @@ -997,7 +991,7 @@ pub fn integrate_upstream_commits( } pub fn integrate_with_rebase( - project_repository: &project_repository::ProjectRepo, + project_repository: &ProjectRepo, branch: &mut Branch, unknown_commits: &mut Vec, ) -> Result { @@ -1009,7 +1003,7 @@ pub fn integrate_with_rebase( } pub fn integrate_with_merge( - project_repository: &project_repository::ProjectRepo, + project_repository: &ProjectRepo, branch: &mut Branch, upstream_commit: &git2::Commit, merge_base: git2::Oid, @@ -1063,7 +1057,7 @@ pub fn integrate_with_merge( } pub fn update_branch( - project_repository: &project_repository::ProjectRepo, + project_repository: &ProjectRepo, branch_update: &branch::BranchUpdateRequest, ) -> Result { let vb_state = project_repository.project().virtual_branches(); @@ -1141,10 +1135,7 @@ pub fn update_branch( Ok(branch) } -pub fn delete_branch( - project_repository: &project_repository::ProjectRepo, - branch_id: BranchId, -) -> Result<()> { +pub fn delete_branch(project_repository: &ProjectRepo, branch_id: BranchId) -> Result<()> { let vb_state = project_repository.project().virtual_branches(); let Some(branch) = vb_state.try_branch(branch_id)? else { return Ok(()); @@ -1332,7 +1323,7 @@ pub type VirtualBranchHunksByPathMap = HashMap>; // list the virtual branches and their file statuses (statusi?) #[allow(clippy::type_complexity)] pub fn get_status_by_branch( - project_repository: &project_repository::ProjectRepo, + project_repository: &ProjectRepo, integration_commit: Option<&git2::Oid>, ) -> Result<(AppliedStatuses, Vec)> { let vb_state = project_repository.project().virtual_branches(); @@ -1379,7 +1370,7 @@ pub fn get_status_by_branch( // // ownerships are not taken into account here, as they are not relevant for non applied branches fn get_non_applied_status( - project_repository: &project_repository::ProjectRepo, + project_repository: &ProjectRepo, virtual_branches: Vec, ) -> Result> { virtual_branches @@ -1482,7 +1473,7 @@ fn new_compute_locks( } fn compute_merge_base( - project_repository: &project_repository::ProjectRepo, + project_repository: &ProjectRepo, target_sha: &git2::Oid, virtual_branches: &Vec, ) -> Result { @@ -1503,7 +1494,7 @@ fn compute_merge_base( } fn compute_locks( - project_repository: &project_repository::ProjectRepo, + project_repository: &ProjectRepo, integration_commit: &git2::Oid, target_sha: &git2::Oid, base_diffs: &BranchStatus, @@ -1567,7 +1558,7 @@ fn compute_locks( // Returns branches and their associated file changes, in addition to a list // of skipped files. fn get_applied_status( - project_repository: &project_repository::ProjectRepo, + project_repository: &ProjectRepo, integration_commit: &git2::Oid, target_sha: &git2::Oid, mut virtual_branches: Vec, @@ -1757,7 +1748,7 @@ fn get_applied_status( /// NOTE: There is no use returning an iterator here as this acts like the final product. fn virtual_hunks_into_virtual_files( - project_repository: &project_repository::ProjectRepo, + project_repository: &ProjectRepo, hunks: impl IntoIterator)>, ) -> Vec { hunks @@ -1784,7 +1775,7 @@ fn virtual_hunks_into_virtual_files( // reset virtual branch to a specific commit pub fn reset_branch( - project_repository: &project_repository::ProjectRepo, + project_repository: &ProjectRepo, branch_id: BranchId, target_commit_id: git2::Oid, ) -> Result<()> { @@ -1855,7 +1846,7 @@ pub fn reset_branch( } fn diffs_into_virtual_files( - project_repository: &project_repository::ProjectRepo, + project_repository: &ProjectRepo, diffs: BranchStatus, ) -> Vec { let hunks_by_filepath = virtual_hunks_by_git_hunks(&project_repository.project().path, diffs); @@ -1866,7 +1857,7 @@ fn diffs_into_virtual_files( // constructs a tree from those changes on top of the target // and writes it as a new tree for storage pub fn write_tree( - project_repository: &project_repository::ProjectRepo, + project_repository: &ProjectRepo, target: &git2::Oid, files: impl IntoIterator, impl Borrow>)>, ) -> Result { @@ -1874,7 +1865,7 @@ pub fn write_tree( } pub fn write_tree_onto_commit( - project_repository: &project_repository::ProjectRepo, + project_repository: &ProjectRepo, commit_oid: git2::Oid, files: impl IntoIterator, impl Borrow>)>, ) -> Result { @@ -1888,7 +1879,7 @@ pub fn write_tree_onto_commit( } pub fn write_tree_onto_tree( - project_repository: &project_repository::ProjectRepo, + project_repository: &ProjectRepo, base_tree: &git2::Tree, files: impl IntoIterator, impl Borrow>)>, ) -> Result { @@ -2036,7 +2027,7 @@ pub fn write_tree_onto_tree( #[allow(clippy::too_many_arguments)] pub fn commit( - project_repository: &project_repository::ProjectRepo, + project_repository: &ProjectRepo, branch_id: BranchId, message: &str, ownership: Option<&branch::BranchOwnershipClaims>, @@ -2157,7 +2148,7 @@ pub fn commit( } pub fn push( - project_repository: &project_repository::ProjectRepo, + project_repository: &ProjectRepo, branch_id: BranchId, with_force: bool, credentials: &Helper, @@ -2224,7 +2215,7 @@ pub fn push( } fn is_commit_integrated( - project_repository: &project_repository::ProjectRepo, + project_repository: &ProjectRepo, target: &target::Target, commit: &git2::Commit, ) -> Result { @@ -2288,7 +2279,7 @@ fn is_commit_integrated( } pub fn is_remote_branch_mergeable( - project_repository: &project_repository::ProjectRepo, + project_repository: &ProjectRepo, branch_name: &git::RemoteRefname, ) -> Result { let vb_state = project_repository.project().virtual_branches(); @@ -2331,7 +2322,7 @@ pub fn is_remote_branch_mergeable( // the changes need to be removed from the "from" commit, everything rebased, // then added to the "to" commit and everything above that rebased again. pub fn move_commit_file( - project_repository: &project_repository::ProjectRepo, + project_repository: &ProjectRepo, branch_id: BranchId, from_commit_id: git2::Oid, to_commit_id: git2::Oid, @@ -2568,7 +2559,7 @@ pub fn move_commit_file( // add the file changes. The branch is then rebased onto the new commit // and the respective branch head is updated pub fn amend( - project_repository: &project_repository::ProjectRepo, + project_repository: &ProjectRepo, branch_id: BranchId, commit_oid: git2::Oid, target_ownership: &BranchOwnershipClaims, @@ -2715,7 +2706,7 @@ pub fn amend( // if the offset is negative, move the commit up one // rewrites the branch head to the new head commit pub fn reorder_commit( - project_repository: &project_repository::ProjectRepo, + project_repository: &ProjectRepo, branch_id: BranchId, commit_oid: git2::Oid, offset: i32, @@ -2800,7 +2791,7 @@ pub fn reorder_commit( // if offset is positive, insert below, if negative, insert above // return the oid of the new head commit of the branch with the inserted blank commit pub fn insert_blank_commit( - project_repository: &project_repository::ProjectRepo, + project_repository: &ProjectRepo, branch_id: BranchId, commit_oid: git2::Oid, offset: i32, @@ -2854,7 +2845,7 @@ pub fn insert_blank_commit( // remove a commit in a branch by rebasing all commits _except_ for it onto it's parent // if successful, it will update the branch head to the new head commit pub fn undo_commit( - project_repository: &project_repository::ProjectRepo, + project_repository: &ProjectRepo, branch_id: BranchId, commit_oid: git2::Oid, ) -> Result<()> { @@ -2905,7 +2896,7 @@ pub fn undo_commit( /// squashes a commit from a virtual branch into its parent. pub fn squash( - project_repository: &project_repository::ProjectRepo, + project_repository: &ProjectRepo, branch_id: BranchId, commit_id: git2::Oid, ) -> Result<()> { @@ -2994,7 +2985,7 @@ pub fn squash( // changes a commit message for commit_oid, rebases everything above it, updates branch head if successful pub fn update_commit_message( - project_repository: &project_repository::ProjectRepo, + project_repository: &ProjectRepo, branch_id: BranchId, commit_id: git2::Oid, message: &str, @@ -3068,7 +3059,7 @@ pub fn update_commit_message( /// moves commit from the branch it's in to the top of the target branch pub fn move_commit( - project_repository: &project_repository::ProjectRepo, + project_repository: &ProjectRepo, target_branch_id: BranchId, commit_id: git2::Oid, ) -> Result<()> { @@ -3208,13 +3199,10 @@ pub fn move_commit( } pub fn create_virtual_branch_from_branch( - project_repository: &project_repository::ProjectRepo, + project_repository: &ProjectRepo, upstream: &git::Refname, ) -> Result { - fn apply_branch( - project_repository: &project_repository::ProjectRepo, - branch_id: BranchId, - ) -> Result { + fn apply_branch(project_repository: &ProjectRepo, branch_id: BranchId) -> Result { project_repository.assure_resolved()?; let repo = project_repository.repo(); @@ -3633,7 +3621,7 @@ pub fn apply>(base_image: S, patch: &Patch<'_, [u8]>) -> Result>, ) -> Result<()> { let conflicting_files = conflicts::conflicting_files(project_repository)?; diff --git a/crates/gitbutler-command-context/Cargo.toml b/crates/gitbutler-command-context/Cargo.toml new file mode 100644 index 000000000..f5e88ed73 --- /dev/null +++ b/crates/gitbutler-command-context/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "gitbutler-command-context" +version = "0.0.0" +edition = "2021" +authors = ["GitButler "] +publish = false + +[dependencies] +gitbutler-core.workspace = true +anyhow = "1.0.86" +git2.workspace = true +tracing = "0.1.40" diff --git a/crates/gitbutler-command-context/src/lib.rs b/crates/gitbutler-command-context/src/lib.rs new file mode 100644 index 000000000..ad16a2ba9 --- /dev/null +++ b/crates/gitbutler-command-context/src/lib.rs @@ -0,0 +1,2 @@ +mod repository; +pub use repository::ProjectRepo; diff --git a/crates/gitbutler-core/src/project_repository/repository.rs b/crates/gitbutler-command-context/src/repository.rs similarity index 98% rename from crates/gitbutler-core/src/project_repository/repository.rs rename to crates/gitbutler-command-context/src/repository.rs index 5076aaa47..b0b85c3b6 100644 --- a/crates/gitbutler-core/src/project_repository/repository.rs +++ b/crates/gitbutler-command-context/src/repository.rs @@ -1,6 +1,6 @@ use anyhow::Result; -use crate::projects; +use gitbutler_core::projects; pub struct ProjectRepo { git_repository: git2::Repository, diff --git a/crates/gitbutler-core/src/project_repository/mod.rs b/crates/gitbutler-core/src/project_repository/mod.rs index 019e0aff7..43fe76c17 100644 --- a/crates/gitbutler-core/src/project_repository/mod.rs +++ b/crates/gitbutler-core/src/project_repository/mod.rs @@ -1,5 +1,3 @@ mod config; -mod repository; pub use config::Config; -pub use repository::ProjectRepo; diff --git a/crates/gitbutler-repo/Cargo.toml b/crates/gitbutler-repo/Cargo.toml index a07ae884b..9e2bc18ee 100644 --- a/crates/gitbutler-repo/Cargo.toml +++ b/crates/gitbutler-repo/Cargo.toml @@ -16,6 +16,7 @@ tracing = "0.1.40" tempfile = "3.10" thiserror.workspace = true resolve-path = "0.1.0" +gitbutler-command-context.workspace = true [[test]] name="repo" diff --git a/crates/gitbutler-repo/src/commands.rs b/crates/gitbutler-repo/src/commands.rs index ca8174110..947a7ef88 100644 --- a/crates/gitbutler-repo/src/commands.rs +++ b/crates/gitbutler-repo/src/commands.rs @@ -1,9 +1,7 @@ use anyhow::Result; use bstr::BString; -use gitbutler_core::{ - project_repository::{self, Config}, - projects::Project, -}; +use gitbutler_command_context::ProjectRepo; +use gitbutler_core::{project_repository::Config, projects::Project}; use crate::RepositoryExt; @@ -17,19 +15,19 @@ pub trait RepoCommands { impl RepoCommands for Project { fn get_local_config(&self, key: &str) -> Result> { - let project_repo = project_repository::ProjectRepo::open(self)?; + let project_repo = ProjectRepo::open(self)?; let config: Config = project_repo.repo().into(); config.get_local(key) } fn set_local_config(&self, key: &str, value: &str) -> Result<()> { - let project_repo = project_repository::ProjectRepo::open(self)?; + let project_repo = ProjectRepo::open(self)?; let config: Config = project_repo.repo().into(); config.set_local(key, value) } fn check_signing_settings(&self) -> Result { - let repo = project_repository::ProjectRepo::open(self)?; + let repo = ProjectRepo::open(self)?; let signed = repo.repo().sign_buffer(&BString::new("test".into()).into()); match signed { Ok(_) => Ok(true), @@ -38,12 +36,12 @@ impl RepoCommands for Project { } fn remotes(&self) -> Result> { - let project_repository = project_repository::ProjectRepo::open(self)?; + let project_repository = ProjectRepo::open(self)?; project_repository.repo().remotes_as_string() } fn add_remote(&self, name: &str, url: &str) -> Result<()> { - let project_repository = project_repository::ProjectRepo::open(self)?; + let project_repository = ProjectRepo::open(self)?; project_repository.repo().remote(name, url)?; Ok(()) } diff --git a/crates/gitbutler-repo/src/credentials.rs b/crates/gitbutler-repo/src/credentials.rs index 6672ddca5..787828d30 100644 --- a/crates/gitbutler-repo/src/credentials.rs +++ b/crates/gitbutler-repo/src/credentials.rs @@ -3,7 +3,8 @@ use std::{path::PathBuf, vec}; use anyhow::Context; -use gitbutler_core::{keys, project_repository, projects}; +use gitbutler_command_context::ProjectRepo; +use gitbutler_core::{keys, projects}; use gitbutler_core::git::Url; @@ -90,7 +91,7 @@ pub enum HelpError { impl Helper { pub fn help<'a>( &'a self, - project_repository: &'a project_repository::ProjectRepo, + project_repository: &'a ProjectRepo, remote_name: &str, ) -> Result)>, HelpError> { let remote = project_repository.repo().find_remote(remote_name)?; @@ -142,7 +143,7 @@ impl Helper { } fn https_flow( - project_repository: &project_repository::ProjectRepo, + project_repository: &ProjectRepo, remote_url: &gitbutler_core::git::Url, ) -> Result, HelpError> { let mut flow = vec![]; diff --git a/crates/gitbutler-repo/src/rebase.rs b/crates/gitbutler-repo/src/rebase.rs index 5a81d269d..0b3cd6cc5 100644 --- a/crates/gitbutler-repo/src/rebase.rs +++ b/crates/gitbutler-repo/src/rebase.rs @@ -1,7 +1,8 @@ use anyhow::{anyhow, Context, Result}; use bstr::ByteSlice; +use gitbutler_command_context::ProjectRepo; use gitbutler_core::git::HasCommitHeaders; -use gitbutler_core::{error::Marker, git::CommitExt, project_repository}; +use gitbutler_core::{error::Marker, git::CommitExt}; use crate::{LogUntil, RepoActions, RepositoryExt}; @@ -9,7 +10,7 @@ use crate::{LogUntil, RepoActions, RepositoryExt}; /// this function takes a commit range and generates a Vector of commit oids /// and then passes them to `cherry_rebase_group` to rebase them onto the target commit pub fn cherry_rebase( - project_repository: &project_repository::ProjectRepo, + project_repository: &ProjectRepo, target_commit_oid: git2::Oid, start_commit_oid: git2::Oid, end_commit_oid: git2::Oid, @@ -33,7 +34,7 @@ pub fn cherry_rebase( /// the difference between this and a libgit2 based rebase is that this will successfully /// rebase empty commits (two commits with identical trees) pub fn cherry_rebase_group( - project_repository: &project_repository::ProjectRepo, + project_repository: &ProjectRepo, target_commit_oid: git2::Oid, ids_to_rebase: &mut [git2::Oid], ) -> Result { diff --git a/crates/gitbutler-repo/src/repository.rs b/crates/gitbutler-repo/src/repository.rs index 49f0bb4b0..13b44b550 100644 --- a/crates/gitbutler-repo/src/repository.rs +++ b/crates/gitbutler-repo/src/repository.rs @@ -2,6 +2,7 @@ use std::str::FromStr; use anyhow::{anyhow, Context, Result}; +use gitbutler_command_context::ProjectRepo; use gitbutler_core::{ askpass, error::Code, @@ -11,7 +12,7 @@ use gitbutler_core::{ virtual_branches::{Branch, BranchId}, }; -use gitbutler_core::project_repository::{Config, ProjectRepo}; +use gitbutler_core::project_repository::Config; use crate::{credentials::Helper, RepositoryExt}; pub trait RepoActions { diff --git a/crates/gitbutler-repo/tests/credentials.rs b/crates/gitbutler-repo/tests/credentials.rs index a695137e3..a59631e70 100644 --- a/crates/gitbutler-repo/tests/credentials.rs +++ b/crates/gitbutler-repo/tests/credentials.rs @@ -1,7 +1,8 @@ use std::path::PathBuf; use std::str; -use gitbutler_core::{project_repository, projects, users}; +use gitbutler_command_context::ProjectRepo; +use gitbutler_core::{projects, users}; use gitbutler_repo::credentials::{Credential, Helper, SshCredential}; use gitbutler_testsupport::{temp_dir, test_repository}; @@ -36,7 +37,7 @@ impl TestCase<'_> { preferred_key: self.preferred_key.clone(), ..Default::default() }; - let project_repository = project_repository::ProjectRepo::open(&project).unwrap(); + let project_repository = ProjectRepo::open(&project).unwrap(); let flow = helper.help(&project_repository, "origin").unwrap(); flow.into_iter() diff --git a/crates/gitbutler-sync/Cargo.toml b/crates/gitbutler-sync/Cargo.toml index 04d5895ab..12f2eb164 100644 --- a/crates/gitbutler-sync/Cargo.toml +++ b/crates/gitbutler-sync/Cargo.toml @@ -13,3 +13,4 @@ git2.workspace = true gitbutler-core.workspace = true gitbutler-oplog.workspace = true gitbutler-branchstate.workspace = true +gitbutler-command-context.workspace = true diff --git a/crates/gitbutler-sync/src/cloud.rs b/crates/gitbutler-sync/src/cloud.rs index 40c31993e..37d39898b 100644 --- a/crates/gitbutler-sync/src/cloud.rs +++ b/crates/gitbutler-sync/src/cloud.rs @@ -4,12 +4,12 @@ use std::time; use anyhow::{anyhow, Context, Result}; use gitbutler_branchstate::VirtualBranchesAccess; +use gitbutler_command_context::ProjectRepo; use gitbutler_core::error::Code; use gitbutler_core::git::Url; use gitbutler_core::id::Id; use gitbutler_core::{ - git::{self}, - project_repository, + git, projects::{self, CodePushState}, users, }; @@ -17,7 +17,7 @@ use gitbutler_oplog::oplog::Oplog; use itertools::Itertools; pub async fn sync_with_gitbutler( - project_repository: &project_repository::ProjectRepo, + project_repository: &ProjectRepo, user: &users::User, projects: &projects::Controller, ) -> Result<()> { @@ -61,7 +61,7 @@ pub async fn sync_with_gitbutler( async fn push_target( projects: &projects::Controller, - project_repository: &project_repository::ProjectRepo, + project_repository: &ProjectRepo, default_target: &gitbutler_core::virtual_branches::target::Target, gb_code_last_commit: Option, project_id: Id, @@ -138,9 +138,7 @@ fn batch_rev_walk( Ok(oids) } -fn collect_refs( - project_repository: &project_repository::ProjectRepo, -) -> anyhow::Result> { +fn collect_refs(project_repository: &ProjectRepo) -> anyhow::Result> { Ok(project_repository .repo() .references_glob("refs/*")? @@ -153,7 +151,7 @@ fn collect_refs( } fn push_all_refs( - project_repository: &project_repository::ProjectRepo, + project_repository: &ProjectRepo, user: &users::User, project_id: Id, ) -> Result<()> { @@ -200,7 +198,7 @@ async fn update_project( } fn push_to_gitbutler_server( - project_repo: &project_repository::ProjectRepo, + project_repo: &ProjectRepo, user: Option<&users::User>, ref_specs: &[&str], ) -> Result { diff --git a/crates/gitbutler-tauri/Cargo.toml b/crates/gitbutler-tauri/Cargo.toml index 5edcff5e8..71bf8b352 100644 --- a/crates/gitbutler-tauri/Cargo.toml +++ b/crates/gitbutler-tauri/Cargo.toml @@ -51,6 +51,7 @@ gitbutler-watcher.workspace = true gitbutler-branch.workspace = true gitbutler-oplog.workspace = true gitbutler-repo.workspace = true +gitbutler-command-context.workspace = true open = "5" [dependencies.tauri] diff --git a/crates/gitbutler-tauri/src/app.rs b/crates/gitbutler-tauri/src/app.rs index aba454c23..80323d451 100644 --- a/crates/gitbutler-tauri/src/app.rs +++ b/crates/gitbutler-tauri/src/app.rs @@ -1,7 +1,8 @@ use anyhow::{Context, Result}; use gitbutler_branch::conflicts; +use gitbutler_command_context::ProjectRepo; use gitbutler_core::{ - git, project_repository, + git, projects::{self, ProjectId}, virtual_branches::BranchId, }; @@ -19,7 +20,7 @@ impl App { pub fn mark_resolved(&self, project_id: ProjectId, path: &str) -> Result<()> { let project = self.projects.get(project_id)?; - let project_repository = project_repository::ProjectRepo::open(&project)?; + let project_repository = ProjectRepo::open(&project)?; // mark file as resolved conflicts::resolve(&project_repository, path)?; Ok(()) @@ -27,7 +28,7 @@ impl App { pub fn git_remote_branches(&self, project_id: ProjectId) -> Result> { let project = self.projects.get(project_id)?; - let project_repository = project_repository::ProjectRepo::open(&project)?; + let project_repository = ProjectRepo::open(&project)?; project_repository.repo().remote_branches() } @@ -40,7 +41,7 @@ impl App { askpass: Option>, ) -> Result<()> { let project = self.projects.get(project_id)?; - let project_repository = project_repository::ProjectRepo::open(&project)?; + let project_repository = ProjectRepo::open(&project)?; project_repository.git_test_push(credentials, remote_name, branch_name, askpass) } @@ -52,13 +53,13 @@ impl App { askpass: Option, ) -> Result<()> { let project = self.projects.get(project_id)?; - let project_repository = project_repository::ProjectRepo::open(&project)?; + let project_repository = ProjectRepo::open(&project)?; project_repository.fetch(remote_name, credentials, askpass) } pub fn git_index_size(&self, project_id: ProjectId) -> Result { let project = self.projects.get(project_id)?; - let project_repository = project_repository::ProjectRepo::open(&project)?; + let project_repository = ProjectRepo::open(&project)?; let size = project_repository .repo() .index() @@ -69,7 +70,7 @@ impl App { pub fn git_head(&self, project_id: ProjectId) -> Result { let project = self.projects.get(project_id)?; - let project_repository = project_repository::ProjectRepo::open(&project)?; + let project_repository = ProjectRepo::open(&project)?; let head = project_repository .repo() .head() diff --git a/crates/gitbutler-testsupport/Cargo.toml b/crates/gitbutler-testsupport/Cargo.toml index e156c60cb..c080590a1 100644 --- a/crates/gitbutler-testsupport/Cargo.toml +++ b/crates/gitbutler-testsupport/Cargo.toml @@ -21,3 +21,4 @@ gitbutler-core = { path = "../gitbutler-core" } gitbutler-branch = { path = "../gitbutler-branch" } gitbutler-repo = { path = "../gitbutler-repo" } gitbutler-branchstate = { path = "../gitbutler-branchstate" } +gitbutler-command-context.workspace = true diff --git a/crates/gitbutler-testsupport/src/lib.rs b/crates/gitbutler-testsupport/src/lib.rs index dbc01102b..72c8736c3 100644 --- a/crates/gitbutler-testsupport/src/lib.rs +++ b/crates/gitbutler-testsupport/src/lib.rs @@ -19,13 +19,12 @@ pub mod paths { pub mod virtual_branches { use gitbutler_branchstate::VirtualBranchesAccess; - use gitbutler_core::{project_repository, virtual_branches}; + use gitbutler_command_context::ProjectRepo; + use gitbutler_core::virtual_branches; use crate::empty_bare_repository; - pub fn set_test_target( - project_repository: &project_repository::ProjectRepo, - ) -> anyhow::Result<()> { + pub fn set_test_target(project_repository: &ProjectRepo) -> anyhow::Result<()> { let vb_state = project_repository.project().virtual_branches(); let (remote_repo, _tmp) = empty_bare_repository(); let mut remote = project_repository diff --git a/crates/gitbutler-testsupport/src/suite.rs b/crates/gitbutler-testsupport/src/suite.rs index 0fa129409..1f2cd26bb 100644 --- a/crates/gitbutler-testsupport/src/suite.rs +++ b/crates/gitbutler-testsupport/src/suite.rs @@ -4,6 +4,7 @@ use std::{ path::{Path, PathBuf}, }; +use gitbutler_command_context::ProjectRepo; use gitbutler_core::project_repository; use gitbutler_repo::{credentials::Helper, RepositoryExt}; use tempfile::{tempdir, TempDir}; @@ -91,7 +92,7 @@ impl Suite { pub struct Case { pub project: gitbutler_core::projects::Project, - pub project_repository: gitbutler_core::project_repository::ProjectRepo, + pub project_repository: ProjectRepo, pub credentials: Helper, /// The directory containing the `project_repository` project_tmp: Option, @@ -111,8 +112,8 @@ impl Drop for Case { impl Case { fn new(project: gitbutler_core::projects::Project, project_tmp: TempDir) -> Case { - let project_repository = gitbutler_core::project_repository::ProjectRepo::open(&project) - .expect("failed to create project repository"); + let project_repository = + ProjectRepo::open(&project).expect("failed to create project repository"); let credentials = Helper::default(); Case { project, @@ -127,8 +128,8 @@ impl Case { .projects .get(self.project.id) .expect("failed to get project"); - let project_repository = gitbutler_core::project_repository::ProjectRepo::open(&project) - .expect("failed to create project repository"); + let project_repository = + ProjectRepo::open(&project).expect("failed to create project repository"); let credentials = Helper::default(); Self { credentials, diff --git a/crates/gitbutler-watcher/Cargo.toml b/crates/gitbutler-watcher/Cargo.toml index ac0906cfe..1048e8883 100644 --- a/crates/gitbutler-watcher/Cargo.toml +++ b/crates/gitbutler-watcher/Cargo.toml @@ -20,6 +20,8 @@ tokio = { workspace = true, features = [ "macros" ] } tokio-util = "0.7.11" tracing = "0.1.40" gix = { workspace = true, features = ["excludes"] } +gitbutler-command-context.workspace = true + backoff = "0.4.0" notify = { version = "6.0.1" } diff --git a/crates/gitbutler-watcher/src/handler.rs b/crates/gitbutler-watcher/src/handler.rs index b09600c56..55287763e 100644 --- a/crates/gitbutler-watcher/src/handler.rs +++ b/crates/gitbutler-watcher/src/handler.rs @@ -3,9 +3,10 @@ use std::sync::Arc; use anyhow::{Context, Result}; use gitbutler_branch::VirtualBranches; +use gitbutler_command_context::ProjectRepo; use gitbutler_core::error::Marker; use gitbutler_core::projects::ProjectId; -use gitbutler_core::{assets, git, project_repository, projects, users}; +use gitbutler_core::{assets, git, projects, users}; use gitbutler_oplog::{ entry::{OperationKind, SnapshotDetails}, oplog::Oplog, @@ -155,7 +156,7 @@ impl Handler { .get(project_id) .context("failed to get project")?; let open_projects_repository = || { - project_repository::ProjectRepo::open(&project.clone()) + ProjectRepo::open(&project.clone()) .context("failed to open project repository for project") }; @@ -211,7 +212,7 @@ impl Handler { if project.is_sync_enabled() && project.has_code_url() { if let Some(user) = self.users.get_user()? { - let repository = project_repository::ProjectRepo::open(&project) + let repository = ProjectRepo::open(&project) .context("failed to open project repository for project")?; return sync_with_gitbutler(&repository, &user, &self.projects).await; }