mirror of
https://github.com/gitbutlerapp/gitbutler.git
synced 2024-09-11 12:25:42 +03:00
Merge pull request #4523 from gitbutlerapp/Boosting-my-contribution-score
Boosting my contribution score
This commit is contained in:
commit
d37dcefdf5
@ -1,6 +1,6 @@
|
||||
use anyhow::Result;
|
||||
use gitbutler_branch::{BranchCreateRequest, BranchId, BranchOwnershipClaims, BranchUpdateRequest};
|
||||
use gitbutler_command_context::ProjectRepository;
|
||||
use gitbutler_command_context::CommandContext;
|
||||
use gitbutler_oplog::{
|
||||
entry::{OperationKind, SnapshotDetails},
|
||||
OplogExt, SnapshotExt,
|
||||
@ -34,21 +34,13 @@ impl VirtualBranchActions {
|
||||
ownership: Option<&BranchOwnershipClaims>,
|
||||
run_hooks: bool,
|
||||
) -> Result<git2::Oid> {
|
||||
let project_repository = open_with_verify(project)?;
|
||||
let ctx = open_with_verify(project)?;
|
||||
let mut guard = project.exclusive_worktree_access();
|
||||
let snapshot_tree = project_repository
|
||||
.project()
|
||||
.prepare_snapshot(guard.read_permission());
|
||||
let result = branch::commit(
|
||||
&project_repository,
|
||||
branch_id,
|
||||
message,
|
||||
ownership,
|
||||
run_hooks,
|
||||
)
|
||||
.map_err(Into::into);
|
||||
let snapshot_tree = ctx.project().prepare_snapshot(guard.read_permission());
|
||||
let result =
|
||||
branch::commit(&ctx, branch_id, message, ownership, run_hooks).map_err(Into::into);
|
||||
let _ = snapshot_tree.and_then(|snapshot_tree| {
|
||||
project_repository.project().snapshot_commit_creation(
|
||||
ctx.project().snapshot_commit_creation(
|
||||
snapshot_tree,
|
||||
result.as_ref().err(),
|
||||
message.to_owned(),
|
||||
@ -64,8 +56,8 @@ impl VirtualBranchActions {
|
||||
project: &Project,
|
||||
branch_name: &RemoteRefname,
|
||||
) -> Result<bool> {
|
||||
let project_repository = ProjectRepository::open(project)?;
|
||||
branch::is_remote_branch_mergeable(&project_repository, branch_name).map_err(Into::into)
|
||||
let ctx = CommandContext::open(project)?;
|
||||
branch::is_remote_branch_mergeable(&ctx, branch_name).map_err(Into::into)
|
||||
}
|
||||
|
||||
pub fn list_virtual_branches(
|
||||
@ -84,9 +76,9 @@ impl VirtualBranchActions {
|
||||
project: &Project,
|
||||
create: &BranchCreateRequest,
|
||||
) -> Result<BranchId> {
|
||||
let project_repository = open_with_verify(project)?;
|
||||
let ctx = open_with_verify(project)?;
|
||||
let mut guard = project.exclusive_worktree_access();
|
||||
let branch_manager = project_repository.branch_manager();
|
||||
let branch_manager = ctx.branch_manager();
|
||||
let branch_id = branch_manager
|
||||
.create_virtual_branch(create, guard.write_permission())?
|
||||
.id;
|
||||
@ -95,8 +87,8 @@ impl VirtualBranchActions {
|
||||
|
||||
#[instrument(skip(project), err(Debug))]
|
||||
pub fn get_base_branch_data(project: &Project) -> Result<BaseBranch> {
|
||||
let project_repository = ProjectRepository::open(project)?;
|
||||
get_base_branch_data(&project_repository)
|
||||
let ctx = CommandContext::open(project)?;
|
||||
get_base_branch_data(&ctx)
|
||||
}
|
||||
|
||||
pub fn list_remote_commit_files(
|
||||
@ -104,9 +96,8 @@ impl VirtualBranchActions {
|
||||
project: &Project,
|
||||
commit_oid: git2::Oid,
|
||||
) -> Result<Vec<RemoteBranchFile>> {
|
||||
let project_repository = ProjectRepository::open(project)?;
|
||||
crate::file::list_remote_commit_files(project_repository.repo(), commit_oid)
|
||||
.map_err(Into::into)
|
||||
let ctx = CommandContext::open(project)?;
|
||||
crate::file::list_remote_commit_files(ctx.repository(), commit_oid).map_err(Into::into)
|
||||
}
|
||||
|
||||
pub fn set_base_branch(
|
||||
@ -114,38 +105,38 @@ impl VirtualBranchActions {
|
||||
project: &Project,
|
||||
target_branch: &RemoteRefname,
|
||||
) -> Result<BaseBranch> {
|
||||
let project_repository = ProjectRepository::open(project)?;
|
||||
let ctx = CommandContext::open(project)?;
|
||||
let mut guard = project.exclusive_worktree_access();
|
||||
let _ = project_repository.project().create_snapshot(
|
||||
let _ = ctx.project().create_snapshot(
|
||||
SnapshotDetails::new(OperationKind::SetBaseBranch),
|
||||
guard.write_permission(),
|
||||
);
|
||||
set_base_branch(&project_repository, target_branch)
|
||||
set_base_branch(&ctx, target_branch)
|
||||
}
|
||||
|
||||
pub fn set_target_push_remote(&self, project: &Project, push_remote: &str) -> Result<()> {
|
||||
let project_repository = ProjectRepository::open(project)?;
|
||||
set_target_push_remote(&project_repository, push_remote)
|
||||
let ctx = CommandContext::open(project)?;
|
||||
set_target_push_remote(&ctx, push_remote)
|
||||
}
|
||||
|
||||
pub fn integrate_upstream_commits(&self, project: &Project, branch_id: BranchId) -> Result<()> {
|
||||
let project_repository = open_with_verify(project)?;
|
||||
let ctx = open_with_verify(project)?;
|
||||
let mut guard = project.exclusive_worktree_access();
|
||||
let _ = project_repository.project().create_snapshot(
|
||||
let _ = ctx.project().create_snapshot(
|
||||
SnapshotDetails::new(OperationKind::MergeUpstream),
|
||||
guard.write_permission(),
|
||||
);
|
||||
branch::integrate_upstream_commits(&project_repository, branch_id).map_err(Into::into)
|
||||
branch::integrate_upstream_commits(&ctx, branch_id).map_err(Into::into)
|
||||
}
|
||||
|
||||
pub fn update_base_branch(&self, project: &Project) -> Result<Vec<ReferenceName>> {
|
||||
let project_repository = open_with_verify(project)?;
|
||||
let ctx = open_with_verify(project)?;
|
||||
let mut guard = project.exclusive_worktree_access();
|
||||
let _ = project_repository.project().create_snapshot(
|
||||
let _ = ctx.project().create_snapshot(
|
||||
SnapshotDetails::new(OperationKind::UpdateWorkspaceBase),
|
||||
guard.write_permission(),
|
||||
);
|
||||
update_base_branch(&project_repository, guard.write_permission()).map_err(Into::into)
|
||||
update_base_branch(&ctx, guard.write_permission()).map_err(Into::into)
|
||||
}
|
||||
|
||||
pub fn update_virtual_branch(
|
||||
@ -153,18 +144,16 @@ impl VirtualBranchActions {
|
||||
project: &Project,
|
||||
branch_update: BranchUpdateRequest,
|
||||
) -> Result<()> {
|
||||
let project_repository = open_with_verify(project)?;
|
||||
let ctx = open_with_verify(project)?;
|
||||
let mut guard = project.exclusive_worktree_access();
|
||||
let snapshot_tree = project_repository
|
||||
.project()
|
||||
.prepare_snapshot(guard.read_permission());
|
||||
let old_branch = project_repository
|
||||
let snapshot_tree = ctx.project().prepare_snapshot(guard.read_permission());
|
||||
let old_branch = ctx
|
||||
.project()
|
||||
.virtual_branches()
|
||||
.get_branch_in_workspace(branch_update.id)?;
|
||||
let result = branch::update_branch(&project_repository, &branch_update);
|
||||
let result = branch::update_branch(&ctx, &branch_update);
|
||||
let _ = snapshot_tree.and_then(|snapshot_tree| {
|
||||
project_repository.project().snapshot_branch_update(
|
||||
ctx.project().snapshot_branch_update(
|
||||
snapshot_tree,
|
||||
&old_branch,
|
||||
&branch_update,
|
||||
@ -181,22 +170,22 @@ impl VirtualBranchActions {
|
||||
project: &Project,
|
||||
branch_updates: Vec<BranchUpdateRequest>,
|
||||
) -> Result<()> {
|
||||
let project_repository = open_with_verify(project)?;
|
||||
let ctx = open_with_verify(project)?;
|
||||
for branch_update in branch_updates {
|
||||
let branch = project_repository
|
||||
let branch = ctx
|
||||
.project()
|
||||
.virtual_branches()
|
||||
.get_branch_in_workspace(branch_update.id)?;
|
||||
if branch_update.order != Some(branch.order) {
|
||||
branch::update_branch(&project_repository, &branch_update)?;
|
||||
branch::update_branch(&ctx, &branch_update)?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn delete_virtual_branch(&self, project: &Project, branch_id: BranchId) -> Result<()> {
|
||||
let project_repository = open_with_verify(project)?;
|
||||
let branch_manager = project_repository.branch_manager();
|
||||
let ctx = open_with_verify(project)?;
|
||||
let branch_manager = ctx.branch_manager();
|
||||
let mut guard = project.exclusive_worktree_access();
|
||||
branch_manager.delete_branch(branch_id, guard.write_permission())
|
||||
}
|
||||
@ -206,24 +195,23 @@ impl VirtualBranchActions {
|
||||
project: &Project,
|
||||
ownership: &BranchOwnershipClaims,
|
||||
) -> Result<()> {
|
||||
let project_repository = open_with_verify(project)?;
|
||||
let ctx = open_with_verify(project)?;
|
||||
let mut guard = project.exclusive_worktree_access();
|
||||
let _ = project_repository.project().create_snapshot(
|
||||
let _ = ctx.project().create_snapshot(
|
||||
SnapshotDetails::new(OperationKind::DiscardHunk),
|
||||
guard.write_permission(),
|
||||
);
|
||||
branch::unapply_ownership(&project_repository, ownership, guard.write_permission())
|
||||
.map_err(Into::into)
|
||||
branch::unapply_ownership(&ctx, ownership, guard.write_permission()).map_err(Into::into)
|
||||
}
|
||||
|
||||
pub fn reset_files(&self, project: &Project, files: &Vec<String>) -> Result<()> {
|
||||
let project_repository = open_with_verify(project)?;
|
||||
let ctx = open_with_verify(project)?;
|
||||
let mut guard = project.exclusive_worktree_access();
|
||||
let _ = project_repository.project().create_snapshot(
|
||||
let _ = ctx.project().create_snapshot(
|
||||
SnapshotDetails::new(OperationKind::DiscardFile),
|
||||
guard.write_permission(),
|
||||
);
|
||||
branch::reset_files(&project_repository, files).map_err(Into::into)
|
||||
branch::reset_files(&ctx, files).map_err(Into::into)
|
||||
}
|
||||
|
||||
pub fn amend(
|
||||
@ -233,13 +221,13 @@ impl VirtualBranchActions {
|
||||
commit_oid: git2::Oid,
|
||||
ownership: &BranchOwnershipClaims,
|
||||
) -> Result<git2::Oid> {
|
||||
let project_repository = open_with_verify(project)?;
|
||||
let ctx = open_with_verify(project)?;
|
||||
let mut guard = project.exclusive_worktree_access();
|
||||
let _ = project_repository.project().create_snapshot(
|
||||
let _ = ctx.project().create_snapshot(
|
||||
SnapshotDetails::new(OperationKind::AmendCommit),
|
||||
guard.write_permission(),
|
||||
);
|
||||
branch::amend(&project_repository, branch_id, commit_oid, ownership)
|
||||
branch::amend(&ctx, branch_id, commit_oid, ownership)
|
||||
}
|
||||
|
||||
pub fn move_commit_file(
|
||||
@ -250,20 +238,14 @@ impl VirtualBranchActions {
|
||||
to_commit_oid: git2::Oid,
|
||||
ownership: &BranchOwnershipClaims,
|
||||
) -> Result<git2::Oid> {
|
||||
let project_repository = open_with_verify(project)?;
|
||||
let ctx = open_with_verify(project)?;
|
||||
let mut guard = project.exclusive_worktree_access();
|
||||
let _ = project_repository.project().create_snapshot(
|
||||
let _ = ctx.project().create_snapshot(
|
||||
SnapshotDetails::new(OperationKind::MoveCommitFile),
|
||||
guard.write_permission(),
|
||||
);
|
||||
branch::move_commit_file(
|
||||
&project_repository,
|
||||
branch_id,
|
||||
from_commit_oid,
|
||||
to_commit_oid,
|
||||
ownership,
|
||||
)
|
||||
.map_err(Into::into)
|
||||
branch::move_commit_file(&ctx, branch_id, from_commit_oid, to_commit_oid, ownership)
|
||||
.map_err(Into::into)
|
||||
}
|
||||
|
||||
pub fn undo_commit(
|
||||
@ -272,15 +254,13 @@ impl VirtualBranchActions {
|
||||
branch_id: BranchId,
|
||||
commit_oid: git2::Oid,
|
||||
) -> Result<()> {
|
||||
let project_repository = open_with_verify(project)?;
|
||||
let ctx = open_with_verify(project)?;
|
||||
let mut guard = project.exclusive_worktree_access();
|
||||
let snapshot_tree = project_repository
|
||||
.project()
|
||||
.prepare_snapshot(guard.read_permission());
|
||||
let snapshot_tree = ctx.project().prepare_snapshot(guard.read_permission());
|
||||
let result: Result<()> =
|
||||
branch::undo_commit(&project_repository, branch_id, commit_oid).map_err(Into::into);
|
||||
branch::undo_commit(&ctx, branch_id, commit_oid).map_err(Into::into);
|
||||
let _ = snapshot_tree.and_then(|snapshot_tree| {
|
||||
project_repository.project().snapshot_commit_undo(
|
||||
ctx.project().snapshot_commit_undo(
|
||||
snapshot_tree,
|
||||
result.as_ref(),
|
||||
commit_oid,
|
||||
@ -297,14 +277,13 @@ impl VirtualBranchActions {
|
||||
commit_oid: git2::Oid,
|
||||
offset: i32,
|
||||
) -> Result<()> {
|
||||
let project_repository = open_with_verify(project)?;
|
||||
let ctx = open_with_verify(project)?;
|
||||
let mut guard = project.exclusive_worktree_access();
|
||||
let _ = project_repository.project().create_snapshot(
|
||||
let _ = ctx.project().create_snapshot(
|
||||
SnapshotDetails::new(OperationKind::InsertBlankCommit),
|
||||
guard.write_permission(),
|
||||
);
|
||||
branch::insert_blank_commit(&project_repository, branch_id, commit_oid, offset)
|
||||
.map_err(Into::into)
|
||||
branch::insert_blank_commit(&ctx, branch_id, commit_oid, offset).map_err(Into::into)
|
||||
}
|
||||
|
||||
pub fn reorder_commit(
|
||||
@ -314,14 +293,13 @@ impl VirtualBranchActions {
|
||||
commit_oid: git2::Oid,
|
||||
offset: i32,
|
||||
) -> Result<()> {
|
||||
let project_repository = open_with_verify(project)?;
|
||||
let ctx = open_with_verify(project)?;
|
||||
let mut guard = project.exclusive_worktree_access();
|
||||
let _ = project_repository.project().create_snapshot(
|
||||
let _ = ctx.project().create_snapshot(
|
||||
SnapshotDetails::new(OperationKind::ReorderCommit),
|
||||
guard.write_permission(),
|
||||
);
|
||||
branch::reorder_commit(&project_repository, branch_id, commit_oid, offset)
|
||||
.map_err(Into::into)
|
||||
branch::reorder_commit(&ctx, branch_id, commit_oid, offset).map_err(Into::into)
|
||||
}
|
||||
|
||||
pub fn reset_virtual_branch(
|
||||
@ -330,13 +308,13 @@ impl VirtualBranchActions {
|
||||
branch_id: BranchId,
|
||||
target_commit_oid: git2::Oid,
|
||||
) -> Result<()> {
|
||||
let project_repository = open_with_verify(project)?;
|
||||
let ctx = open_with_verify(project)?;
|
||||
let mut guard = project.exclusive_worktree_access();
|
||||
let _ = project_repository.project().create_snapshot(
|
||||
let _ = ctx.project().create_snapshot(
|
||||
SnapshotDetails::new(OperationKind::UndoCommit),
|
||||
guard.write_permission(),
|
||||
);
|
||||
branch::reset_branch(&project_repository, branch_id, target_commit_oid).map_err(Into::into)
|
||||
branch::reset_branch(&ctx, branch_id, target_commit_oid).map_err(Into::into)
|
||||
}
|
||||
|
||||
pub fn convert_to_real_branch(
|
||||
@ -344,16 +322,14 @@ impl VirtualBranchActions {
|
||||
project: &Project,
|
||||
branch_id: BranchId,
|
||||
) -> Result<ReferenceName> {
|
||||
let project_repository = open_with_verify(project)?;
|
||||
let ctx = open_with_verify(project)?;
|
||||
let mut guard = project.exclusive_worktree_access();
|
||||
let snapshot_tree = project_repository
|
||||
.project()
|
||||
.prepare_snapshot(guard.read_permission());
|
||||
let branch_manager = project_repository.branch_manager();
|
||||
let snapshot_tree = ctx.project().prepare_snapshot(guard.read_permission());
|
||||
let branch_manager = ctx.branch_manager();
|
||||
let result = branch_manager.convert_to_real_branch(branch_id, guard.write_permission());
|
||||
|
||||
let _ = snapshot_tree.and_then(|snapshot_tree| {
|
||||
project_repository.project().snapshot_branch_unapplied(
|
||||
ctx.project().snapshot_branch_unapplied(
|
||||
snapshot_tree,
|
||||
result.as_ref(),
|
||||
guard.write_permission(),
|
||||
@ -371,13 +347,13 @@ impl VirtualBranchActions {
|
||||
askpass: Option<Option<BranchId>>,
|
||||
) -> Result<()> {
|
||||
let helper = Helper::default();
|
||||
let project_repository = open_with_verify(project)?;
|
||||
branch::push(&project_repository, branch_id, with_force, &helper, askpass)
|
||||
let ctx = open_with_verify(project)?;
|
||||
branch::push(&ctx, branch_id, with_force, &helper, askpass)
|
||||
}
|
||||
|
||||
pub fn list_remote_branches(project: Project) -> Result<Vec<RemoteBranch>> {
|
||||
let project_repository = ProjectRepository::open(&project)?;
|
||||
list_remote_branches(&project_repository)
|
||||
let ctx = CommandContext::open(&project)?;
|
||||
list_remote_branches(&ctx)
|
||||
}
|
||||
|
||||
pub fn get_remote_branch_data(
|
||||
@ -385,8 +361,8 @@ impl VirtualBranchActions {
|
||||
project: &Project,
|
||||
refname: &Refname,
|
||||
) -> Result<RemoteBranchData> {
|
||||
let project_repository = ProjectRepository::open(project)?;
|
||||
get_branch_data(&project_repository, refname)
|
||||
let ctx = CommandContext::open(project)?;
|
||||
get_branch_data(&ctx, refname)
|
||||
}
|
||||
|
||||
pub fn squash(
|
||||
@ -395,13 +371,13 @@ impl VirtualBranchActions {
|
||||
branch_id: BranchId,
|
||||
commit_oid: git2::Oid,
|
||||
) -> Result<()> {
|
||||
let project_repository = open_with_verify(project)?;
|
||||
let ctx = open_with_verify(project)?;
|
||||
let mut guard = project.exclusive_worktree_access();
|
||||
let _ = project_repository.project().create_snapshot(
|
||||
let _ = ctx.project().create_snapshot(
|
||||
SnapshotDetails::new(OperationKind::SquashCommit),
|
||||
guard.write_permission(),
|
||||
);
|
||||
branch::squash(&project_repository, branch_id, commit_oid).map_err(Into::into)
|
||||
branch::squash(&ctx, branch_id, commit_oid).map_err(Into::into)
|
||||
}
|
||||
|
||||
pub fn update_commit_message(
|
||||
@ -411,14 +387,13 @@ impl VirtualBranchActions {
|
||||
commit_oid: git2::Oid,
|
||||
message: &str,
|
||||
) -> Result<()> {
|
||||
let project_repository = open_with_verify(project)?;
|
||||
let ctx = open_with_verify(project)?;
|
||||
let mut guard = project.exclusive_worktree_access();
|
||||
let _ = project_repository.project().create_snapshot(
|
||||
let _ = ctx.project().create_snapshot(
|
||||
SnapshotDetails::new(OperationKind::UpdateCommitMessage),
|
||||
guard.write_permission(),
|
||||
);
|
||||
branch::update_commit_message(&project_repository, branch_id, commit_oid, message)
|
||||
.map_err(Into::into)
|
||||
branch::update_commit_message(&ctx, branch_id, commit_oid, message).map_err(Into::into)
|
||||
}
|
||||
|
||||
pub fn fetch_from_remotes(
|
||||
@ -426,15 +401,14 @@ impl VirtualBranchActions {
|
||||
project: &Project,
|
||||
askpass: Option<String>,
|
||||
) -> Result<FetchResult> {
|
||||
let project_repository = ProjectRepository::open(project)?;
|
||||
let ctx = CommandContext::open(project)?;
|
||||
|
||||
let helper = Helper::default();
|
||||
let remotes = project_repository.repo().remotes_as_string()?;
|
||||
let remotes = ctx.repository().remotes_as_string()?;
|
||||
let fetch_errors: Vec<_> = remotes
|
||||
.iter()
|
||||
.filter_map(|remote| {
|
||||
project_repository
|
||||
.fetch(remote, &helper, askpass.clone())
|
||||
ctx.fetch(remote, &helper, askpass.clone())
|
||||
.err()
|
||||
.map(|err| err.to_string())
|
||||
})
|
||||
@ -459,13 +433,13 @@ impl VirtualBranchActions {
|
||||
target_branch_id: BranchId,
|
||||
commit_oid: git2::Oid,
|
||||
) -> Result<()> {
|
||||
let project_repository = open_with_verify(project)?;
|
||||
let ctx = open_with_verify(project)?;
|
||||
let mut guard = project.exclusive_worktree_access();
|
||||
let _ = project_repository.project().create_snapshot(
|
||||
let _ = ctx.project().create_snapshot(
|
||||
SnapshotDetails::new(OperationKind::MoveCommit),
|
||||
guard.write_permission(),
|
||||
);
|
||||
branch::move_commit(&project_repository, target_branch_id, commit_oid).map_err(Into::into)
|
||||
branch::move_commit(&ctx, target_branch_id, commit_oid).map_err(Into::into)
|
||||
}
|
||||
|
||||
pub fn create_virtual_branch_from_branch(
|
||||
@ -474,8 +448,8 @@ impl VirtualBranchActions {
|
||||
branch: &Refname,
|
||||
remote: Option<RemoteRefname>,
|
||||
) -> Result<BranchId> {
|
||||
let project_repository = open_with_verify(project)?;
|
||||
let branch_manager = project_repository.branch_manager();
|
||||
let ctx = open_with_verify(project)?;
|
||||
let branch_manager = ctx.branch_manager();
|
||||
let mut guard = project.exclusive_worktree_access();
|
||||
branch_manager
|
||||
.create_virtual_branch_from_branch(branch, remote, guard.write_permission())
|
||||
@ -483,9 +457,9 @@ impl VirtualBranchActions {
|
||||
}
|
||||
}
|
||||
|
||||
fn open_with_verify(project: &Project) -> Result<ProjectRepository> {
|
||||
let project_repository = ProjectRepository::open(project)?;
|
||||
fn open_with_verify(project: &Project) -> Result<CommandContext> {
|
||||
let ctx = CommandContext::open(project)?;
|
||||
let mut guard = project.exclusive_worktree_access();
|
||||
crate::integration::verify_branch(&project_repository, guard.write_permission())?;
|
||||
Ok(project_repository)
|
||||
crate::integration::verify_branch(&ctx, guard.write_permission())?;
|
||||
Ok(ctx)
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ use gitbutler_branch::{
|
||||
self, Branch, BranchId, BranchOwnershipClaims, Target, VirtualBranchesHandle,
|
||||
GITBUTLER_INTEGRATION_REFERENCE,
|
||||
};
|
||||
use gitbutler_command_context::ProjectRepository;
|
||||
use gitbutler_command_context::CommandContext;
|
||||
use gitbutler_error::error::Marker;
|
||||
use gitbutler_project::{access::WorktreeWritePermission, FetchResult};
|
||||
use gitbutler_reference::{ReferenceName, Refname, RemoteRefname};
|
||||
@ -41,18 +41,15 @@ pub struct BaseBranch {
|
||||
pub last_fetched_ms: Option<u128>,
|
||||
}
|
||||
|
||||
pub(crate) fn get_base_branch_data(project_repository: &ProjectRepository) -> Result<BaseBranch> {
|
||||
let target = default_target(&project_repository.project().gb_dir())?;
|
||||
let base = target_to_base_branch(project_repository, &target)?;
|
||||
pub(crate) fn get_base_branch_data(ctx: &CommandContext) -> Result<BaseBranch> {
|
||||
let target = default_target(&ctx.project().gb_dir())?;
|
||||
let base = target_to_base_branch(ctx, &target)?;
|
||||
Ok(base)
|
||||
}
|
||||
|
||||
fn go_back_to_integration(
|
||||
project_repository: &ProjectRepository,
|
||||
default_target: &Target,
|
||||
) -> Result<BaseBranch> {
|
||||
let statuses = project_repository
|
||||
.repo()
|
||||
fn go_back_to_integration(ctx: &CommandContext, default_target: &Target) -> Result<BaseBranch> {
|
||||
let statuses = ctx
|
||||
.repository()
|
||||
.statuses(Some(
|
||||
git2::StatusOptions::new()
|
||||
.show(git2::StatusShow::IndexAndWorkdir)
|
||||
@ -63,13 +60,13 @@ fn go_back_to_integration(
|
||||
return Err(anyhow!("current HEAD is dirty")).context(Marker::ProjectConflict);
|
||||
}
|
||||
|
||||
let vb_state = project_repository.project().virtual_branches();
|
||||
let vb_state = ctx.project().virtual_branches();
|
||||
let virtual_branches = vb_state
|
||||
.list_branches_in_workspace()
|
||||
.context("failed to read virtual branches")?;
|
||||
|
||||
let target_commit = project_repository
|
||||
.repo()
|
||||
let target_commit = ctx
|
||||
.repository()
|
||||
.find_commit(default_target.sha)
|
||||
.context("failed to find target commit")?;
|
||||
|
||||
@ -81,48 +78,47 @@ fn go_back_to_integration(
|
||||
.context("failed to get base tree from commit")?;
|
||||
for branch in &virtual_branches {
|
||||
// merge this branches tree with our tree
|
||||
let branch_head = project_repository
|
||||
.repo()
|
||||
let branch_head = ctx
|
||||
.repository()
|
||||
.find_commit(branch.head)
|
||||
.context("failed to find branch head")?;
|
||||
let branch_tree = branch_head
|
||||
.tree()
|
||||
.context("failed to get branch head tree")?;
|
||||
let mut result = project_repository
|
||||
.repo()
|
||||
let mut result = ctx
|
||||
.repository()
|
||||
.merge_trees(&base_tree, &final_tree, &branch_tree, None)
|
||||
.context("failed to merge")?;
|
||||
let final_tree_oid = result
|
||||
.write_tree_to(project_repository.repo())
|
||||
.write_tree_to(ctx.repository())
|
||||
.context("failed to write tree")?;
|
||||
final_tree = project_repository
|
||||
.repo()
|
||||
final_tree = ctx
|
||||
.repository()
|
||||
.find_tree(final_tree_oid)
|
||||
.context("failed to find written tree")?;
|
||||
}
|
||||
|
||||
project_repository
|
||||
.repo()
|
||||
ctx.repository()
|
||||
.checkout_tree_builder(&final_tree)
|
||||
.force()
|
||||
.checkout()
|
||||
.context("failed to checkout tree")?;
|
||||
|
||||
let base = target_to_base_branch(project_repository, default_target)?;
|
||||
update_gitbutler_integration(&vb_state, project_repository)?;
|
||||
let base = target_to_base_branch(ctx, default_target)?;
|
||||
update_gitbutler_integration(&vb_state, ctx)?;
|
||||
Ok(base)
|
||||
}
|
||||
|
||||
pub(crate) fn set_base_branch(
|
||||
project_repository: &ProjectRepository,
|
||||
ctx: &CommandContext,
|
||||
target_branch_ref: &RemoteRefname,
|
||||
) -> Result<BaseBranch> {
|
||||
let repo = project_repository.repo();
|
||||
let repo = ctx.repository();
|
||||
|
||||
// if target exists, and it is the same as the requested branch, we should go back
|
||||
if let Ok(target) = default_target(&project_repository.project().gb_dir()) {
|
||||
if let Ok(target) = default_target(&ctx.project().gb_dir()) {
|
||||
if target.branch.eq(target_branch_ref) {
|
||||
return go_back_to_integration(project_repository, &target);
|
||||
return go_back_to_integration(ctx, &target);
|
||||
}
|
||||
}
|
||||
|
||||
@ -154,7 +150,7 @@ pub(crate) fn set_base_branch(
|
||||
.peel_to_commit()
|
||||
.context("Failed to peel HEAD reference to commit")?;
|
||||
|
||||
// calculate the commit as the merge-base between HEAD in project_repository and this target commit
|
||||
// calculate the commit as the merge-base between HEAD in ctx and this target commit
|
||||
let target_commit_oid = repo
|
||||
.merge_base(current_head_commit.id(), target_branch_head.id())
|
||||
.context(format!(
|
||||
@ -170,7 +166,7 @@ pub(crate) fn set_base_branch(
|
||||
push_remote_name: None,
|
||||
};
|
||||
|
||||
let vb_state = project_repository.project().virtual_branches();
|
||||
let vb_state = ctx.project().virtual_branches();
|
||||
vb_state.set_default_target(target.clone())?;
|
||||
|
||||
// TODO: make sure this is a real branch
|
||||
@ -244,14 +240,14 @@ pub(crate) fn set_base_branch(
|
||||
updated_timestamp_ms: now_ms,
|
||||
head: current_head_commit.id(),
|
||||
tree: gitbutler_diff::write::hunks_onto_commit(
|
||||
project_repository,
|
||||
ctx,
|
||||
current_head_commit.id(),
|
||||
gitbutler_diff::diff_files_into_hunks(wd_diff),
|
||||
)?,
|
||||
ownership,
|
||||
order: 0,
|
||||
selected_for_changes: None,
|
||||
allow_rebasing: project_repository.project().ok_with_force_push.into(),
|
||||
allow_rebasing: ctx.project().ok_with_force_push.into(),
|
||||
applied: true,
|
||||
in_workspace: true,
|
||||
not_in_workspace_wip_change_id: None,
|
||||
@ -261,38 +257,35 @@ pub(crate) fn set_base_branch(
|
||||
}
|
||||
}
|
||||
|
||||
set_exclude_decoration(project_repository)?;
|
||||
set_exclude_decoration(ctx)?;
|
||||
|
||||
update_gitbutler_integration(&vb_state, project_repository)?;
|
||||
update_gitbutler_integration(&vb_state, ctx)?;
|
||||
|
||||
let base = target_to_base_branch(project_repository, &target)?;
|
||||
let base = target_to_base_branch(ctx, &target)?;
|
||||
Ok(base)
|
||||
}
|
||||
|
||||
pub(crate) fn set_target_push_remote(
|
||||
project_repository: &ProjectRepository,
|
||||
push_remote_name: &str,
|
||||
) -> Result<()> {
|
||||
let remote = project_repository
|
||||
.repo()
|
||||
pub(crate) fn set_target_push_remote(ctx: &CommandContext, push_remote_name: &str) -> Result<()> {
|
||||
let remote = ctx
|
||||
.repository()
|
||||
.find_remote(push_remote_name)
|
||||
.context(format!("failed to find remote {}", push_remote_name))?;
|
||||
|
||||
// if target exists, and it is the same as the requested branch, we should go back
|
||||
let mut target = default_target(&project_repository.project().gb_dir())?;
|
||||
let mut target = default_target(&ctx.project().gb_dir())?;
|
||||
target.push_remote_name = remote
|
||||
.name()
|
||||
.context("failed to get remote name")?
|
||||
.to_string()
|
||||
.into();
|
||||
let vb_state = project_repository.project().virtual_branches();
|
||||
let vb_state = ctx.project().virtual_branches();
|
||||
vb_state.set_default_target(target)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn set_exclude_decoration(project_repository: &ProjectRepository) -> Result<()> {
|
||||
let repo = project_repository.repo();
|
||||
fn set_exclude_decoration(ctx: &CommandContext) -> Result<()> {
|
||||
let repo = ctx.repository();
|
||||
let mut config = repo.config()?;
|
||||
config
|
||||
.set_multivar("log.excludeDecoration", "refs/gitbutler", "refs/gitbutler")
|
||||
@ -327,14 +320,14 @@ fn _print_tree(repo: &git2::Repository, tree: &git2::Tree) -> Result<()> {
|
||||
// merge the target branch into our current working directory
|
||||
// update the target sha
|
||||
pub(crate) fn update_base_branch(
|
||||
project_repository: &ProjectRepository,
|
||||
ctx: &CommandContext,
|
||||
perm: &mut WorktreeWritePermission,
|
||||
) -> anyhow::Result<Vec<ReferenceName>> {
|
||||
project_repository.assure_resolved()?;
|
||||
ctx.assure_resolved()?;
|
||||
|
||||
// look up the target and see if there is a new oid
|
||||
let target = default_target(&project_repository.project().gb_dir())?;
|
||||
let repo = project_repository.repo();
|
||||
let target = default_target(&ctx.project().gb_dir())?;
|
||||
let repo = ctx.repository();
|
||||
let target_branch = repo
|
||||
.find_branch_by_refname(&target.branch.clone().into())
|
||||
.context(format!("failed to find branch {}", target.branch))?;
|
||||
@ -360,10 +353,10 @@ pub(crate) fn update_base_branch(
|
||||
target.sha
|
||||
))?;
|
||||
|
||||
let vb_state = project_repository.project().virtual_branches();
|
||||
let vb_state = ctx.project().virtual_branches();
|
||||
|
||||
// try to update every branch
|
||||
let updated_vbranches = get_applied_status(project_repository, None)?
|
||||
let updated_vbranches = get_applied_status(ctx, None)?
|
||||
.branches
|
||||
.into_iter()
|
||||
.map(|(branch, _)| branch)
|
||||
@ -390,16 +383,13 @@ pub(crate) fn update_base_branch(
|
||||
branch.upstream = None;
|
||||
branch.upstream_head = None;
|
||||
|
||||
let non_commited_files = gitbutler_diff::trees(
|
||||
project_repository.repo(),
|
||||
&branch_head_tree,
|
||||
&branch_tree,
|
||||
)?;
|
||||
let non_commited_files =
|
||||
gitbutler_diff::trees(ctx.repository(), &branch_head_tree, &branch_tree)?;
|
||||
if non_commited_files.is_empty() {
|
||||
// if there are no commited files, then the branch is fully merged
|
||||
// and we can delete it.
|
||||
vb_state.mark_as_not_in_workspace(branch.id)?;
|
||||
project_repository.delete_branch_reference(&branch)?;
|
||||
ctx.delete_branch_reference(&branch)?;
|
||||
Ok(None)
|
||||
} else {
|
||||
vb_state.set_branch(branch.clone())?;
|
||||
@ -418,7 +408,7 @@ pub(crate) fn update_base_branch(
|
||||
|
||||
if branch_tree_merge_index.has_conflicts() {
|
||||
// branch tree conflicts with new target, unapply branch for now. we'll handle it later, when user applies it back.
|
||||
let branch_manager = project_repository.branch_manager();
|
||||
let branch_manager = ctx.branch_manager();
|
||||
let unapplied_real_branch =
|
||||
branch_manager.convert_to_real_branch(branch.id, perm)?;
|
||||
|
||||
@ -428,7 +418,7 @@ pub(crate) fn update_base_branch(
|
||||
}
|
||||
|
||||
let branch_merge_index_tree_oid =
|
||||
branch_tree_merge_index.write_tree_to(project_repository.repo())?;
|
||||
branch_tree_merge_index.write_tree_to(ctx.repository())?;
|
||||
|
||||
if branch_merge_index_tree_oid == new_target_tree.id() {
|
||||
return result_integrated_detected(branch);
|
||||
@ -452,7 +442,7 @@ pub(crate) fn update_base_branch(
|
||||
if branch_head_merge_index.has_conflicts() {
|
||||
// branch commits conflict with new target, make sure the branch is
|
||||
// unapplied. conflicts witll be dealt with when applying it back.
|
||||
let branch_manager = project_repository.branch_manager();
|
||||
let branch_manager = ctx.branch_manager();
|
||||
let unapplied_real_branch =
|
||||
branch_manager.convert_to_real_branch(branch.id, perm)?;
|
||||
unapplied_branch_names.push(unapplied_real_branch);
|
||||
@ -462,7 +452,7 @@ pub(crate) fn update_base_branch(
|
||||
|
||||
// branch commits do not conflict with new target, so lets merge them
|
||||
let branch_head_merge_tree_oid = branch_head_merge_index
|
||||
.write_tree_to(project_repository.repo())
|
||||
.write_tree_to(ctx.repository())
|
||||
.context(format!(
|
||||
"failed to write head merge index for {}",
|
||||
branch.id
|
||||
@ -477,7 +467,7 @@ pub(crate) fn update_base_branch(
|
||||
.find_tree(branch_head_merge_tree_oid)
|
||||
.context("failed to find tree")?;
|
||||
|
||||
let new_target_head = project_repository
|
||||
let new_target_head = ctx
|
||||
.commit(
|
||||
format!(
|
||||
"Merged {}/{} into {}",
|
||||
@ -504,7 +494,7 @@ pub(crate) fn update_base_branch(
|
||||
|
||||
// branch was not pushed to upstream yet. attempt a rebase,
|
||||
let rebased_head_oid = cherry_rebase(
|
||||
project_repository,
|
||||
ctx,
|
||||
new_target_commit.id(),
|
||||
new_target_commit.id(),
|
||||
branch.head,
|
||||
@ -558,15 +548,12 @@ pub(crate) fn update_base_branch(
|
||||
})?;
|
||||
|
||||
// Rewriting the integration commit is necessary after changing target sha.
|
||||
crate::integration::update_gitbutler_integration(&vb_state, project_repository)?;
|
||||
crate::integration::update_gitbutler_integration(&vb_state, ctx)?;
|
||||
Ok(unapplied_branch_names)
|
||||
}
|
||||
|
||||
pub(crate) fn target_to_base_branch(
|
||||
project_repository: &ProjectRepository,
|
||||
target: &Target,
|
||||
) -> Result<BaseBranch> {
|
||||
let repo = project_repository.repo();
|
||||
pub(crate) fn target_to_base_branch(ctx: &CommandContext, target: &Target) -> Result<BaseBranch> {
|
||||
let repo = ctx.repository();
|
||||
let branch = repo
|
||||
.find_branch_by_refname(&target.branch.clone().into())?
|
||||
.ok_or(anyhow!("failed to get branch"))?;
|
||||
@ -574,7 +561,7 @@ pub(crate) fn target_to_base_branch(
|
||||
let oid = commit.id();
|
||||
|
||||
// gather a list of commits between oid and target.sha
|
||||
let upstream_commits = project_repository
|
||||
let upstream_commits = ctx
|
||||
.log(oid, LogUntil::Commit(target.sha))
|
||||
.context("failed to get upstream commits")?
|
||||
.iter()
|
||||
@ -582,7 +569,7 @@ pub(crate) fn target_to_base_branch(
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
// get some recent commits
|
||||
let recent_commits = project_repository
|
||||
let recent_commits = ctx
|
||||
.log(target.sha, LogUntil::Take(20))
|
||||
.context("failed to get recent commits")?
|
||||
.iter()
|
||||
@ -612,7 +599,7 @@ pub(crate) fn target_to_base_branch(
|
||||
behind: upstream_commits.len(),
|
||||
upstream_commits,
|
||||
recent_commits,
|
||||
last_fetched_ms: project_repository
|
||||
last_fetched_ms: ctx
|
||||
.project()
|
||||
.project_data_last_fetch
|
||||
.as_ref()
|
||||
|
@ -9,7 +9,7 @@ use bstr::{BString, ByteSlice};
|
||||
use gitbutler_branch::{
|
||||
Branch as GitButlerBranch, BranchId, ReferenceExt, Target, VirtualBranchesHandle,
|
||||
};
|
||||
use gitbutler_command_context::ProjectRepository;
|
||||
use gitbutler_command_context::CommandContext;
|
||||
use gitbutler_reference::normalize_branch_name;
|
||||
use gitbutler_repo::RepoActionsExt;
|
||||
use itertools::Itertools;
|
||||
@ -19,7 +19,7 @@ use crate::VirtualBranchesExt;
|
||||
|
||||
/// Returns a list of branches associated with this project.
|
||||
pub fn list_branches(
|
||||
ctx: &ProjectRepository,
|
||||
ctx: &CommandContext,
|
||||
filter: Option<BranchListingFilter>,
|
||||
) -> Result<Vec<BranchListing>> {
|
||||
let vb_handle = ctx.project().virtual_branches();
|
||||
@ -33,7 +33,7 @@ pub fn list_branches(
|
||||
_ => None,
|
||||
});
|
||||
let mut git_branches: Vec<GroupBranch> = vec![];
|
||||
for result in ctx.repo().branches(branch_filter)? {
|
||||
for result in ctx.repository().branches(branch_filter)? {
|
||||
match result {
|
||||
Ok((branch, branch_type)) => match branch_type {
|
||||
git2::BranchType::Local => {
|
||||
@ -98,10 +98,10 @@ fn matches_all(branch: &BranchListing, filter: &Option<BranchListingFilter>) ->
|
||||
fn combine_branches(
|
||||
mut group_branches: Vec<GroupBranch>,
|
||||
virtual_branches: impl Iterator<Item = GitButlerBranch>,
|
||||
ctx: &ProjectRepository,
|
||||
ctx: &CommandContext,
|
||||
vb_handle: &VirtualBranchesHandle,
|
||||
) -> Result<Vec<BranchListing>> {
|
||||
let repo = ctx.repo();
|
||||
let repo = ctx.repository();
|
||||
for branch in virtual_branches {
|
||||
group_branches.push(GroupBranch::Virtual(branch));
|
||||
}
|
||||
@ -393,10 +393,10 @@ pub struct VirtualBranchReference {
|
||||
/// Takes a list of branch names (the given name, as returned by `BranchListing`) and returns
|
||||
/// a list of enriched branch data in the form of `BranchData`.
|
||||
pub fn get_branch_listing_details(
|
||||
ctx: &ProjectRepository,
|
||||
ctx: &CommandContext,
|
||||
branch_names: Vec<String>,
|
||||
) -> Result<Vec<BranchListingDetails>> {
|
||||
let repo = ctx.repo();
|
||||
let repo = ctx.repository();
|
||||
// Can we do this in a more efficient way?
|
||||
let branches = list_branches(ctx, None)?
|
||||
.into_iter()
|
||||
|
@ -25,12 +25,12 @@ impl BranchManager<'_> {
|
||||
create: &BranchCreateRequest,
|
||||
perm: &mut WorktreeWritePermission,
|
||||
) -> Result<Branch> {
|
||||
let vb_state = self.project_repository.project().virtual_branches();
|
||||
let vb_state = self.ctx.project().virtual_branches();
|
||||
let default_target = vb_state.get_default_target()?;
|
||||
|
||||
let commit = self
|
||||
.project_repository
|
||||
.repo()
|
||||
.ctx
|
||||
.repository()
|
||||
.find_commit(default_target.sha)
|
||||
.context("failed to find default target commit")?;
|
||||
|
||||
@ -54,7 +54,7 @@ impl BranchManager<'_> {
|
||||
);
|
||||
|
||||
_ = self
|
||||
.project_repository
|
||||
.ctx
|
||||
.project()
|
||||
.snapshot_branch_creation(name.clone(), perm);
|
||||
|
||||
@ -107,7 +107,7 @@ impl BranchManager<'_> {
|
||||
ownership: BranchOwnershipClaims::default(),
|
||||
order,
|
||||
selected_for_changes,
|
||||
allow_rebasing: self.project_repository.project().ok_with_force_push.into(),
|
||||
allow_rebasing: self.ctx.project().ok_with_force_push.into(),
|
||||
applied: true,
|
||||
in_workspace: true,
|
||||
not_in_workspace_wip_change_id: None,
|
||||
@ -119,7 +119,7 @@ impl BranchManager<'_> {
|
||||
}
|
||||
|
||||
vb_state.set_branch(branch.clone())?;
|
||||
self.project_repository.add_branch_reference(&branch)?;
|
||||
self.ctx.add_branch_reference(&branch)?;
|
||||
|
||||
Ok(branch)
|
||||
}
|
||||
@ -151,11 +151,11 @@ impl BranchManager<'_> {
|
||||
.to_string();
|
||||
|
||||
let _ = self
|
||||
.project_repository
|
||||
.ctx
|
||||
.project()
|
||||
.snapshot_branch_creation(branch_name.clone(), perm);
|
||||
|
||||
let vb_state = self.project_repository.project().virtual_branches();
|
||||
let vb_state = self.ctx.project().virtual_branches();
|
||||
|
||||
let default_target = vb_state.get_default_target()?;
|
||||
|
||||
@ -165,7 +165,7 @@ impl BranchManager<'_> {
|
||||
}
|
||||
}
|
||||
|
||||
let repo = self.project_repository.repo();
|
||||
let repo = self.ctx.repository();
|
||||
let head_reference = repo
|
||||
.find_reference(&target.to_string())
|
||||
.map_err(|err| match err {
|
||||
@ -200,11 +200,8 @@ impl BranchManager<'_> {
|
||||
let merge_base_tree = repo.find_commit(merge_base_oid)?.tree()?;
|
||||
|
||||
// do a diff between the head of this branch and the target base
|
||||
let diff = gitbutler_diff::trees(
|
||||
self.project_repository.repo(),
|
||||
&merge_base_tree,
|
||||
&head_commit_tree,
|
||||
)?;
|
||||
let diff =
|
||||
gitbutler_diff::trees(self.ctx.repository(), &merge_base_tree, &head_commit_tree)?;
|
||||
|
||||
// assign ownership to the branch
|
||||
let ownership = diff.iter().fold(
|
||||
@ -235,7 +232,7 @@ impl BranchManager<'_> {
|
||||
branch.ownership = ownership;
|
||||
branch.order = order;
|
||||
branch.selected_for_changes = selected_for_changes;
|
||||
branch.allow_rebasing = self.project_repository.project().ok_with_force_push.into();
|
||||
branch.allow_rebasing = self.ctx.project().ok_with_force_push.into();
|
||||
branch.applied = true;
|
||||
branch.in_workspace = true;
|
||||
|
||||
@ -255,7 +252,7 @@ impl BranchManager<'_> {
|
||||
ownership,
|
||||
order,
|
||||
selected_for_changes,
|
||||
allow_rebasing: self.project_repository.project().ok_with_force_push.into(),
|
||||
allow_rebasing: self.ctx.project().ok_with_force_push.into(),
|
||||
applied: true,
|
||||
in_workspace: true,
|
||||
not_in_workspace_wip_change_id: None,
|
||||
@ -263,7 +260,7 @@ impl BranchManager<'_> {
|
||||
};
|
||||
|
||||
vb_state.set_branch(branch.clone())?;
|
||||
self.project_repository.add_branch_reference(&branch)?;
|
||||
self.ctx.add_branch_reference(&branch)?;
|
||||
|
||||
match self.apply_branch(branch.id, perm) {
|
||||
Ok(_) => Ok(branch.id),
|
||||
@ -287,11 +284,11 @@ impl BranchManager<'_> {
|
||||
branch_id: BranchId,
|
||||
perm: &mut WorktreeWritePermission,
|
||||
) -> Result<String> {
|
||||
self.project_repository.assure_resolved()?;
|
||||
self.project_repository.assure_unconflicted()?;
|
||||
let repo = self.project_repository.repo();
|
||||
self.ctx.assure_resolved()?;
|
||||
self.ctx.assure_unconflicted()?;
|
||||
let repo = self.ctx.repository();
|
||||
|
||||
let vb_state = self.project_repository.project().virtual_branches();
|
||||
let vb_state = self.ctx.project().virtual_branches();
|
||||
let default_target = vb_state.get_default_target()?;
|
||||
|
||||
let mut branch = vb_state.get_branch_in_workspace(branch_id)?;
|
||||
@ -358,11 +355,7 @@ impl BranchManager<'_> {
|
||||
merge_conflicts.push(path);
|
||||
}
|
||||
}
|
||||
conflicts::mark(
|
||||
self.project_repository,
|
||||
&merge_conflicts,
|
||||
Some(default_target.sha),
|
||||
)?;
|
||||
conflicts::mark(self.ctx, &merge_conflicts, Some(default_target.sha))?;
|
||||
|
||||
return Ok(branch.name);
|
||||
}
|
||||
@ -372,7 +365,7 @@ impl BranchManager<'_> {
|
||||
.context("failed to find head commit")?;
|
||||
|
||||
let merged_branch_tree_oid = merge_index
|
||||
.write_tree_to(self.project_repository.repo())
|
||||
.write_tree_to(self.ctx.repository())
|
||||
.context("failed to write tree")?;
|
||||
|
||||
let merged_branch_tree = repo
|
||||
@ -384,7 +377,7 @@ impl BranchManager<'_> {
|
||||
// branch was pushed to upstream, and user doesn't like force pushing.
|
||||
// create a merge commit to avoid the need of force pushing then.
|
||||
|
||||
let new_branch_head = self.project_repository.commit(
|
||||
let new_branch_head = self.ctx.commit(
|
||||
format!(
|
||||
"Merged {}/{} into {}",
|
||||
default_target.branch.remote(),
|
||||
@ -401,7 +394,7 @@ impl BranchManager<'_> {
|
||||
branch.head = new_branch_head;
|
||||
} else {
|
||||
let rebase = cherry_rebase(
|
||||
self.project_repository,
|
||||
self.ctx,
|
||||
target_commit.id(),
|
||||
target_commit.id(),
|
||||
branch.head,
|
||||
@ -432,7 +425,7 @@ impl BranchManager<'_> {
|
||||
|
||||
// commit the merge tree oid
|
||||
let new_branch_head = self
|
||||
.project_repository
|
||||
.ctx
|
||||
.commit(
|
||||
format!(
|
||||
"Merged {}/{} into {}",
|
||||
@ -459,7 +452,7 @@ impl BranchManager<'_> {
|
||||
vb_state.set_branch(branch.clone())?;
|
||||
}
|
||||
|
||||
let wd_tree = self.project_repository.repo().get_wd_tree()?;
|
||||
let wd_tree = self.ctx.repository().get_wd_tree()?;
|
||||
|
||||
let branch_tree = repo
|
||||
.find_tree(branch.tree)
|
||||
@ -482,11 +475,7 @@ impl BranchManager<'_> {
|
||||
merge_conflicts.push(path);
|
||||
}
|
||||
}
|
||||
conflicts::mark(
|
||||
self.project_repository,
|
||||
&merge_conflicts,
|
||||
Some(default_target.sha),
|
||||
)?;
|
||||
conflicts::mark(self.ctx, &merge_conflicts, Some(default_target.sha))?;
|
||||
}
|
||||
|
||||
// apply the branch
|
||||
@ -508,7 +497,7 @@ impl BranchManager<'_> {
|
||||
|
||||
if let Some(headers) = potential_wip_commit.gitbutler_headers() {
|
||||
if headers.change_id == wip_commit_to_unapply {
|
||||
undo_commit(self.project_repository, branch.id, branch.head)?;
|
||||
undo_commit(self.ctx, branch.id, branch.head)?;
|
||||
}
|
||||
}
|
||||
|
||||
@ -517,7 +506,7 @@ impl BranchManager<'_> {
|
||||
}
|
||||
}
|
||||
|
||||
update_gitbutler_integration(&vb_state, self.project_repository)?;
|
||||
update_gitbutler_integration(&vb_state, self.ctx)?;
|
||||
|
||||
Ok(branch.name)
|
||||
}
|
||||
|
@ -24,7 +24,7 @@ impl BranchManager<'_> {
|
||||
branch_id: BranchId,
|
||||
perm: &mut WorktreeWritePermission,
|
||||
) -> Result<ReferenceName> {
|
||||
let vb_state = self.project_repository.project().virtual_branches();
|
||||
let vb_state = self.ctx.project().virtual_branches();
|
||||
|
||||
let mut target_branch = vb_state.get_branch(branch_id)?;
|
||||
|
||||
@ -34,8 +34,8 @@ impl BranchManager<'_> {
|
||||
self.delete_branch(branch_id, perm)?;
|
||||
|
||||
// If we were conflicting, it means that it was the only branch applied. Since we've now unapplied it we can clear all conflicts
|
||||
if conflicts::is_conflicting(self.project_repository, None)? {
|
||||
conflicts::clear(self.project_repository)?;
|
||||
if conflicts::is_conflicting(self.ctx, None)? {
|
||||
conflicts::clear(self.ctx)?;
|
||||
}
|
||||
|
||||
vb_state.update_ordering()?;
|
||||
@ -43,7 +43,7 @@ impl BranchManager<'_> {
|
||||
// Ensure we still have a default target
|
||||
ensure_selected_for_changes(&vb_state).context("failed to ensure selected for changes")?;
|
||||
|
||||
crate::integration::update_gitbutler_integration(&vb_state, self.project_repository)?;
|
||||
crate::integration::update_gitbutler_integration(&vb_state, self.ctx)?;
|
||||
|
||||
real_branch.reference_name()
|
||||
}
|
||||
@ -53,7 +53,7 @@ impl BranchManager<'_> {
|
||||
branch_id: BranchId,
|
||||
perm: &mut WorktreeWritePermission,
|
||||
) -> Result<()> {
|
||||
let vb_state = self.project_repository.project().virtual_branches();
|
||||
let vb_state = self.ctx.project().virtual_branches();
|
||||
let Some(branch) = vb_state.try_branch(branch_id)? else {
|
||||
return Ok(());
|
||||
};
|
||||
@ -64,16 +64,16 @@ impl BranchManager<'_> {
|
||||
}
|
||||
|
||||
_ = self
|
||||
.project_repository
|
||||
.ctx
|
||||
.project()
|
||||
.snapshot_branch_deletion(branch.name.clone(), perm);
|
||||
|
||||
let repo = self.project_repository.repo();
|
||||
let repo = self.ctx.repository();
|
||||
|
||||
let target_commit = repo.target_commit()?;
|
||||
let base_tree = target_commit.tree().context("failed to get target tree")?;
|
||||
|
||||
let applied_statuses = get_applied_status(self.project_repository, None)
|
||||
let applied_statuses = get_applied_status(self.ctx, None)
|
||||
.context("failed to get status by branch")?
|
||||
.branches;
|
||||
|
||||
@ -97,11 +97,8 @@ impl BranchManager<'_> {
|
||||
.into_iter()
|
||||
.map(|file| (file.path, file.hunks))
|
||||
.collect::<Vec<(PathBuf, Vec<VirtualBranchHunk>)>>();
|
||||
let tree_oid = gitbutler_diff::write::hunks_onto_oid(
|
||||
self.project_repository,
|
||||
&branch.head,
|
||||
files,
|
||||
)?;
|
||||
let tree_oid =
|
||||
gitbutler_diff::write::hunks_onto_oid(self.ctx, &branch.head, files)?;
|
||||
let branch_tree = repo.find_tree(tree_oid)?;
|
||||
let mut result =
|
||||
repo.merge_trees(&base_tree, &final_tree, &branch_tree, None)?;
|
||||
@ -118,7 +115,7 @@ impl BranchManager<'_> {
|
||||
.checkout()
|
||||
.context("failed to checkout tree")?;
|
||||
|
||||
self.project_repository.delete_branch_reference(&branch)?;
|
||||
self.ctx.delete_branch_reference(&branch)?;
|
||||
|
||||
ensure_selected_for_changes(&vb_state).context("failed to ensure selected for changes")?;
|
||||
|
||||
@ -128,12 +125,12 @@ impl BranchManager<'_> {
|
||||
|
||||
impl BranchManager<'_> {
|
||||
fn build_real_branch(&self, vbranch: &mut Branch) -> Result<git2::Branch<'_>> {
|
||||
let repo = self.project_repository.repo();
|
||||
let repo = self.ctx.repository();
|
||||
let target_commit = repo.find_commit(vbranch.head)?;
|
||||
let branch_name = vbranch.name.clone();
|
||||
let branch_name = normalize_branch_name(&branch_name);
|
||||
|
||||
let vb_state = self.project_repository.project().virtual_branches();
|
||||
let vb_state = self.ctx.project().virtual_branches();
|
||||
let branch = repo.branch(&branch_name, &target_commit, true)?;
|
||||
vbranch.source_refname = Some(Refname::try_from(&branch)?);
|
||||
vb_state.set_branch(vbranch.clone())?;
|
||||
@ -148,7 +145,7 @@ impl BranchManager<'_> {
|
||||
vbranch: &mut Branch,
|
||||
branch: &git2::Branch<'_>,
|
||||
) -> Result<Option<git2::Oid>> {
|
||||
let repo = self.project_repository.repo();
|
||||
let repo = self.ctx.repository();
|
||||
|
||||
// Build wip tree as either any uncommitted changes or an empty tree
|
||||
let vbranch_wip_tree = repo.find_tree(vbranch.tree)?;
|
||||
@ -181,7 +178,7 @@ impl BranchManager<'_> {
|
||||
Some(commit_headers.clone()),
|
||||
)?;
|
||||
|
||||
let vb_state = self.project_repository.project().virtual_branches();
|
||||
let vb_state = self.ctx.project().virtual_branches();
|
||||
// vbranch.head = commit_oid;
|
||||
vbranch.not_in_workspace_wip_change_id = Some(commit_headers.change_id);
|
||||
vb_state.set_branch(vbranch.clone())?;
|
||||
|
@ -1,20 +1,18 @@
|
||||
use gitbutler_command_context::ProjectRepository;
|
||||
use gitbutler_command_context::CommandContext;
|
||||
|
||||
mod branch_creation;
|
||||
mod branch_removal;
|
||||
|
||||
pub struct BranchManager<'l> {
|
||||
project_repository: &'l ProjectRepository,
|
||||
ctx: &'l CommandContext,
|
||||
}
|
||||
|
||||
pub trait BranchManagerExt {
|
||||
fn branch_manager(&self) -> BranchManager;
|
||||
}
|
||||
|
||||
impl BranchManagerExt for ProjectRepository {
|
||||
impl BranchManagerExt for CommandContext {
|
||||
fn branch_manager(&self) -> BranchManager {
|
||||
BranchManager {
|
||||
project_repository: self,
|
||||
}
|
||||
BranchManager { ctx: self }
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
use anyhow::{Context, Result};
|
||||
use bstr::BString;
|
||||
use gitbutler_branch::{Branch, BranchId};
|
||||
use gitbutler_command_context::ProjectRepository;
|
||||
use gitbutler_command_context::CommandContext;
|
||||
use gitbutler_commit::commit_ext::CommitExt;
|
||||
use serde::Serialize;
|
||||
|
||||
@ -38,7 +38,7 @@ pub struct VirtualBranchCommit {
|
||||
}
|
||||
|
||||
pub(crate) fn commit_to_vbranch_commit(
|
||||
repository: &ProjectRepository,
|
||||
repository: &CommandContext,
|
||||
branch: &Branch,
|
||||
commit: &git2::Commit,
|
||||
is_integrated: bool,
|
||||
|
@ -12,11 +12,11 @@ use std::{
|
||||
|
||||
use anyhow::{anyhow, bail, Context, Result};
|
||||
use bstr::ByteSlice;
|
||||
use gitbutler_command_context::ProjectRepository;
|
||||
use gitbutler_command_context::CommandContext;
|
||||
use gitbutler_error::error::Marker;
|
||||
|
||||
pub(crate) fn mark<P: AsRef<Path>, A: AsRef<[P]>>(
|
||||
ctx: &ProjectRepository,
|
||||
ctx: &CommandContext,
|
||||
paths: A,
|
||||
parent: Option<git2::Oid>,
|
||||
) -> Result<()> {
|
||||
@ -45,15 +45,15 @@ pub(crate) fn mark<P: AsRef<Path>, A: AsRef<[P]>>(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn conflicts_path(ctx: &ProjectRepository) -> PathBuf {
|
||||
ctx.repo().path().join("conflicts")
|
||||
fn conflicts_path(ctx: &CommandContext) -> PathBuf {
|
||||
ctx.repository().path().join("conflicts")
|
||||
}
|
||||
|
||||
fn merge_parent_path(ctx: &ProjectRepository) -> PathBuf {
|
||||
ctx.repo().path().join("base_merge_parent")
|
||||
fn merge_parent_path(ctx: &CommandContext) -> PathBuf {
|
||||
ctx.repository().path().join("base_merge_parent")
|
||||
}
|
||||
|
||||
pub(crate) fn merge_parent(ctx: &ProjectRepository) -> Result<Option<git2::Oid>> {
|
||||
pub(crate) fn merge_parent(ctx: &CommandContext) -> Result<Option<git2::Oid>> {
|
||||
use std::io::BufRead;
|
||||
|
||||
let merge_path = merge_parent_path(ctx);
|
||||
@ -73,7 +73,7 @@ pub(crate) fn merge_parent(ctx: &ProjectRepository) -> Result<Option<git2::Oid>>
|
||||
}
|
||||
}
|
||||
|
||||
pub fn resolve<P: AsRef<Path>>(ctx: &ProjectRepository, path_to_resolve: P) -> Result<()> {
|
||||
pub fn resolve<P: AsRef<Path>>(ctx: &CommandContext, path_to_resolve: P) -> Result<()> {
|
||||
let path_to_resolve = path_to_resolve.as_ref();
|
||||
let path_to_resolve = path_to_resolve.as_os_str().as_encoded_bytes();
|
||||
let conflicts_path = conflicts_path(ctx);
|
||||
@ -93,7 +93,7 @@ pub fn resolve<P: AsRef<Path>>(ctx: &ProjectRepository, path_to_resolve: P) -> R
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn conflicting_files(ctx: &ProjectRepository) -> Result<Vec<PathBuf>> {
|
||||
pub(crate) fn conflicting_files(ctx: &CommandContext) -> Result<Vec<PathBuf>> {
|
||||
let conflicts_path = conflicts_path(ctx);
|
||||
if !conflicts_path.exists() {
|
||||
return Ok(vec![]);
|
||||
@ -108,7 +108,7 @@ pub(crate) fn conflicting_files(ctx: &ProjectRepository) -> Result<Vec<PathBuf>>
|
||||
|
||||
/// Check if `path` is conflicting in `repository`, or if `None`, check if there is any conflict.
|
||||
// TODO(ST): Should this not rather check the conflicting state in the index?
|
||||
pub(crate) fn is_conflicting(repository: &ProjectRepository, path: Option<&Path>) -> Result<bool> {
|
||||
pub(crate) fn is_conflicting(repository: &CommandContext, path: Option<&Path>) -> Result<bool> {
|
||||
let conflicts_path = conflicts_path(repository);
|
||||
if !conflicts_path.exists() {
|
||||
return Ok(false);
|
||||
@ -128,11 +128,11 @@ pub(crate) fn is_conflicting(repository: &ProjectRepository, path: Option<&Path>
|
||||
|
||||
// is this project still in a resolving conflict state?
|
||||
// - could be that there are no more conflicts, but the state is not committed
|
||||
pub(crate) fn is_resolving(ctx: &ProjectRepository) -> bool {
|
||||
pub(crate) fn is_resolving(ctx: &CommandContext) -> bool {
|
||||
merge_parent_path(ctx).exists()
|
||||
}
|
||||
|
||||
pub(crate) fn clear(ctx: &ProjectRepository) -> Result<()> {
|
||||
pub(crate) fn clear(ctx: &CommandContext) -> Result<()> {
|
||||
remove_file_ignore_missing(merge_parent_path(ctx))?;
|
||||
remove_file_ignore_missing(conflicts_path(ctx))?;
|
||||
Ok(())
|
||||
@ -154,7 +154,7 @@ pub(crate) trait RepoConflictsExt {
|
||||
fn is_resolving(&self) -> bool;
|
||||
}
|
||||
|
||||
impl RepoConflictsExt for ProjectRepository {
|
||||
impl RepoConflictsExt for CommandContext {
|
||||
fn is_resolving(&self) -> bool {
|
||||
is_resolving(self)
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ use std::{
|
||||
};
|
||||
|
||||
use anyhow::{anyhow, Context, Result};
|
||||
use gitbutler_command_context::ProjectRepository;
|
||||
use gitbutler_command_context::CommandContext;
|
||||
use gitbutler_diff::FileDiff;
|
||||
use serde::Serialize;
|
||||
|
||||
@ -86,7 +86,7 @@ impl Get<VirtualBranchFile> for Vec<VirtualBranchFile> {
|
||||
}
|
||||
|
||||
pub(crate) fn list_virtual_commit_files(
|
||||
project_repository: &ProjectRepository,
|
||||
ctx: &CommandContext,
|
||||
commit: &git2::Commit,
|
||||
) -> Result<Vec<VirtualBranchFile>> {
|
||||
if commit.parent_count() == 0 {
|
||||
@ -95,12 +95,9 @@ pub(crate) fn list_virtual_commit_files(
|
||||
let parent = commit.parent(0).context("failed to get parent commit")?;
|
||||
let commit_tree = commit.tree().context("failed to get commit tree")?;
|
||||
let parent_tree = parent.tree().context("failed to get parent tree")?;
|
||||
let diff = gitbutler_diff::trees(project_repository.repo(), &parent_tree, &commit_tree)?;
|
||||
let hunks_by_filepath = virtual_hunks_by_file_diffs(&project_repository.project().path, diff);
|
||||
Ok(virtual_hunks_into_virtual_files(
|
||||
project_repository,
|
||||
hunks_by_filepath,
|
||||
))
|
||||
let diff = gitbutler_diff::trees(ctx.repository(), &parent_tree, &commit_tree)?;
|
||||
let hunks_by_filepath = virtual_hunks_by_file_diffs(&ctx.project().path, diff);
|
||||
Ok(virtual_hunks_into_virtual_files(ctx, hunks_by_filepath))
|
||||
}
|
||||
|
||||
fn virtual_hunks_by_file_diffs<'a>(
|
||||
@ -117,15 +114,14 @@ fn virtual_hunks_by_file_diffs<'a>(
|
||||
|
||||
/// NOTE: There is no use returning an iterator here as this acts like the final product.
|
||||
pub(crate) fn virtual_hunks_into_virtual_files(
|
||||
project_repository: &ProjectRepository,
|
||||
ctx: &CommandContext,
|
||||
hunks: impl IntoIterator<Item = (PathBuf, Vec<VirtualBranchHunk>)>,
|
||||
) -> Vec<VirtualBranchFile> {
|
||||
hunks
|
||||
.into_iter()
|
||||
.map(|(path, hunks)| {
|
||||
let id = path.display().to_string();
|
||||
let conflicted =
|
||||
conflicts::is_conflicting(project_repository, Some(&path)).unwrap_or(false);
|
||||
let conflicted = conflicts::is_conflicting(ctx, Some(&path)).unwrap_or(false);
|
||||
let binary = hunks.iter().any(|h| h.binary);
|
||||
let modified_at = hunks.iter().map(|h| h.modified_at).max().unwrap_or(0);
|
||||
debug_assert!(hunks.iter().all(|hunk| hunk.file_path == path));
|
||||
|
@ -7,7 +7,7 @@ use gitbutler_branch::{
|
||||
GITBUTLER_INTEGRATION_COMMIT_AUTHOR_EMAIL, GITBUTLER_INTEGRATION_COMMIT_AUTHOR_NAME,
|
||||
GITBUTLER_INTEGRATION_REFERENCE,
|
||||
};
|
||||
use gitbutler_command_context::ProjectRepository;
|
||||
use gitbutler_command_context::CommandContext;
|
||||
use gitbutler_commit::commit_ext::CommitExt;
|
||||
use gitbutler_error::error::Marker;
|
||||
use gitbutler_project::access::WorktreeWritePermission;
|
||||
@ -28,12 +28,12 @@ pub(crate) fn get_integration_commiter<'a>() -> Result<git2::Signature<'a>> {
|
||||
//
|
||||
// This is the base against which we diff the working directory to understand
|
||||
// what files have been modified.
|
||||
pub(crate) fn get_workspace_head(project_repo: &ProjectRepository) -> Result<git2::Oid> {
|
||||
let vb_state = project_repo.project().virtual_branches();
|
||||
pub(crate) fn get_workspace_head(ctx: &CommandContext) -> Result<git2::Oid> {
|
||||
let vb_state = ctx.project().virtual_branches();
|
||||
let target = vb_state
|
||||
.get_default_target()
|
||||
.context("failed to get target")?;
|
||||
let repo: &git2::Repository = project_repo.repo();
|
||||
let repo: &git2::Repository = ctx.repository();
|
||||
|
||||
let mut virtual_branches: Vec<Branch> = vb_state.list_branches_in_workspace()?;
|
||||
|
||||
@ -51,9 +51,8 @@ pub(crate) fn get_workspace_head(project_repo: &ProjectRepository) -> Result<git
|
||||
return Ok(target_commit.id());
|
||||
}
|
||||
|
||||
if conflicts::is_conflicting(project_repo, None)? {
|
||||
let merge_parent =
|
||||
conflicts::merge_parent(project_repo)?.ok_or(anyhow!("No merge parent"))?;
|
||||
if conflicts::is_conflicting(ctx, None)? {
|
||||
let merge_parent = conflicts::merge_parent(ctx)?.ok_or(anyhow!("No merge parent"))?;
|
||||
let first_branch = virtual_branches.first().ok_or(anyhow!("No branches"))?;
|
||||
|
||||
let merge_base = repo.merge_base(first_branch.head, merge_parent)?;
|
||||
@ -135,13 +134,13 @@ fn write_integration_file(head: &git2::Reference, path: PathBuf) -> Result<()> {
|
||||
}
|
||||
pub fn update_gitbutler_integration(
|
||||
vb_state: &VirtualBranchesHandle,
|
||||
project_repository: &ProjectRepository,
|
||||
ctx: &CommandContext,
|
||||
) -> Result<git2::Oid> {
|
||||
let target = vb_state
|
||||
.get_default_target()
|
||||
.context("failed to get target")?;
|
||||
|
||||
let repo: &git2::Repository = project_repository.repo();
|
||||
let repo: &git2::Repository = ctx.repository();
|
||||
|
||||
// get commit object from target.sha
|
||||
let target_commit = repo.find_commit(target.sha)?;
|
||||
@ -162,14 +161,14 @@ pub fn update_gitbutler_integration(
|
||||
}
|
||||
}
|
||||
|
||||
let vb_state = project_repository.project().virtual_branches();
|
||||
let vb_state = ctx.project().virtual_branches();
|
||||
|
||||
// get all virtual branches, we need to try to update them all
|
||||
let virtual_branches: Vec<Branch> = vb_state
|
||||
.list_branches_in_workspace()
|
||||
.context("failed to list virtual branches")?;
|
||||
|
||||
let integration_commit = repo.find_commit(get_workspace_head(project_repository)?)?;
|
||||
let integration_commit = repo.find_commit(get_workspace_head(ctx)?)?;
|
||||
let integration_tree = integration_commit.tree()?;
|
||||
|
||||
// message that says how to get back to where they were
|
||||
@ -279,7 +278,7 @@ pub fn update_gitbutler_integration(
|
||||
Ok(final_commit)
|
||||
}
|
||||
|
||||
pub fn verify_branch(ctx: &ProjectRepository, perm: &mut WorktreeWritePermission) -> Result<()> {
|
||||
pub fn verify_branch(ctx: &CommandContext, perm: &mut WorktreeWritePermission) -> Result<()> {
|
||||
verify_current_branch_name(ctx)
|
||||
.and_then(verify_head_is_set)
|
||||
.and_then(|()| verify_head_is_clean(ctx, perm))
|
||||
@ -287,8 +286,13 @@ pub fn verify_branch(ctx: &ProjectRepository, perm: &mut WorktreeWritePermission
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn verify_head_is_set(ctx: &ProjectRepository) -> Result<()> {
|
||||
match ctx.repo().head().context("failed to get head")?.name() {
|
||||
fn verify_head_is_set(ctx: &CommandContext) -> Result<()> {
|
||||
match ctx
|
||||
.repository()
|
||||
.head()
|
||||
.context("failed to get head")?
|
||||
.name()
|
||||
{
|
||||
Some(refname) if *refname == GITBUTLER_INTEGRATION_REFERENCE.to_string() => Ok(()),
|
||||
Some(head_name) => Err(invalid_head_err(head_name)),
|
||||
None => Err(anyhow!(
|
||||
@ -299,8 +303,8 @@ fn verify_head_is_set(ctx: &ProjectRepository) -> Result<()> {
|
||||
}
|
||||
|
||||
// Returns an error if repo head is not pointing to the integration branch.
|
||||
fn verify_current_branch_name(ctx: &ProjectRepository) -> Result<&ProjectRepository> {
|
||||
match ctx.repo().head()?.name() {
|
||||
fn verify_current_branch_name(ctx: &CommandContext) -> Result<&CommandContext> {
|
||||
match ctx.repository().head()?.name() {
|
||||
Some(head) => {
|
||||
let head_name = head.to_string();
|
||||
if head_name != GITBUTLER_INTEGRATION_REFERENCE.to_string() {
|
||||
@ -313,9 +317,9 @@ fn verify_current_branch_name(ctx: &ProjectRepository) -> Result<&ProjectReposit
|
||||
}
|
||||
|
||||
// TODO(ST): Probably there should not be an implicit vbranch creation here.
|
||||
fn verify_head_is_clean(ctx: &ProjectRepository, perm: &mut WorktreeWritePermission) -> Result<()> {
|
||||
fn verify_head_is_clean(ctx: &CommandContext, perm: &mut WorktreeWritePermission) -> Result<()> {
|
||||
let head_commit = ctx
|
||||
.repo()
|
||||
.repository()
|
||||
.head()
|
||||
.context("failed to get head")?
|
||||
.peel_to_commit()
|
||||
@ -342,7 +346,7 @@ fn verify_head_is_clean(ctx: &ProjectRepository, perm: &mut WorktreeWritePermiss
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
ctx.repo()
|
||||
ctx.repository()
|
||||
.reset(
|
||||
integration_commit.as_ref().unwrap().as_object(),
|
||||
git2::ResetType::Soft,
|
||||
@ -369,12 +373,12 @@ fn verify_head_is_clean(ctx: &ProjectRepository, perm: &mut WorktreeWritePermiss
|
||||
let mut head = new_branch.head;
|
||||
for commit in extra_commits {
|
||||
let new_branch_head = ctx
|
||||
.repo()
|
||||
.repository()
|
||||
.find_commit(head)
|
||||
.context("failed to find new branch head")?;
|
||||
|
||||
let rebased_commit_oid = ctx
|
||||
.repo()
|
||||
.repository()
|
||||
.commit_with_signature(
|
||||
None,
|
||||
&commit.author(),
|
||||
@ -389,10 +393,13 @@ fn verify_head_is_clean(ctx: &ProjectRepository, perm: &mut WorktreeWritePermiss
|
||||
commit.id()
|
||||
))?;
|
||||
|
||||
let rebased_commit = ctx.repo().find_commit(rebased_commit_oid).context(format!(
|
||||
"failed to find rebased commit {}",
|
||||
rebased_commit_oid
|
||||
))?;
|
||||
let rebased_commit = ctx
|
||||
.repository()
|
||||
.find_commit(rebased_commit_oid)
|
||||
.context(format!(
|
||||
"failed to find rebased commit {}",
|
||||
rebased_commit_oid
|
||||
))?;
|
||||
|
||||
new_branch.head = rebased_commit.id();
|
||||
new_branch.tree = rebased_commit.tree_id();
|
||||
|
@ -3,7 +3,7 @@ use std::path::Path;
|
||||
use anyhow::{Context, Result};
|
||||
use bstr::BString;
|
||||
use gitbutler_branch::{ReferenceExt, Target, VirtualBranchesHandle};
|
||||
use gitbutler_command_context::ProjectRepository;
|
||||
use gitbutler_command_context::CommandContext;
|
||||
use gitbutler_commit::commit_ext::CommitExt;
|
||||
use gitbutler_reference::{Refname, RemoteRefname};
|
||||
use gitbutler_repo::{LogUntil, RepoActionsExt, RepositoryExt};
|
||||
@ -61,17 +61,17 @@ 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: &ProjectRepository) -> Result<Vec<RemoteBranch>> {
|
||||
let default_target = default_target(&project_repository.project().gb_dir())?;
|
||||
pub fn list_remote_branches(ctx: &CommandContext) -> Result<Vec<RemoteBranch>> {
|
||||
let default_target = default_target(&ctx.project().gb_dir())?;
|
||||
|
||||
let mut remote_branches = vec![];
|
||||
for (branch, _) in project_repository
|
||||
.repo()
|
||||
for (branch, _) in ctx
|
||||
.repository()
|
||||
.branches(None)
|
||||
.context("failed to list remote branches")?
|
||||
.flatten()
|
||||
{
|
||||
let branch = branch_to_remote_branch(project_repository, &branch);
|
||||
let branch = branch_to_remote_branch(ctx, &branch);
|
||||
|
||||
if let Some(branch) = branch {
|
||||
let branch_is_trunk = branch.name.branch() == Some(default_target.branch.branch())
|
||||
@ -88,14 +88,11 @@ pub fn list_remote_branches(project_repository: &ProjectRepository) -> Result<Ve
|
||||
Ok(remote_branches)
|
||||
}
|
||||
|
||||
pub(crate) fn get_branch_data(
|
||||
ctx: &ProjectRepository,
|
||||
refname: &Refname,
|
||||
) -> Result<RemoteBranchData> {
|
||||
pub(crate) fn get_branch_data(ctx: &CommandContext, refname: &Refname) -> Result<RemoteBranchData> {
|
||||
let default_target = default_target(&ctx.project().gb_dir())?;
|
||||
|
||||
let branch = ctx
|
||||
.repo()
|
||||
.repository()
|
||||
.find_branch_by_refname(refname)?
|
||||
.ok_or(anyhow::anyhow!("failed to find branch {}", refname))?;
|
||||
|
||||
@ -104,7 +101,7 @@ pub(crate) fn get_branch_data(
|
||||
}
|
||||
|
||||
pub(crate) fn branch_to_remote_branch(
|
||||
ctx: &ProjectRepository,
|
||||
ctx: &CommandContext,
|
||||
branch: &git2::Branch,
|
||||
) -> Option<RemoteBranch> {
|
||||
let commit = match branch.get().peel_to_commit() {
|
||||
@ -122,7 +119,10 @@ pub(crate) fn branch_to_remote_branch(
|
||||
.context("could not get branch name")
|
||||
.ok()?;
|
||||
|
||||
let given_name = branch.get().given_name(&ctx.repo().remotes().ok()?).ok()?;
|
||||
let given_name = branch
|
||||
.get()
|
||||
.given_name(&ctx.repository().remotes().ok()?)
|
||||
.ok()?;
|
||||
|
||||
branch.get().target().map(|sha| RemoteBranch {
|
||||
sha,
|
||||
@ -145,7 +145,7 @@ pub(crate) fn branch_to_remote_branch(
|
||||
}
|
||||
|
||||
pub(crate) fn branch_to_remote_branch_data(
|
||||
project_repository: &ProjectRepository,
|
||||
ctx: &CommandContext,
|
||||
branch: &git2::Branch,
|
||||
base: git2::Oid,
|
||||
) -> Result<Option<RemoteBranchData>> {
|
||||
@ -153,13 +153,13 @@ pub(crate) fn branch_to_remote_branch_data(
|
||||
.get()
|
||||
.target()
|
||||
.map(|sha| {
|
||||
let ahead = project_repository
|
||||
let ahead = ctx
|
||||
.log(sha, LogUntil::Commit(base))
|
||||
.context("failed to get ahead commits")?;
|
||||
|
||||
let name = Refname::try_from(branch).context("could not get branch name")?;
|
||||
|
||||
let count_behind = project_repository
|
||||
let count_behind = ctx
|
||||
.distance(base, sha)
|
||||
.context("failed to get behind count")?;
|
||||
|
||||
|
@ -4,7 +4,7 @@ use anyhow::{bail, Context, Result};
|
||||
use gitbutler_branch::{
|
||||
Branch, BranchCreateRequest, BranchId, BranchOwnershipClaims, OwnershipClaim,
|
||||
};
|
||||
use gitbutler_command_context::ProjectRepository;
|
||||
use gitbutler_command_context::CommandContext;
|
||||
use gitbutler_diff::{diff_files_into_hunks, GitHunk, Hunk, HunkHash};
|
||||
use gitbutler_project::access::WorktreeWritePermission;
|
||||
use gitbutler_repo::RepositoryExt;
|
||||
@ -29,17 +29,16 @@ pub struct VirtualBranchesStatus {
|
||||
/// of skipped files.
|
||||
// TODO(kv): make this side effect free
|
||||
pub fn get_applied_status(
|
||||
project_repository: &ProjectRepository,
|
||||
ctx: &CommandContext,
|
||||
perm: Option<&mut WorktreeWritePermission>,
|
||||
) -> Result<VirtualBranchesStatus> {
|
||||
let integration_commit = get_workspace_head(project_repository)?;
|
||||
let mut virtual_branches = project_repository
|
||||
let integration_commit = get_workspace_head(ctx)?;
|
||||
let mut virtual_branches = ctx
|
||||
.project()
|
||||
.virtual_branches()
|
||||
.list_branches_in_workspace()?;
|
||||
let base_file_diffs =
|
||||
gitbutler_diff::workdir(project_repository.repo(), &integration_commit.to_owned())
|
||||
.context("failed to diff workdir")?;
|
||||
let base_file_diffs = gitbutler_diff::workdir(ctx.repository(), &integration_commit.to_owned())
|
||||
.context("failed to diff workdir")?;
|
||||
|
||||
let mut skipped_files: Vec<gitbutler_diff::FileDiff> = Vec::new();
|
||||
for file_diff in base_file_diffs.values() {
|
||||
@ -52,7 +51,7 @@ pub fn get_applied_status(
|
||||
// sort by order, so that the default branch is first (left in the ui)
|
||||
virtual_branches.sort_by(|a, b| a.order.cmp(&b.order));
|
||||
|
||||
let branch_manager = project_repository.branch_manager();
|
||||
let branch_manager = ctx.branch_manager();
|
||||
|
||||
if virtual_branches.is_empty() && !base_diffs.is_empty() {
|
||||
if let Some(perm) = perm {
|
||||
@ -70,7 +69,7 @@ pub fn get_applied_status(
|
||||
.map(|branch| (branch.id, HashMap::new()))
|
||||
.collect();
|
||||
|
||||
let locks = compute_locks(project_repository.repo(), &base_diffs, &virtual_branches)?;
|
||||
let locks = compute_locks(ctx.repository(), &base_diffs, &virtual_branches)?;
|
||||
|
||||
for branch in &mut virtual_branches {
|
||||
let old_claims = branch.ownership.claims.clone();
|
||||
@ -187,11 +186,10 @@ pub fn get_applied_status(
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
// write updated state if not resolving
|
||||
if !project_repository.is_resolving() {
|
||||
let vb_state = project_repository.project().virtual_branches();
|
||||
if !ctx.is_resolving() {
|
||||
let vb_state = ctx.project().virtual_branches();
|
||||
for (vbranch, files) in &mut hunks_by_branch {
|
||||
vbranch.tree =
|
||||
gitbutler_diff::write::hunks_onto_oid(project_repository, &vbranch.head, files)?;
|
||||
vbranch.tree = gitbutler_diff::write::hunks_onto_oid(ctx, &vbranch.head, files)?;
|
||||
vb_state
|
||||
.set_branch(vbranch.clone())
|
||||
.context(format!("failed to write virtual branch {}", vbranch.name))?;
|
||||
@ -200,11 +198,7 @@ pub fn get_applied_status(
|
||||
let hunks_by_branch: Vec<(Branch, HashMap<PathBuf, Vec<VirtualBranchHunk>>)> = hunks_by_branch
|
||||
.iter()
|
||||
.map(|(branch, hunks)| {
|
||||
let hunks = file_hunks_from_diffs(
|
||||
&project_repository.project().path,
|
||||
hunks.clone(),
|
||||
Some(&locks),
|
||||
);
|
||||
let hunks = file_hunks_from_diffs(&ctx.project().path, hunks.clone(), Some(&locks));
|
||||
(branch.clone(), hunks)
|
||||
})
|
||||
.collect();
|
||||
@ -212,7 +206,7 @@ pub fn get_applied_status(
|
||||
let files_by_branch: Vec<(Branch, Vec<VirtualBranchFile>)> = hunks_by_branch
|
||||
.iter()
|
||||
.map(|(branch, hunks)| {
|
||||
let files = virtual_hunks_into_virtual_files(project_repository, hunks.clone());
|
||||
let files = virtual_hunks_into_virtual_files(ctx, hunks.clone());
|
||||
(branch.clone(), files)
|
||||
})
|
||||
.collect();
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,6 @@
|
||||
use anyhow::Result;
|
||||
use gitbutler_branch_actions::{list_branches, Author};
|
||||
use gitbutler_command_context::ProjectRepository;
|
||||
use gitbutler_command_context::CommandContext;
|
||||
|
||||
#[test]
|
||||
fn on_main_single_branch_no_vbranch() -> Result<()> {
|
||||
@ -128,6 +128,6 @@ fn default_author() -> Author {
|
||||
}
|
||||
}
|
||||
|
||||
fn project_ctx(name: &str) -> anyhow::Result<ProjectRepository> {
|
||||
fn project_ctx(name: &str) -> anyhow::Result<CommandContext> {
|
||||
gitbutler_testsupport::read_only::fixture("for-listing.sh", name)
|
||||
}
|
||||
|
@ -1,2 +1,2 @@
|
||||
mod repository;
|
||||
pub use repository::ProjectRepository;
|
||||
pub use repository::CommandContext;
|
||||
|
@ -1,12 +1,12 @@
|
||||
use anyhow::Result;
|
||||
use gitbutler_project::Project;
|
||||
|
||||
pub struct ProjectRepository {
|
||||
pub struct CommandContext {
|
||||
git_repository: git2::Repository,
|
||||
project: Project,
|
||||
}
|
||||
|
||||
impl ProjectRepository {
|
||||
impl CommandContext {
|
||||
pub fn open(project: &Project) -> Result<Self> {
|
||||
let repo = git2::Repository::open(&project.path)?;
|
||||
|
||||
@ -67,7 +67,7 @@ impl ProjectRepository {
|
||||
&self.project
|
||||
}
|
||||
|
||||
pub fn repo(&self) -> &git2::Repository {
|
||||
pub fn repository(&self) -> &git2::Repository {
|
||||
&self.git_repository
|
||||
}
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ use std::{borrow::Borrow, path::PathBuf};
|
||||
use anyhow::{anyhow, Context, Result};
|
||||
use bstr::{BString, ByteSlice, ByteVec};
|
||||
use diffy::{apply_bytes as diffy_apply, Line, Patch};
|
||||
use gitbutler_command_context::ProjectRepository;
|
||||
use gitbutler_command_context::CommandContext;
|
||||
use hex::ToHex;
|
||||
|
||||
use crate::GitHunk;
|
||||
@ -14,18 +14,18 @@ use crate::GitHunk;
|
||||
// constructs a tree from those changes on top of the target
|
||||
// and writes it as a new tree for storage
|
||||
pub fn hunks_onto_oid<T>(
|
||||
project_repository: &ProjectRepository,
|
||||
ctx: &CommandContext,
|
||||
target: &git2::Oid,
|
||||
files: impl IntoIterator<Item = (impl Borrow<PathBuf>, impl Borrow<Vec<T>>)>,
|
||||
) -> Result<git2::Oid>
|
||||
where
|
||||
T: Into<GitHunk> + Clone,
|
||||
{
|
||||
hunks_onto_commit(project_repository, *target, files)
|
||||
hunks_onto_commit(ctx, *target, files)
|
||||
}
|
||||
|
||||
pub fn hunks_onto_commit<T>(
|
||||
project_repository: &ProjectRepository,
|
||||
ctx: &CommandContext,
|
||||
commit_oid: git2::Oid,
|
||||
files: impl IntoIterator<Item = (impl Borrow<PathBuf>, impl Borrow<Vec<T>>)>,
|
||||
) -> Result<git2::Oid>
|
||||
@ -33,29 +33,29 @@ where
|
||||
T: Into<GitHunk> + Clone,
|
||||
{
|
||||
// read the base sha into an index
|
||||
let git_repository: &git2::Repository = project_repository.repo();
|
||||
let git_repository: &git2::Repository = ctx.repository();
|
||||
|
||||
let head_commit = git_repository.find_commit(commit_oid)?;
|
||||
let base_tree = head_commit.tree()?;
|
||||
|
||||
hunks_onto_tree(project_repository, &base_tree, files)
|
||||
hunks_onto_tree(ctx, &base_tree, files)
|
||||
}
|
||||
|
||||
pub fn hunks_onto_tree<T>(
|
||||
project_repository: &ProjectRepository,
|
||||
ctx: &CommandContext,
|
||||
base_tree: &git2::Tree,
|
||||
files: impl IntoIterator<Item = (impl Borrow<PathBuf>, impl Borrow<Vec<T>>)>,
|
||||
) -> Result<git2::Oid>
|
||||
where
|
||||
T: Into<GitHunk> + Clone,
|
||||
{
|
||||
let git_repository = project_repository.repo();
|
||||
let git_repository = ctx.repository();
|
||||
let mut builder = git2::build::TreeUpdateBuilder::new();
|
||||
// now update the index with content in the working directory for each file
|
||||
for (rel_path, hunks) in files {
|
||||
let rel_path = rel_path.borrow();
|
||||
let hunks: Vec<GitHunk> = hunks.borrow().iter().map(|h| h.clone().into()).collect();
|
||||
let full_path = project_repository.project().worktree_path().join(rel_path);
|
||||
let full_path = ctx.project().worktree_path().join(rel_path);
|
||||
|
||||
let is_submodule = full_path.is_dir()
|
||||
&& hunks.len() == 1
|
||||
@ -102,7 +102,7 @@ where
|
||||
|
||||
// if the link target is inside the project repository, make it relative
|
||||
let link_target = link_target
|
||||
.strip_prefix(project_repository.project().worktree_path())
|
||||
.strip_prefix(ctx.project().worktree_path())
|
||||
.unwrap_or(&link_target);
|
||||
|
||||
let blob_oid = git_repository.blob(
|
||||
@ -193,7 +193,7 @@ where
|
||||
|
||||
// now write out the tree
|
||||
let tree_oid = builder
|
||||
.create_updated(project_repository.repo(), base_tree)
|
||||
.create_updated(ctx.repository(), base_tree)
|
||||
.context("failed to write updated tree")?;
|
||||
|
||||
Ok(tree_oid)
|
||||
|
@ -1,6 +1,6 @@
|
||||
use anyhow::Result;
|
||||
use bstr::BString;
|
||||
use gitbutler_command_context::ProjectRepository;
|
||||
use gitbutler_command_context::CommandContext;
|
||||
use gitbutler_project::Project;
|
||||
|
||||
use crate::{Config, RepositoryExt};
|
||||
@ -15,20 +15,22 @@ pub trait RepoCommands {
|
||||
|
||||
impl RepoCommands for Project {
|
||||
fn get_local_config(&self, key: &str) -> Result<Option<String>> {
|
||||
let project_repo = ProjectRepository::open(self)?;
|
||||
let config: Config = project_repo.repo().into();
|
||||
let ctx = CommandContext::open(self)?;
|
||||
let config: Config = ctx.repository().into();
|
||||
config.get_local(key)
|
||||
}
|
||||
|
||||
fn set_local_config(&self, key: &str, value: &str) -> Result<()> {
|
||||
let project_repo = ProjectRepository::open(self)?;
|
||||
let config: Config = project_repo.repo().into();
|
||||
let ctx = CommandContext::open(self)?;
|
||||
let config: Config = ctx.repository().into();
|
||||
config.set_local(key, value)
|
||||
}
|
||||
|
||||
fn check_signing_settings(&self) -> Result<bool> {
|
||||
let repo = ProjectRepository::open(self)?;
|
||||
let signed = repo.repo().sign_buffer(&BString::new("test".into()).into());
|
||||
let repo = CommandContext::open(self)?;
|
||||
let signed = repo
|
||||
.repository()
|
||||
.sign_buffer(&BString::new("test".into()).into());
|
||||
match signed {
|
||||
Ok(_) => Ok(true),
|
||||
Err(e) => Err(e),
|
||||
@ -36,13 +38,13 @@ impl RepoCommands for Project {
|
||||
}
|
||||
|
||||
fn remotes(&self) -> Result<Vec<String>> {
|
||||
let project_repository = ProjectRepository::open(self)?;
|
||||
project_repository.repo().remotes_as_string()
|
||||
let ctx = CommandContext::open(self)?;
|
||||
ctx.repository().remotes_as_string()
|
||||
}
|
||||
|
||||
fn add_remote(&self, name: &str, url: &str) -> Result<()> {
|
||||
let project_repository = ProjectRepository::open(self)?;
|
||||
project_repository.repo().remote(name, url)?;
|
||||
let ctx = CommandContext::open(self)?;
|
||||
ctx.repository().remote(name, url)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
use std::{path::PathBuf, str::FromStr, vec};
|
||||
|
||||
use anyhow::Context;
|
||||
use gitbutler_command_context::ProjectRepository;
|
||||
use gitbutler_command_context::CommandContext;
|
||||
use gitbutler_project::AuthKey;
|
||||
use gitbutler_url::{ConvertError, Scheme, Url};
|
||||
|
||||
@ -81,10 +81,10 @@ pub enum HelpError {
|
||||
impl Helper {
|
||||
pub fn help<'a>(
|
||||
&'a self,
|
||||
project_repository: &'a ProjectRepository,
|
||||
ctx: &'a CommandContext,
|
||||
remote_name: &str,
|
||||
) -> Result<Vec<(git2::Remote, Vec<Credential>)>, HelpError> {
|
||||
let remote = project_repository.repo().find_remote(remote_name)?;
|
||||
let remote = ctx.repository().find_remote(remote_name)?;
|
||||
let remote_url = Url::from_str(remote.url().ok_or(HelpError::NoUrlSet)?)
|
||||
.context("failed to parse remote url")?;
|
||||
|
||||
@ -93,15 +93,13 @@ impl Helper {
|
||||
return Ok(vec![(remote, vec![Credential::Noop])]);
|
||||
}
|
||||
|
||||
match &project_repository.project().preferred_key {
|
||||
match &ctx.project().preferred_key {
|
||||
AuthKey::Local { private_key_path } => {
|
||||
let ssh_remote = if remote_url.scheme == Scheme::Ssh {
|
||||
Ok(remote)
|
||||
} else {
|
||||
let ssh_url = remote_url.as_ssh()?;
|
||||
project_repository
|
||||
.repo()
|
||||
.remote_anonymous(&ssh_url.to_string())
|
||||
ctx.repository().remote_anonymous(&ssh_url.to_string())
|
||||
}?;
|
||||
|
||||
Ok(vec![(
|
||||
@ -117,9 +115,9 @@ impl Helper {
|
||||
Ok(remote)
|
||||
} else {
|
||||
let url = remote_url.as_https()?;
|
||||
project_repository.repo().remote_anonymous(&url.to_string())
|
||||
ctx.repository().remote_anonymous(&url.to_string())
|
||||
}?;
|
||||
let flow = Self::https_flow(project_repository, &remote_url)?
|
||||
let flow = Self::https_flow(ctx, &remote_url)?
|
||||
.into_iter()
|
||||
.map(Credential::Https)
|
||||
.collect::<Vec<_>>();
|
||||
@ -133,13 +131,13 @@ impl Helper {
|
||||
}
|
||||
|
||||
fn https_flow(
|
||||
project_repository: &ProjectRepository,
|
||||
ctx: &CommandContext,
|
||||
remote_url: &Url,
|
||||
) -> Result<Vec<HttpsCredential>, HelpError> {
|
||||
let mut flow = vec![];
|
||||
|
||||
let mut helper = git2::CredentialHelper::new(&remote_url.to_string());
|
||||
let config = project_repository.repo().config()?;
|
||||
let config = ctx.repository().config()?;
|
||||
helper.config(&config);
|
||||
if let Some((username, password)) = helper.execute() {
|
||||
flow.push(HttpsCredential::CredentialHelper { username, password });
|
||||
|
@ -1,6 +1,6 @@
|
||||
use anyhow::{anyhow, Context, Result};
|
||||
use bstr::ByteSlice;
|
||||
use gitbutler_command_context::ProjectRepository;
|
||||
use gitbutler_command_context::CommandContext;
|
||||
use gitbutler_commit::{commit_ext::CommitExt, commit_headers::HasCommitHeaders};
|
||||
use gitbutler_error::error::Marker;
|
||||
|
||||
@ -10,21 +10,19 @@ use crate::{LogUntil, RepoActionsExt, 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: &ProjectRepository,
|
||||
ctx: &CommandContext,
|
||||
target_commit_oid: git2::Oid,
|
||||
start_commit_oid: git2::Oid,
|
||||
end_commit_oid: git2::Oid,
|
||||
) -> Result<Option<git2::Oid>> {
|
||||
// get a list of the commits to rebase
|
||||
let mut ids_to_rebase =
|
||||
project_repository.l(end_commit_oid, LogUntil::Commit(start_commit_oid))?;
|
||||
let mut ids_to_rebase = ctx.l(end_commit_oid, LogUntil::Commit(start_commit_oid))?;
|
||||
|
||||
if ids_to_rebase.is_empty() {
|
||||
return Ok(None);
|
||||
}
|
||||
|
||||
let new_head_id =
|
||||
cherry_rebase_group(project_repository, target_commit_oid, &mut ids_to_rebase)?;
|
||||
let new_head_id = cherry_rebase_group(ctx, target_commit_oid, &mut ids_to_rebase)?;
|
||||
|
||||
Ok(Some(new_head_id))
|
||||
}
|
||||
@ -34,7 +32,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: &ProjectRepository,
|
||||
ctx: &CommandContext,
|
||||
target_commit_oid: git2::Oid,
|
||||
ids_to_rebase: &mut [git2::Oid],
|
||||
) -> Result<git2::Oid> {
|
||||
@ -42,22 +40,21 @@ pub fn cherry_rebase_group(
|
||||
// now, rebase unchanged commits onto the new commit
|
||||
let commits_to_rebase = ids_to_rebase
|
||||
.iter()
|
||||
.map(|oid| project_repository.repo().find_commit(oid.to_owned()))
|
||||
.map(|oid| ctx.repository().find_commit(oid.to_owned()))
|
||||
.collect::<Result<Vec<_>, _>>()
|
||||
.context("failed to read commits to rebase")?;
|
||||
|
||||
let new_head_id = commits_to_rebase
|
||||
.into_iter()
|
||||
.fold(
|
||||
project_repository
|
||||
.repo()
|
||||
ctx.repository()
|
||||
.find_commit(target_commit_oid)
|
||||
.context("failed to find new commit"),
|
||||
|head, to_rebase| {
|
||||
let head = head?;
|
||||
|
||||
let mut cherrypick_index = project_repository
|
||||
.repo()
|
||||
let mut cherrypick_index = ctx
|
||||
.repository()
|
||||
.cherrypick_commit(&to_rebase, &head, 0, None)
|
||||
.context("failed to cherry pick")?;
|
||||
|
||||
@ -66,18 +63,18 @@ pub fn cherry_rebase_group(
|
||||
}
|
||||
|
||||
let merge_tree_oid = cherrypick_index
|
||||
.write_tree_to(project_repository.repo())
|
||||
.write_tree_to(ctx.repository())
|
||||
.context("failed to write merge tree")?;
|
||||
|
||||
let merge_tree = project_repository
|
||||
.repo()
|
||||
let merge_tree = ctx
|
||||
.repository()
|
||||
.find_tree(merge_tree_oid)
|
||||
.context("failed to find merge tree")?;
|
||||
|
||||
let commit_headers = to_rebase.gitbutler_headers();
|
||||
|
||||
let commit_oid = project_repository
|
||||
.repo()
|
||||
let commit_oid = ctx
|
||||
.repository()
|
||||
.commit_with_signature(
|
||||
None,
|
||||
&to_rebase.author(),
|
||||
@ -89,8 +86,7 @@ pub fn cherry_rebase_group(
|
||||
)
|
||||
.context("failed to create commit")?;
|
||||
|
||||
project_repository
|
||||
.repo()
|
||||
ctx.repository()
|
||||
.find_commit(commit_oid)
|
||||
.context("failed to find commit")
|
||||
},
|
||||
|
@ -6,7 +6,7 @@ use gitbutler_branch::{
|
||||
Branch, BranchId, GITBUTLER_INTEGRATION_COMMIT_AUTHOR_EMAIL,
|
||||
GITBUTLER_INTEGRATION_COMMIT_AUTHOR_NAME,
|
||||
};
|
||||
use gitbutler_command_context::ProjectRepository;
|
||||
use gitbutler_command_context::CommandContext;
|
||||
use gitbutler_commit::commit_headers::CommitHeadersV2;
|
||||
use gitbutler_error::error::Code;
|
||||
use gitbutler_project::AuthKey;
|
||||
@ -49,7 +49,7 @@ pub trait RepoActionsExt {
|
||||
fn signatures(&self) -> Result<(git2::Signature, git2::Signature)>;
|
||||
}
|
||||
|
||||
impl RepoActionsExt for ProjectRepository {
|
||||
impl RepoActionsExt for CommandContext {
|
||||
fn git_test_push(
|
||||
&self,
|
||||
credentials: &Helper,
|
||||
@ -60,7 +60,7 @@ impl RepoActionsExt for ProjectRepository {
|
||||
let target_branch_refname =
|
||||
Refname::from_str(&format!("refs/remotes/{}/{}", remote_name, branch_name))?;
|
||||
let branch = self
|
||||
.repo()
|
||||
.repository()
|
||||
.find_branch_by_refname(&target_branch_refname)?
|
||||
.ok_or(anyhow!("failed to find branch {}", target_branch_refname))?;
|
||||
|
||||
@ -94,21 +94,23 @@ impl RepoActionsExt for ProjectRepository {
|
||||
}
|
||||
|
||||
fn add_branch_reference(&self, branch: &Branch) -> Result<()> {
|
||||
let (should_write, with_force) =
|
||||
match self.repo().find_reference(&branch.refname().to_string()) {
|
||||
Ok(reference) => match reference.target() {
|
||||
Some(head_oid) => Ok((head_oid != branch.head, true)),
|
||||
None => Ok((true, true)),
|
||||
},
|
||||
Err(err) => match err.code() {
|
||||
git2::ErrorCode::NotFound => Ok((true, false)),
|
||||
_ => Err(err),
|
||||
},
|
||||
}
|
||||
.context("failed to lookup reference")?;
|
||||
let (should_write, with_force) = match self
|
||||
.repository()
|
||||
.find_reference(&branch.refname().to_string())
|
||||
{
|
||||
Ok(reference) => match reference.target() {
|
||||
Some(head_oid) => Ok((head_oid != branch.head, true)),
|
||||
None => Ok((true, true)),
|
||||
},
|
||||
Err(err) => match err.code() {
|
||||
git2::ErrorCode::NotFound => Ok((true, false)),
|
||||
_ => Err(err),
|
||||
},
|
||||
}
|
||||
.context("failed to lookup reference")?;
|
||||
|
||||
if should_write {
|
||||
self.repo()
|
||||
self.repository()
|
||||
.reference(
|
||||
&branch.refname().to_string(),
|
||||
branch.head,
|
||||
@ -122,7 +124,10 @@ impl RepoActionsExt for ProjectRepository {
|
||||
}
|
||||
|
||||
fn delete_branch_reference(&self, branch: &Branch) -> Result<()> {
|
||||
match self.repo().find_reference(&branch.refname().to_string()) {
|
||||
match self
|
||||
.repository()
|
||||
.find_reference(&branch.refname().to_string())
|
||||
{
|
||||
Ok(mut reference) => {
|
||||
reference
|
||||
.delete()
|
||||
@ -141,7 +146,10 @@ impl RepoActionsExt for ProjectRepository {
|
||||
fn l(&self, from: git2::Oid, to: LogUntil) -> Result<Vec<git2::Oid>> {
|
||||
match to {
|
||||
LogUntil::Commit(oid) => {
|
||||
let mut revwalk = self.repo().revwalk().context("failed to create revwalk")?;
|
||||
let mut revwalk = self
|
||||
.repository()
|
||||
.revwalk()
|
||||
.context("failed to create revwalk")?;
|
||||
revwalk
|
||||
.push(from)
|
||||
.context(format!("failed to push {}", from))?;
|
||||
@ -153,7 +161,10 @@ impl RepoActionsExt for ProjectRepository {
|
||||
.collect::<Result<Vec<_>, _>>()
|
||||
}
|
||||
LogUntil::Take(n) => {
|
||||
let mut revwalk = self.repo().revwalk().context("failed to create revwalk")?;
|
||||
let mut revwalk = self
|
||||
.repository()
|
||||
.revwalk()
|
||||
.context("failed to create revwalk")?;
|
||||
revwalk
|
||||
.push(from)
|
||||
.context(format!("failed to push {}", from))?;
|
||||
@ -163,7 +174,10 @@ impl RepoActionsExt for ProjectRepository {
|
||||
.collect::<Result<Vec<_>, _>>()
|
||||
}
|
||||
LogUntil::When(cond) => {
|
||||
let mut revwalk = self.repo().revwalk().context("failed to create revwalk")?;
|
||||
let mut revwalk = self
|
||||
.repository()
|
||||
.revwalk()
|
||||
.context("failed to create revwalk")?;
|
||||
revwalk
|
||||
.push(from)
|
||||
.context(format!("failed to push {}", from))?;
|
||||
@ -173,7 +187,7 @@ impl RepoActionsExt for ProjectRepository {
|
||||
oids.push(oid);
|
||||
|
||||
let commit = self
|
||||
.repo()
|
||||
.repository()
|
||||
.find_commit(oid)
|
||||
.context("failed to find commit")?;
|
||||
|
||||
@ -184,7 +198,10 @@ impl RepoActionsExt for ProjectRepository {
|
||||
Ok(oids)
|
||||
}
|
||||
LogUntil::End => {
|
||||
let mut revwalk = self.repo().revwalk().context("failed to create revwalk")?;
|
||||
let mut revwalk = self
|
||||
.repository()
|
||||
.revwalk()
|
||||
.context("failed to create revwalk")?;
|
||||
revwalk
|
||||
.push(from)
|
||||
.context(format!("failed to push {}", from))?;
|
||||
@ -205,7 +222,7 @@ impl RepoActionsExt for ProjectRepository {
|
||||
Ok(self
|
||||
.list(from, to)?
|
||||
.into_iter()
|
||||
.map(|oid| self.repo().find_commit(oid))
|
||||
.map(|oid| self.repository().find_commit(oid))
|
||||
.collect::<Result<Vec<_>, _>>()?)
|
||||
}
|
||||
|
||||
@ -213,7 +230,7 @@ impl RepoActionsExt for ProjectRepository {
|
||||
fn log(&self, from: git2::Oid, to: LogUntil) -> Result<Vec<git2::Commit>> {
|
||||
self.l(from, to)?
|
||||
.into_iter()
|
||||
.map(|oid| self.repo().find_commit(oid))
|
||||
.map(|oid| self.repository().find_commit(oid))
|
||||
.collect::<Result<Vec<_>, _>>()
|
||||
.context("failed to collect commits")
|
||||
}
|
||||
@ -232,7 +249,7 @@ impl RepoActionsExt for ProjectRepository {
|
||||
commit_headers: Option<CommitHeadersV2>,
|
||||
) -> Result<git2::Oid> {
|
||||
let (author, committer) = self.signatures().context("failed to get signatures")?;
|
||||
self.repo()
|
||||
self.repository()
|
||||
.commit_with_signature(
|
||||
None,
|
||||
&author,
|
||||
@ -428,7 +445,7 @@ impl RepoActionsExt for ProjectRepository {
|
||||
}
|
||||
|
||||
fn signatures(&self) -> Result<(git2::Signature, git2::Signature)> {
|
||||
let repo = gix::open(self.repo().path())?;
|
||||
let repo = gix::open(self.repository().path())?;
|
||||
|
||||
let default_actor = gix::actor::SignatureRef {
|
||||
name: GITBUTLER_INTEGRATION_COMMIT_AUTHOR_NAME.into(),
|
||||
@ -436,7 +453,7 @@ impl RepoActionsExt for ProjectRepository {
|
||||
time: Default::default(),
|
||||
};
|
||||
let author = repo.author().transpose()?.unwrap_or(default_actor);
|
||||
let config: Config = self.repo().into();
|
||||
let config: Config = self.repository().into();
|
||||
let committer = if config.user_real_comitter()? {
|
||||
repo.committer().transpose()?.unwrap_or(default_actor)
|
||||
} else {
|
||||
|
@ -1,6 +1,6 @@
|
||||
use std::{path::PathBuf, str};
|
||||
|
||||
use gitbutler_command_context::ProjectRepository;
|
||||
use gitbutler_command_context::CommandContext;
|
||||
use gitbutler_project as projects;
|
||||
use gitbutler_repo::credentials::{Credential, Helper, SshCredential};
|
||||
use gitbutler_testsupport::{temp_dir, test_repository};
|
||||
@ -36,9 +36,9 @@ impl TestCase<'_> {
|
||||
preferred_key: self.preferred_key.clone(),
|
||||
..Default::default()
|
||||
};
|
||||
let project_repository = ProjectRepository::open(&project).unwrap();
|
||||
let ctx = CommandContext::open(&project).unwrap();
|
||||
|
||||
let flow = helper.help(&project_repository, "origin").unwrap();
|
||||
let flow = helper.help(&ctx, "origin").unwrap();
|
||||
flow.into_iter()
|
||||
.map(|(remote, credentials)| (remote.url().as_ref().unwrap().to_string(), credentials))
|
||||
.collect::<Vec<_>>()
|
||||
|
@ -5,7 +5,7 @@ use std::{
|
||||
|
||||
use anyhow::{anyhow, Context, Result};
|
||||
use gitbutler_branch::{Target, VirtualBranchesHandle};
|
||||
use gitbutler_command_context::ProjectRepository;
|
||||
use gitbutler_command_context::CommandContext;
|
||||
use gitbutler_error::error::Code;
|
||||
use gitbutler_id::id::Id;
|
||||
use gitbutler_oplog::OplogExt;
|
||||
@ -17,11 +17,11 @@ use gitbutler_user as users;
|
||||
use itertools::Itertools;
|
||||
|
||||
pub fn sync_with_gitbutler(
|
||||
project_repository: &ProjectRepository,
|
||||
ctx: &CommandContext,
|
||||
user: &users::User,
|
||||
projects: &projects::Controller,
|
||||
) -> Result<()> {
|
||||
let project = project_repository.project();
|
||||
let project = ctx.project();
|
||||
let vb_state = VirtualBranchesHandle::new(project.gb_dir());
|
||||
let default_target = vb_state.get_default_target()?;
|
||||
let gb_code_last_commit = project
|
||||
@ -33,7 +33,7 @@ pub fn sync_with_gitbutler(
|
||||
// Push target
|
||||
push_target(
|
||||
projects,
|
||||
project_repository,
|
||||
ctx,
|
||||
&default_target,
|
||||
gb_code_last_commit,
|
||||
project.id,
|
||||
@ -42,16 +42,16 @@ pub fn sync_with_gitbutler(
|
||||
)?;
|
||||
|
||||
// Push all refs
|
||||
push_all_refs(project_repository, user, project.id)?;
|
||||
push_all_refs(ctx, user, project.id)?;
|
||||
|
||||
// Push Oplog head
|
||||
let oplog_refspec = project_repository
|
||||
let oplog_refspec = ctx
|
||||
.project()
|
||||
.oplog_head()?
|
||||
.map(|sha| format!("+{}:refs/gitbutler/oplog/oplog", sha));
|
||||
|
||||
if let Some(oplog_refspec) = oplog_refspec {
|
||||
let x = push_to_gitbutler_server(project_repository, Some(user), &[&oplog_refspec]);
|
||||
let x = push_to_gitbutler_server(ctx, Some(user), &[&oplog_refspec]);
|
||||
println!("\n\n\nHERE: {:?}", x?);
|
||||
}
|
||||
|
||||
@ -60,7 +60,7 @@ pub fn sync_with_gitbutler(
|
||||
|
||||
fn push_target(
|
||||
projects: &projects::Controller,
|
||||
project_repository: &ProjectRepository,
|
||||
ctx: &CommandContext,
|
||||
default_target: &Target,
|
||||
gb_code_last_commit: Option<git2::Oid>,
|
||||
project_id: Id<Project>,
|
||||
@ -68,7 +68,7 @@ fn push_target(
|
||||
batch_size: usize,
|
||||
) -> Result<()> {
|
||||
let ids = batch_rev_walk(
|
||||
project_repository.repo(),
|
||||
ctx.repository(),
|
||||
batch_size,
|
||||
default_target.sha,
|
||||
gb_code_last_commit,
|
||||
@ -84,7 +84,7 @@ fn push_target(
|
||||
for (idx, id) in ids.iter().enumerate().rev() {
|
||||
let refspec = format!("+{}:refs/push-tmp/{}", id, project_id);
|
||||
|
||||
push_to_gitbutler_server(project_repository, Some(user), &[&refspec])?;
|
||||
push_to_gitbutler_server(ctx, Some(user), &[&refspec])?;
|
||||
update_project(projects, project_id, *id)?;
|
||||
|
||||
tracing::info!(
|
||||
@ -96,7 +96,7 @@ fn push_target(
|
||||
}
|
||||
|
||||
push_to_gitbutler_server(
|
||||
project_repository,
|
||||
ctx,
|
||||
Some(user),
|
||||
&[&format!("+{}:refs/{}", default_target.sha, project_id)],
|
||||
)?;
|
||||
@ -137,9 +137,9 @@ fn batch_rev_walk(
|
||||
Ok(oids)
|
||||
}
|
||||
|
||||
fn collect_refs(project_repository: &ProjectRepository) -> anyhow::Result<Vec<Refname>> {
|
||||
Ok(project_repository
|
||||
.repo()
|
||||
fn collect_refs(ctx: &CommandContext) -> anyhow::Result<Vec<Refname>> {
|
||||
Ok(ctx
|
||||
.repository()
|
||||
.references_glob("refs/*")?
|
||||
.flatten()
|
||||
.filter_map(|r| {
|
||||
@ -150,11 +150,11 @@ fn collect_refs(project_repository: &ProjectRepository) -> anyhow::Result<Vec<Re
|
||||
}
|
||||
|
||||
fn push_all_refs(
|
||||
project_repository: &ProjectRepository,
|
||||
ctx: &CommandContext,
|
||||
user: &users::User,
|
||||
project_id: Id<projects::Project>,
|
||||
) -> Result<()> {
|
||||
let gb_references = collect_refs(project_repository)?;
|
||||
let gb_references = collect_refs(ctx)?;
|
||||
let all_refs: Vec<_> = gb_references
|
||||
.iter()
|
||||
.filter(|r| {
|
||||
@ -168,7 +168,7 @@ fn push_all_refs(
|
||||
|
||||
let all_refs: Vec<_> = all_refs.iter().map(String::as_str).collect();
|
||||
|
||||
let anything_pushed = push_to_gitbutler_server(project_repository, Some(user), &all_refs)?;
|
||||
let anything_pushed = push_to_gitbutler_server(ctx, Some(user), &all_refs)?;
|
||||
if anything_pushed {
|
||||
tracing::info!(
|
||||
%project_id,
|
||||
@ -196,11 +196,11 @@ fn update_project(
|
||||
}
|
||||
|
||||
fn push_to_gitbutler_server(
|
||||
project_repo: &ProjectRepository,
|
||||
ctx: &CommandContext,
|
||||
user: Option<&users::User>,
|
||||
ref_specs: &[&str],
|
||||
) -> Result<bool> {
|
||||
let project = project_repo.project();
|
||||
let project = ctx.project();
|
||||
let url = project
|
||||
.api
|
||||
.as_ref()
|
||||
@ -243,7 +243,7 @@ fn push_to_gitbutler_server(
|
||||
let headers = &[auth_header.as_str()];
|
||||
push_options.custom_headers(headers);
|
||||
|
||||
let mut remote = project_repo.repo().remote_anonymous(&url.to_string())?;
|
||||
let mut remote = ctx.repository().remote_anonymous(&url.to_string())?;
|
||||
|
||||
remote
|
||||
.push(ref_specs, Some(&mut push_options))
|
||||
|
@ -3,7 +3,7 @@ use std::path::PathBuf;
|
||||
use anyhow::{Context, Result};
|
||||
use gitbutler_branch::BranchId;
|
||||
use gitbutler_branch_actions::conflicts;
|
||||
use gitbutler_command_context::ProjectRepository;
|
||||
use gitbutler_command_context::CommandContext;
|
||||
use gitbutler_project as projects;
|
||||
use gitbutler_project::ProjectId;
|
||||
use gitbutler_reference::RemoteRefname;
|
||||
@ -28,16 +28,16 @@ impl App {
|
||||
impl App {
|
||||
pub fn mark_resolved(&self, project_id: ProjectId, path: &str) -> Result<()> {
|
||||
let project = self.projects().get(project_id)?;
|
||||
let project_repository = ProjectRepository::open(&project)?;
|
||||
let ctx = CommandContext::open(&project)?;
|
||||
// mark file as resolved
|
||||
conflicts::resolve(&project_repository, path)?;
|
||||
conflicts::resolve(&ctx, path)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn git_remote_branches(&self, project_id: ProjectId) -> Result<Vec<RemoteRefname>> {
|
||||
let project = self.projects().get(project_id)?;
|
||||
let project_repository = ProjectRepository::open(&project)?;
|
||||
project_repository.repo().remote_branches()
|
||||
let ctx = CommandContext::open(&project)?;
|
||||
ctx.repository().remote_branches()
|
||||
}
|
||||
|
||||
pub fn git_test_push(
|
||||
@ -49,8 +49,8 @@ impl App {
|
||||
askpass: Option<Option<BranchId>>,
|
||||
) -> Result<()> {
|
||||
let project = self.projects().get(project_id)?;
|
||||
let project_repository = ProjectRepository::open(&project)?;
|
||||
project_repository.git_test_push(credentials, remote_name, branch_name, askpass)
|
||||
let ctx = CommandContext::open(&project)?;
|
||||
ctx.git_test_push(credentials, remote_name, branch_name, askpass)
|
||||
}
|
||||
|
||||
pub fn git_test_fetch(
|
||||
@ -61,15 +61,15 @@ impl App {
|
||||
askpass: Option<String>,
|
||||
) -> Result<()> {
|
||||
let project = self.projects().get(project_id)?;
|
||||
let project_repository = ProjectRepository::open(&project)?;
|
||||
project_repository.fetch(remote_name, credentials, askpass)
|
||||
let ctx = CommandContext::open(&project)?;
|
||||
ctx.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 = ProjectRepository::open(&project)?;
|
||||
let size = project_repository
|
||||
.repo()
|
||||
let ctx = CommandContext::open(&project)?;
|
||||
let size = ctx
|
||||
.repository()
|
||||
.index()
|
||||
.context("failed to get index size")?
|
||||
.len();
|
||||
@ -78,9 +78,9 @@ impl App {
|
||||
|
||||
pub fn git_head(&self, project_id: ProjectId) -> Result<String> {
|
||||
let project = self.projects().get(project_id)?;
|
||||
let project_repository = ProjectRepository::open(&project)?;
|
||||
let head = project_repository
|
||||
.repo()
|
||||
let ctx = CommandContext::open(&project)?;
|
||||
let head = ctx
|
||||
.repository()
|
||||
.head()
|
||||
.context("failed to get repository head")?;
|
||||
Ok(head.name().unwrap().to_string())
|
||||
|
@ -7,7 +7,7 @@ pub mod commands {
|
||||
BaseBranch, BranchListing, BranchListingDetails, BranchListingFilter, RemoteBranch,
|
||||
RemoteBranchData, RemoteBranchFile, VirtualBranchActions, VirtualBranches,
|
||||
};
|
||||
use gitbutler_command_context::ProjectRepository;
|
||||
use gitbutler_command_context::CommandContext;
|
||||
use gitbutler_error::error::Code;
|
||||
use gitbutler_project as projects;
|
||||
use gitbutler_project::{FetchResult, ProjectId};
|
||||
@ -416,7 +416,7 @@ pub mod commands {
|
||||
project_id: ProjectId,
|
||||
filter: Option<BranchListingFilter>,
|
||||
) -> Result<Vec<BranchListing>, Error> {
|
||||
let ctx = ProjectRepository::open(&projects.get(project_id)?)?;
|
||||
let ctx = CommandContext::open(&projects.get(project_id)?)?;
|
||||
let branches = gitbutler_branch_actions::list_branches(&ctx, filter)?;
|
||||
Ok(branches)
|
||||
}
|
||||
@ -428,7 +428,7 @@ pub mod commands {
|
||||
project_id: ProjectId,
|
||||
branch_names: Vec<String>,
|
||||
) -> Result<Vec<BranchListingDetails>, Error> {
|
||||
let ctx = ProjectRepository::open(&projects.get(project_id)?)?;
|
||||
let ctx = CommandContext::open(&projects.get(project_id)?)?;
|
||||
let branches = gitbutler_branch_actions::get_branch_listing_details(&ctx, branch_names)?;
|
||||
Ok(branches)
|
||||
}
|
||||
|
@ -19,15 +19,15 @@ pub mod paths {
|
||||
|
||||
pub mod virtual_branches {
|
||||
use gitbutler_branch::{Target, VirtualBranchesHandle};
|
||||
use gitbutler_command_context::ProjectRepository;
|
||||
use gitbutler_command_context::CommandContext;
|
||||
|
||||
use crate::empty_bare_repository;
|
||||
|
||||
pub fn set_test_target(project_repository: &ProjectRepository) -> anyhow::Result<()> {
|
||||
let vb_state = VirtualBranchesHandle::new(project_repository.project().gb_dir());
|
||||
pub fn set_test_target(ctx: &CommandContext) -> anyhow::Result<()> {
|
||||
let vb_state = VirtualBranchesHandle::new(ctx.project().gb_dir());
|
||||
let (remote_repo, _tmp) = empty_bare_repository();
|
||||
let mut remote = project_repository
|
||||
.repo()
|
||||
let mut remote = ctx
|
||||
.repository()
|
||||
.remote("origin", remote_repo.path().to_str().unwrap())
|
||||
.expect("failed to add remote");
|
||||
remote.push(&["refs/heads/master:refs/heads/master"], None)?;
|
||||
@ -41,7 +41,7 @@ pub mod virtual_branches {
|
||||
})
|
||||
.expect("failed to write target");
|
||||
|
||||
gitbutler_branch_actions::update_gitbutler_integration(&vb_state, project_repository)
|
||||
gitbutler_branch_actions::update_gitbutler_integration(&vb_state, ctx)
|
||||
.expect("failed to update integration");
|
||||
|
||||
Ok(())
|
||||
@ -66,7 +66,7 @@ pub mod read_only {
|
||||
path::{Path, PathBuf},
|
||||
};
|
||||
|
||||
use gitbutler_command_context::ProjectRepository;
|
||||
use gitbutler_command_context::CommandContext;
|
||||
use gitbutler_project::{Project, ProjectId};
|
||||
use once_cell::sync::Lazy;
|
||||
use parking_lot::Mutex;
|
||||
@ -102,10 +102,7 @@ pub mod read_only {
|
||||
/// the output of `script_name`.
|
||||
///
|
||||
/// Returns the project that is strictly for read-only use.
|
||||
pub fn fixture(
|
||||
script_name: &str,
|
||||
project_directory: &str,
|
||||
) -> anyhow::Result<ProjectRepository> {
|
||||
pub fn fixture(script_name: &str, project_directory: &str) -> anyhow::Result<CommandContext> {
|
||||
static IS_VALID_PROJECT: Lazy<Mutex<BTreeSet<(String, String)>>> =
|
||||
Lazy::new(|| Mutex::new(Default::default()));
|
||||
|
||||
@ -131,7 +128,7 @@ pub mod read_only {
|
||||
..Default::default()
|
||||
}
|
||||
};
|
||||
ProjectRepository::open(&project)
|
||||
CommandContext::open(&project)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4,7 +4,7 @@ use std::{
|
||||
path::{Path, PathBuf},
|
||||
};
|
||||
|
||||
use gitbutler_command_context::ProjectRepository;
|
||||
use gitbutler_command_context::CommandContext;
|
||||
use gitbutler_repo::{credentials::Helper, RepositoryExt};
|
||||
use tempfile::{tempdir, TempDir};
|
||||
|
||||
@ -88,9 +88,9 @@ impl Suite {
|
||||
|
||||
pub struct Case {
|
||||
pub project: gitbutler_project::Project,
|
||||
pub project_repository: ProjectRepository,
|
||||
pub ctx: CommandContext,
|
||||
pub credentials: Helper,
|
||||
/// The directory containing the `project_repository`
|
||||
/// The directory containing the `ctx`
|
||||
project_tmp: Option<TempDir>,
|
||||
}
|
||||
|
||||
@ -108,12 +108,11 @@ impl Drop for Case {
|
||||
|
||||
impl Case {
|
||||
fn new(project: gitbutler_project::Project, project_tmp: TempDir) -> Case {
|
||||
let project_repository =
|
||||
ProjectRepository::open(&project).expect("failed to create project repository");
|
||||
let ctx = CommandContext::open(&project).expect("failed to create project repository");
|
||||
let credentials = Helper::default();
|
||||
Case {
|
||||
project,
|
||||
project_repository,
|
||||
ctx,
|
||||
project_tmp: Some(project_tmp),
|
||||
credentials,
|
||||
}
|
||||
@ -124,12 +123,11 @@ impl Case {
|
||||
.projects
|
||||
.get(self.project.id)
|
||||
.expect("failed to get project");
|
||||
let project_repository =
|
||||
ProjectRepository::open(&project).expect("failed to create project repository");
|
||||
let ctx = CommandContext::open(&project).expect("failed to create project repository");
|
||||
let credentials = Helper::default();
|
||||
Self {
|
||||
credentials,
|
||||
project_repository,
|
||||
ctx,
|
||||
project,
|
||||
project_tmp: self.project_tmp.take(),
|
||||
}
|
||||
|
@ -2,7 +2,7 @@ use std::{path::PathBuf, sync::Arc};
|
||||
|
||||
use anyhow::{Context, Result};
|
||||
use gitbutler_branch_actions::{VirtualBranchActions, VirtualBranches};
|
||||
use gitbutler_command_context::ProjectRepository;
|
||||
use gitbutler_command_context::CommandContext;
|
||||
use gitbutler_error::error::Marker;
|
||||
use gitbutler_oplog::{
|
||||
entry::{OperationKind, SnapshotDetails},
|
||||
@ -136,7 +136,7 @@ impl Handler {
|
||||
.get(project_id)
|
||||
.context("failed to get project")?;
|
||||
let open_projects_repository = || {
|
||||
ProjectRepository::open(&project.clone())
|
||||
CommandContext::open(&project.clone())
|
||||
.context("failed to open project repository for project")
|
||||
};
|
||||
|
||||
@ -152,14 +152,11 @@ impl Handler {
|
||||
self.emit_app_event(Change::GitActivity(project.id))?;
|
||||
}
|
||||
"HEAD" => {
|
||||
let project_repository = open_projects_repository()?;
|
||||
let head_ref = project_repository
|
||||
.repo()
|
||||
.head()
|
||||
.context("failed to get head")?;
|
||||
let ctx = open_projects_repository()?;
|
||||
let head_ref = ctx.repository().head().context("failed to get head")?;
|
||||
let head_ref_name = head_ref.name().context("failed to get head name")?;
|
||||
if head_ref_name != "refs/heads/gitbutler/integration" {
|
||||
let mut integration_reference = project_repository.repo().find_reference(
|
||||
let mut integration_reference = ctx.repository().find_reference(
|
||||
&Refname::from(LocalRefname::new("gitbutler/integration", None))
|
||||
.to_string(),
|
||||
)?;
|
||||
@ -188,7 +185,7 @@ impl Handler {
|
||||
|
||||
if project.is_sync_enabled() && project.has_code_url() {
|
||||
if let Some(user) = self.users.get_user()? {
|
||||
let repository = ProjectRepository::open(&project)
|
||||
let repository = CommandContext::open(&project)
|
||||
.context("failed to open project repository for project")?;
|
||||
return sync_with_gitbutler(&repository, &user, &self.projects);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user