Merge pull request #4275 from gitbutlerapp/move-ProjectRepo-into-separate-crate-gitbutler-command-context

move ProjectRepo into separate crate gitbutler-command-context
This commit is contained in:
Kiril Videlov 2024-07-08 13:37:12 +02:00 committed by GitHub
commit a8f1254e4b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
36 changed files with 232 additions and 174 deletions

20
Cargo.lock generated
View File

@ -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,9 +2278,14 @@ dependencies = [
"anyhow",
"bstr",
"git2",
"gitbutler-command-context",
"gitbutler-core",
"gitbutler-git",
"gitbutler-testsupport",
"resolve-path",
"serde_json",
"tempfile",
"thiserror",
"tokio",
"tracing",
]
@ -2281,6 +2297,7 @@ dependencies = [
"anyhow",
"git2",
"gitbutler-branchstate",
"gitbutler-command-context",
"gitbutler-core",
"gitbutler-oplog",
"itertools 0.13.0",
@ -2299,6 +2316,7 @@ dependencies = [
"futures",
"git2",
"gitbutler-branch",
"gitbutler-command-context",
"gitbutler-core",
"gitbutler-oplog",
"gitbutler-repo",
@ -2335,6 +2353,7 @@ dependencies = [
"git2",
"gitbutler-branch",
"gitbutler-branchstate",
"gitbutler-command-context",
"gitbutler-core",
"gitbutler-repo",
"keyring",
@ -2352,6 +2371,7 @@ dependencies = [
"backoff",
"futures",
"gitbutler-branch",
"gitbutler-command-context",
"gitbutler-core",
"gitbutler-notify-debouncer",
"gitbutler-oplog",

View File

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

View File

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

View File

@ -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<u128>,
}
pub fn get_base_branch_data(
project_repository: &project_repository::ProjectRepo,
) -> Result<BaseBranch> {
pub fn get_base_branch_data(project_repository: &ProjectRepo) -> Result<BaseBranch> {
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<BaseBranch> {
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<BaseBranch> {
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<Vec<git2::Branch<'_>>> {
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<BaseBranch> {
let repo = project_repository.repo();

View File

@ -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<P: AsRef<Path>, A: AsRef<[P]>>(
repository: &ProjectRepo,

View File

@ -1,17 +1,13 @@
use anyhow::Result;
use gitbutler_branchstate::{VirtualBranchesAccess, VirtualBranchesHandle};
use gitbutler_core::{
git::{credentials::Helper, 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,
snapshot::Snapshot,
};
use gitbutler_repo::{RepoActions, RepositoryExt};
use gitbutler_repo::{credentials::Helper, RepoActions, RepositoryExt};
use std::{path::Path, sync::Arc};
use tokio::sync::Semaphore;

View File

@ -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<git2::Signature<'a>> {
// what files have been modified.
pub fn get_workspace_head(
vb_state: &VirtualBranchesHandle,
project_repo: &project_repository::ProjectRepo,
project_repo: &ProjectRepo,
) -> Result<git2::Oid> {
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<git2::Oid> {
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),

View File

@ -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<Vec<RemoteBranch>> {
pub fn list_remote_branches(project_repository: &ProjectRepo) -> Result<Vec<RemoteBranch>> {
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<RemoteBranchData> {
let default_target = default_target(&project_repository.project().gb_dir())?;
@ -148,7 +144,7 @@ pub fn branch_to_remote_branch(branch: &git2::Branch) -> Result<Option<RemoteBra
}
pub fn branch_to_remote_branch_data(
project_repository: &project_repository::ProjectRepo,
project_repository: &ProjectRepo,
branch: &git2::Branch,
base: git2::Oid,
) -> Result<Option<RemoteBranchData>> {

View File

@ -1,5 +1,7 @@
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};
use std::borrow::Borrow;
#[cfg(target_family = "unix")]
@ -40,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};
@ -204,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()?;
@ -304,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<String>,
) -> Result<()> {
pub fn reset_files(project_repository: &ProjectRepo, files: &Vec<String>) -> Result<()> {
project_repository.assure_resolved()?;
// for each tree, we need to checkout the entry from the index at that path
@ -334,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<git2::Branch<'_>> {
fn build_real_branch<'l>(
project_repository: &'l project_repository::ProjectRepo,
project_repository: &'l ProjectRepo,
vbranch: &branch::Branch,
name_conflict_resolution: NameConflitResolution,
) -> Result<git2::Branch<'l>> {
@ -390,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<git2::Oid> {
@ -473,7 +471,7 @@ fn find_base_tree<'a>(
}
pub fn list_virtual_branches(
project_repository: &project_repository::ProjectRepo,
project_repository: &ProjectRepo,
) -> Result<(Vec<VirtualBranch>, Vec<diff::FileDiff>)> {
let mut branches: Vec<VirtualBranch> = Vec::new();
@ -654,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<bool> {
fn is_requires_force(project_repository: &ProjectRepo, branch: &branch::Branch) -> Result<bool> {
let upstream = if let Some(upstream) = &branch.upstream {
upstream
} else {
@ -686,7 +681,7 @@ fn is_requires_force(
}
fn list_virtual_commit_files(
project_repository: &project_repository::ProjectRepo,
project_repository: &ProjectRepo,
commit: &git2::Commit,
) -> Result<Vec<VirtualBranchFile>> {
if commit.parent_count() == 0 {
@ -704,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,
@ -742,7 +737,7 @@ fn commit_to_vbranch_commit(
}
pub fn create_virtual_branch(
project_repository: &project_repository::ProjectRepo,
project_repository: &ProjectRepo,
create: &BranchCreateRequest,
) -> Result<branch::Branch> {
let vb_state = project_repository.project().virtual_branches();
@ -866,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)?;
@ -996,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<git2::Oid>,
) -> Result<git2::Oid> {
@ -1008,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,
@ -1062,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<branch::Branch> {
let vb_state = project_repository.project().virtual_branches();
@ -1140,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(());
@ -1331,7 +1323,7 @@ pub type VirtualBranchHunksByPathMap = HashMap<PathBuf, Vec<VirtualBranchHunk>>;
// 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<diff::FileDiff>)> {
let vb_state = project_repository.project().virtual_branches();
@ -1378,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<branch::Branch>,
) -> Result<Vec<(branch::Branch, BranchStatus)>> {
virtual_branches
@ -1481,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<branch::Branch>,
) -> Result<git2::Oid> {
@ -1502,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,
@ -1566,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<branch::Branch>,
@ -1756,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<Item = (PathBuf, Vec<VirtualBranchHunk>)>,
) -> Vec<VirtualBranchFile> {
hunks
@ -1783,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<()> {
@ -1854,7 +1846,7 @@ pub fn reset_branch(
}
fn diffs_into_virtual_files(
project_repository: &project_repository::ProjectRepo,
project_repository: &ProjectRepo,
diffs: BranchStatus,
) -> Vec<VirtualBranchFile> {
let hunks_by_filepath = virtual_hunks_by_git_hunks(&project_repository.project().path, diffs);
@ -1865,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<Item = (impl Borrow<PathBuf>, impl Borrow<Vec<diff::GitHunk>>)>,
) -> Result<git2::Oid> {
@ -1873,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<Item = (impl Borrow<PathBuf>, impl Borrow<Vec<diff::GitHunk>>)>,
) -> Result<git2::Oid> {
@ -1887,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<Item = (impl Borrow<PathBuf>, impl Borrow<Vec<diff::GitHunk>>)>,
) -> Result<git2::Oid> {
@ -2035,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>,
@ -2156,10 +2148,10 @@ pub fn commit(
}
pub fn push(
project_repository: &project_repository::ProjectRepo,
project_repository: &ProjectRepo,
branch_id: BranchId,
with_force: bool,
credentials: &git::credentials::Helper,
credentials: &Helper,
askpass: Option<Option<BranchId>>,
) -> Result<()> {
let vb_state = project_repository.project().virtual_branches();
@ -2223,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<bool> {
@ -2287,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<bool> {
let vb_state = project_repository.project().virtual_branches();
@ -2330,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,
@ -2567,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,
@ -2714,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,
@ -2799,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,
@ -2853,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<()> {
@ -2904,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<()> {
@ -2993,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,
@ -3067,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<()> {
@ -3207,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<BranchId> {
fn apply_branch(
project_repository: &project_repository::ProjectRepo,
branch_id: BranchId,
) -> Result<String> {
fn apply_branch(project_repository: &ProjectRepo, branch_id: BranchId) -> Result<String> {
project_repository.assure_resolved()?;
let repo = project_repository.repo();
@ -3632,7 +3621,7 @@ pub fn apply<S: AsRef<[u8]>>(base_image: S, patch: &Patch<'_, [u8]>) -> Result<B
// are present in a file it will be resolved, meaning it will be removed from the
// conflicts file.
fn update_conflict_markers(
project_repository: &project_repository::ProjectRepo,
project_repository: &ProjectRepo,
files: &HashMap<PathBuf, Vec<GitHunk>>,
) -> Result<()> {
let conflicting_files = conflicts::conflicting_files(project_repository)?;

View File

@ -0,0 +1,12 @@
[package]
name = "gitbutler-command-context"
version = "0.0.0"
edition = "2021"
authors = ["GitButler <gitbutler@gitbutler.com>"]
publish = false
[dependencies]
gitbutler-core.workspace = true
anyhow = "1.0.86"
git2.workspace = true
tracing = "0.1.40"

View File

@ -0,0 +1,2 @@
mod repository;
pub use repository::ProjectRepo;

View File

@ -1,6 +1,6 @@
use anyhow::Result;
use crate::projects;
use gitbutler_core::projects;
pub struct ProjectRepo {
git_repository: git2::Repository,

View File

@ -1,4 +1,3 @@
pub mod credentials;
pub mod diff;
mod reference;

View File

@ -1,5 +1,3 @@
mod config;
mod repository;
pub use config::Config;
pub use repository::ProjectRepo;

View File

@ -2,7 +2,6 @@ mod suite {
mod projects;
}
mod git;
mod keys;
mod lock;
mod types;

View File

@ -14,3 +14,14 @@ tokio = { workspace = true, features = [ "rt-multi-thread", "rt", "macros" ] }
gitbutler-git.workspace = true
tracing = "0.1.40"
tempfile = "3.10"
thiserror.workspace = true
resolve-path = "0.1.0"
gitbutler-command-context.workspace = true
[[test]]
name="repo"
path = "tests/mod.rs"
[dev-dependencies]
gitbutler-testsupport.workspace = true
serde_json = { version = "1.0", features = [ "std", "arbitrary_precision" ] }

View File

@ -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<Option<String>> {
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<bool> {
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<Vec<String>> {
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(())
}

View File

@ -3,9 +3,10 @@ use std::{path::PathBuf, vec};
use anyhow::Context;
use crate::{keys, project_repository, projects};
use gitbutler_command_context::ProjectRepo;
use gitbutler_core::{keys, projects};
use super::Url;
use gitbutler_core::git::Url;
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum SshCredential {
@ -80,7 +81,7 @@ pub enum HelpError {
#[error("no url set for remote")]
NoUrlSet,
#[error("failed to convert url: {0}")]
UrlConvertError(#[from] super::ConvertError),
UrlConvertError(#[from] gitbutler_core::git::ConvertError),
#[error(transparent)]
Git(#[from] git2::Error),
#[error(transparent)]
@ -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<Vec<(git2::Remote, Vec<Credential>)>, HelpError> {
let remote = project_repository.repo().find_remote(remote_name)?;
@ -98,13 +99,13 @@ impl Helper {
.context("failed to parse remote url")?;
// if file, no auth needed.
if remote_url.scheme == super::Scheme::File {
if remote_url.scheme == gitbutler_core::git::Scheme::File {
return Ok(vec![(remote, vec![Credential::Noop])]);
}
match &project_repository.project().preferred_key {
projects::AuthKey::Local { private_key_path } => {
let ssh_remote = if remote_url.scheme == super::Scheme::Ssh {
let ssh_remote = if remote_url.scheme == gitbutler_core::git::Scheme::Ssh {
Ok(remote)
} else {
let ssh_url = remote_url.as_ssh()?;
@ -122,7 +123,7 @@ impl Helper {
)])
}
projects::AuthKey::GitCredentialsHelper => {
let https_remote = if remote_url.scheme == super::Scheme::Https {
let https_remote = if remote_url.scheme == gitbutler_core::git::Scheme::Https {
Ok(remote)
} else {
let url = remote_url.as_https()?;
@ -142,8 +143,8 @@ impl Helper {
}
fn https_flow(
project_repository: &project_repository::ProjectRepo,
remote_url: &super::Url,
project_repository: &ProjectRepo,
remote_url: &gitbutler_core::git::Url,
) -> Result<Vec<HttpsCredential>, HelpError> {
let mut flow = vec![];

View File

@ -8,3 +8,5 @@ pub use commands::RepoCommands;
mod repository_ext;
pub use repository_ext::RepositoryExt;
pub mod credentials;

View File

@ -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<git2::Oid> {

View File

@ -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,22 +12,18 @@ use gitbutler_core::{
virtual_branches::{Branch, BranchId},
};
use gitbutler_core::project_repository::{Config, ProjectRepo};
use gitbutler_core::project_repository::Config;
use crate::RepositoryExt;
use crate::{credentials::Helper, RepositoryExt};
pub trait RepoActions {
fn fetch(
&self,
remote_name: &str,
credentials: &git::credentials::Helper,
askpass: Option<String>,
) -> Result<()>;
fn fetch(&self, remote_name: &str, credentials: &Helper, askpass: Option<String>)
-> Result<()>;
fn push(
&self,
head: &git2::Oid,
branch: &git::RemoteRefname,
with_force: bool,
credentials: &git::credentials::Helper,
credentials: &Helper,
refspec: Option<String>,
askpass_broker: Option<Option<BranchId>>,
) -> Result<()>;
@ -46,7 +43,7 @@ pub trait RepoActions {
fn add_branch_reference(&self, branch: &Branch) -> Result<()>;
fn git_test_push(
&self,
credentials: &git::credentials::Helper,
credentials: &Helper,
remote_name: &str,
branch_name: &str,
askpass: Option<Option<BranchId>>,
@ -56,7 +53,7 @@ pub trait RepoActions {
impl RepoActions for ProjectRepo {
fn git_test_push(
&self,
credentials: &git::credentials::Helper,
credentials: &Helper,
remote_name: &str,
branch_name: &str,
askpass: Option<Option<BranchId>>,
@ -254,7 +251,7 @@ impl RepoActions for ProjectRepo {
head: &git2::Oid,
branch: &git::RemoteRefname,
with_force: bool,
credentials: &git::credentials::Helper,
credentials: &Helper,
refspec: Option<String>,
askpass_broker: Option<Option<BranchId>>,
) -> Result<()> {
@ -357,7 +354,7 @@ impl RepoActions for ProjectRepo {
fn fetch(
&self,
remote_name: &str,
credentials: &git::credentials::Helper,
credentials: &Helper,
askpass: Option<String>,
) -> Result<()> {
let refspec = format!("+refs/heads/*:refs/remotes/{}/*", remote_name);

View File

@ -1,10 +1,9 @@
use std::path::PathBuf;
use std::str;
use gitbutler_core::{
git::credentials::{Credential, Helper, SshCredential},
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};
@ -22,9 +21,9 @@ impl TestCase<'_> {
gitbutler_testsupport::secrets::setup_blackhole_store();
let users = users::Controller::from_path(local_app_data.path());
let user: users::User = serde_json::from_str(if self.with_github_login {
include_str!("../../tests/fixtures/users/with-github.v1")
include_str!("../tests/fixtures/users/with-github.v1")
} else {
include_str!("../../tests/fixtures/users/login-only.v1")
include_str!("../tests/fixtures/users/login-only.v1")
})
.expect("valid v1 sample user");
users.set_user(&user).unwrap();
@ -38,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()

View File

@ -0,0 +1,15 @@
{
"id": 13612,
"name": "Sebastian Thiel",
"given_name": null,
"family_name": null,
"email": "sebastian.thiel@icloud.com",
"picture": "https://avatars.githubusercontent.com/u/63622?v=4",
"locale": null,
"created_at": "2024-03-26T13:17:05Z",
"updated_at": "2024-06-24T15:21:45Z",
"access_token": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee",
"role": null,
"github_access_token": null,
"github_username": null
}

View File

@ -0,0 +1,15 @@
{
"id": 13612,
"name": "Sebastian Thiel",
"given_name": null,
"family_name": null,
"email": "sebastian.thiel@icloud.com",
"picture": "https://avatars.githubusercontent.com/u/63622?v=4",
"locale": null,
"created_at": "2024-03-26T13:17:05Z",
"updated_at": "2024-06-24T15:21:45Z",
"access_token": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee",
"role": null,
"github_access_token": "gho_AAAAAAAAAAAAABBBBBBBBBBBBBBBCCCCCCCC",
"github_username": null
}

View File

@ -13,3 +13,4 @@ git2.workspace = true
gitbutler-core.workspace = true
gitbutler-oplog.workspace = true
gitbutler-branchstate.workspace = true
gitbutler-command-context.workspace = true

View File

@ -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<git2::Oid>,
project_id: Id<projects::Project>,
@ -138,9 +138,7 @@ fn batch_rev_walk(
Ok(oids)
}
fn collect_refs(
project_repository: &project_repository::ProjectRepo,
) -> anyhow::Result<Vec<git::Refname>> {
fn collect_refs(project_repository: &ProjectRepo) -> anyhow::Result<Vec<git::Refname>> {
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<projects::Project>,
) -> 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<bool> {

View File

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

View File

@ -1,11 +1,12 @@
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,
};
use gitbutler_repo::{RepoActions, RepositoryExt};
use gitbutler_repo::{credentials::Helper, RepoActions, RepositoryExt};
#[derive(Clone)]
pub struct App {
@ -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<Vec<git::RemoteRefname>> {
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()
}
@ -36,11 +37,11 @@ impl App {
project_id: ProjectId,
remote_name: &str,
branch_name: &str,
credentials: &git::credentials::Helper,
credentials: &Helper,
askpass: Option<Option<BranchId>>,
) -> 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)
}
@ -48,17 +49,17 @@ impl App {
&self,
project_id: ProjectId,
remote_name: &str,
credentials: &git::credentials::Helper,
credentials: &Helper,
askpass: Option<String>,
) -> 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<usize> {
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<String> {
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()

View File

@ -1,4 +1,5 @@
use gitbutler_core::{git, projects::ProjectId};
use gitbutler_repo::credentials::Helper;
use tauri::Manager;
use tracing::instrument;
@ -25,7 +26,7 @@ pub async fn git_test_push(
branch_name: &str,
) -> Result<(), Error> {
let app = handle.state::<app::App>();
let helper = handle.state::<gitbutler_core::git::credentials::Helper>();
let helper = handle.state::<Helper>();
Ok(app.git_test_push(
project_id,
remote_name,
@ -45,7 +46,7 @@ pub async fn git_test_fetch(
action: Option<String>,
) -> Result<(), Error> {
let app = handle.state::<app::App>();
let helper = handle.state::<gitbutler_core::git::credentials::Helper>();
let helper = handle.state::<Helper>();
Ok(app.git_test_fetch(
project_id,
remote_name,

View File

@ -13,7 +13,8 @@
clippy::too_many_lines
)]
use gitbutler_core::{assets, git, storage};
use gitbutler_core::{assets, storage};
use gitbutler_repo::credentials::Helper;
use gitbutler_tauri::{
app, askpass, commands, config, github, keys, logs, menu, projects, remotes, repo, secret,
undo, users, virtual_branches, watcher, zip,
@ -132,7 +133,7 @@ fn main() {
let keys_controller = gitbutler_core::keys::Controller::new(keys_storage_controller.clone());
app_handle.manage(keys_controller.clone());
let git_credentials_controller = git::credentials::Helper::default();
let git_credentials_controller = Helper::default();
app_handle.manage(git_credentials_controller.clone());
app_handle.manage(gitbutler_branch::controller::Controller::default());

View File

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

View File

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

View File

@ -4,8 +4,9 @@ use std::{
path::{Path, PathBuf},
};
use gitbutler_command_context::ProjectRepo;
use gitbutler_core::project_repository;
use gitbutler_repo::RepositoryExt;
use gitbutler_repo::{credentials::Helper, RepositoryExt};
use tempfile::{tempdir, TempDir};
use crate::{init_opts, init_opts_bare, VAR_NO_CLEANUP};
@ -91,8 +92,8 @@ impl Suite {
pub struct Case {
pub project: gitbutler_core::projects::Project,
pub project_repository: gitbutler_core::project_repository::ProjectRepo,
pub credentials: gitbutler_core::git::credentials::Helper,
pub project_repository: ProjectRepo,
pub credentials: Helper,
/// The directory containing the `project_repository`
project_tmp: Option<TempDir>,
}
@ -111,9 +112,9 @@ 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 credentials = gitbutler_core::git::credentials::Helper::default();
let project_repository =
ProjectRepo::open(&project).expect("failed to create project repository");
let credentials = Helper::default();
Case {
project,
project_repository,
@ -127,9 +128,9 @@ 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 credentials = gitbutler_core::git::credentials::Helper::default();
let project_repository =
ProjectRepo::open(&project).expect("failed to create project repository");
let credentials = Helper::default();
Self {
credentials,
project_repository,

View File

@ -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" }

View File

@ -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;
}